Skip to content

Commit 6d84d84

Browse files
Revert "review comments"
This reverts commit 5e3eb12.
1 parent 5e3eb12 commit 6d84d84

File tree

8 files changed

+125
-8
lines changed

8 files changed

+125
-8
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ SpaceCat Task Processor is a Node.js service that processes messages from the AW
2727
1. Clone the repository
2828
2. Install dependencies:
2929
```sh
30-
npm install
30+
npm ci
3131
```
3232
3. Configure AWS credentials and environment variables as needed
3333

scripts/populate-env.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/bin/bash
2+
3+
# Define the secret name and region
4+
SECRET_NAME="/helix-deploy/spacecat-services/api-service/latest"
5+
REGION="us-east-1"
6+
7+
# Retrieve the secret from AWS Secrets Manager
8+
SECRET_JSON=$(aws secretsmanager get-secret-value --secret-id $SECRET_NAME --region $REGION --query SecretString --output text)
9+
10+
touch env.sh
11+
12+
# Parse the JSON and write to env.sh
13+
echo "$SECRET_JSON" | jq -r 'to_entries | .[] | "export \(.key)=\(.value | @sh)"' >> env.sh
14+
15+
echo "env.sh file has been populated with secrets from AWS Secrets Manager."

scripts/watch-and-copy.js

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* Copyright 2025 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
import chokidar from 'chokidar';
13+
import fs from 'fs';
14+
import path from 'path';
15+
import { fileURLToPath } from 'url';
16+
17+
const __filename = fileURLToPath(import.meta.url);
18+
const __dirname = path.dirname(__filename);
19+
20+
const srcDir = path.join(__dirname, '..', 'src');
21+
const destDir = path.join(__dirname, '..', '.aws-sam/build/SpacecatAuditWorkerFunction/src');
22+
23+
function copyFile(filePath) {
24+
try {
25+
const relativePath = path.relative(srcDir, filePath);
26+
const destPath = path.join(destDir, relativePath);
27+
28+
// Skip files that start with a dot
29+
if (path.basename(filePath).startsWith('.')) {
30+
return;
31+
}
32+
33+
fs.mkdirSync(path.dirname(destPath), { recursive: true });
34+
35+
// Read and compare file contents
36+
const srcContent = fs.readFileSync(filePath);
37+
let destContent;
38+
try {
39+
destContent = fs.readFileSync(destPath);
40+
} catch {
41+
// If the destination file doesn't exist, proceed with copying
42+
destContent = null;
43+
}
44+
45+
if (!destContent || !srcContent.equals(destContent)) {
46+
fs.copyFileSync(filePath, destPath);
47+
console.log(`Copied ${filePath} to ${destPath}`);
48+
}
49+
} catch (error) {
50+
console.error(`Error copying file ${filePath}:`, error);
51+
}
52+
}
53+
54+
// Initialize watcher.
55+
const watcher = chokidar.watch(srcDir, {
56+
ignored: /(^|[\\])\../, // ignore dotfiles
57+
persistent: true,
58+
});
59+
60+
// Add event listeners.
61+
watcher
62+
.on('add', copyFile)
63+
.on('change', copyFile)
64+
.on('error', (error) => console.error(`Watcher error: ${error}`));
65+
66+
console.log(`Watching for changes in ${srcDir}...`);
67+
68+
// Handle graceful shutdown
69+
process.on('SIGINT', () => {
70+
console.log('Stopping file watcher...');
71+
watcher.close().then(() => {
72+
console.log('File watcher closed.');
73+
process.exit(0);
74+
});
75+
});
76+
77+
// Output some initial stats
78+
setTimeout(() => {
79+
const watchedPaths = watcher.getWatched();
80+
const fileCount = Object.values(watchedPaths).reduce((acc, files) => acc + files.length, 0);
81+
console.log(`Watching ${fileCount} files in ${Object.keys(watchedPaths).length} directories`);
82+
}, 2000);

src/index.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
*/
1212
import wrap from '@adobe/helix-shared-wrap';
1313
import { helixStatus } from '@adobe/helix-status';
14+
import secrets from '@adobe/helix-shared-secrets';
1415
import dataAccess from '@adobe/spacecat-shared-data-access';
1516
import { sqsEventAdapter } from '@adobe/spacecat-shared-utils';
1617
import { internalServerError, notFound, ok } from '@adobe/spacecat-shared-http-utils';
@@ -26,6 +27,14 @@ const HANDLERS = {
2627
dummy: (message) => ok(message),
2728
};
2829

30+
// Custom secret name resolver to use the correct secret path
31+
function getSecretName() {
32+
return '/helix-deploy/spacecat-services/api-service/latest';
33+
}
34+
35+
// Export for testing
36+
export { getSecretName };
37+
2938
function getElapsedSeconds(startTime) {
3039
const endTime = process.hrtime(startTime);
3140
const elapsedSeconds = endTime[0] + endTime[1] / 1e9;
@@ -67,4 +76,5 @@ async function run(message, context) {
6776
export const main = wrap(run)
6877
.with(dataAccess)
6978
.with(sqsEventAdapter)
79+
.with(secrets, { name: getSecretName })
7080
.with(helixStatus);

src/tasks/demo-url-processor/handler.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ import { say } from '../../utils/slack-utils.js';
1616
const TASK_TYPE = 'demo-url-processor';
1717

1818
/**
19-
* Runs the demo url processor
20-
* @param {object} message - The message object
19+
* Runs the audit status processor
20+
* @param {object} demoUrlMessage - The demoUrlMessage object
2121
* @param {object} context - The context object
2222
*/
2323
export async function runDemoUrlProcessor(message, context) {

src/tasks/opportunity-status-processor/handler.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export async function runOpportunityStatusProcessor(message, context) {
6262

6363
try {
6464
// Get the site and its opportunities
65-
const site = await Site.findById(siteId);
65+
const site = await Site.findByBaseURL(`https://${siteId}.com`);
6666
if (!site) {
6767
log.error(`Site not found for siteId: ${siteId}`);
6868
await say(env, log, slackContext, `:x: Site not found for siteId: ${siteId}`);
@@ -83,8 +83,10 @@ export async function runOpportunityStatusProcessor(message, context) {
8383
continue;
8484
}
8585
processedTypes.add(opportunityType);
86+
8687
// eslint-disable-next-line no-await-in-loop
8788
const suggestions = await opportunity.getSuggestions();
89+
8890
// Get the opportunity title
8991
const opportunityTitle = getOpportunityTitle(opportunityType);
9092
const hasSuggestions = suggestions && suggestions.length > 0;

test/index.test.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import sinon from 'sinon';
1717
import sinonChai from 'sinon-chai';
1818
import { Request } from '@adobe/fetch';
1919
import esmock from 'esmock';
20-
import { main } from '../src/index.js';
20+
import { main, getSecretName } from '../src/index.js';
2121

2222
use(sinonChai);
2323

@@ -97,10 +97,18 @@ describe('Index Tests', () => {
9797
expect(resp.status).to.equal(200);
9898
// Verify the task handler was found
9999
expect(context.log.info.calledWith('Found task handler for type: dummy')).to.be.true;
100+
// Print all log.info calls for debugging
101+
// eslint-disable-next-line no-console
102+
console.log('log.info calls:', context.log.info.getCalls().map((call) => call.args[0]));
100103
// Verify the task completion message (using partial match since timing varies)
101104
expect(context.log.info.calledWithMatch(sinon.match('dummy task for site-id completed in'))).to.be.true;
102105
});
103106

107+
it('should cover getSecretName function', () => {
108+
const secretName = getSecretName();
109+
expect(secretName).to.equal('/helix-deploy/spacecat-services/api-service/latest');
110+
});
111+
104112
it('should handle handler throwing an error', async () => {
105113
// Test a handler type that doesn't exist to trigger the catch block
106114
messageBodyJson.type = 'opportunity-status-processor';

test/tasks/opportunity-status-processor/opportunity-status-processor.test.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ describe('Opportunity Status Processor', () => {
4747
.withSandbox(sandbox)
4848
.withDataAccess({
4949
Site: {
50-
findById: sandbox.stub().resolves(mockSite),
50+
findByBaseURL: sandbox.stub().resolves(mockSite),
5151
},
5252
})
5353
.build();
@@ -91,13 +91,13 @@ describe('Opportunity Status Processor', () => {
9191
auditTypes: ['cwv', 'broken-links'],
9292
})).to.be.true;
9393

94-
expect(context.dataAccess.Site.findById.calledWith('test-site-id')).to.be.true;
94+
expect(context.dataAccess.Site.findByBaseURL.calledWith('https://test-site-id.com')).to.be.true;
9595
expect(mockSite.getOpportunities.called).to.be.true;
9696
expect(context.log.info.calledWith('Found 2 opportunities for site test-site-id')).to.be.true;
9797
});
9898

9999
it('should handle site not found error', async () => {
100-
context.dataAccess.Site.findById.resolves(null);
100+
context.dataAccess.Site.findByBaseURL.resolves(null);
101101

102102
await runOpportunityStatusProcessor(message, context);
103103

0 commit comments

Comments
 (0)