Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"build": "hedy -v --test-bundle",
"deploy": "hedy -v --deploy --aws-deploy-bucket=spacecat-prod-deploy --pkgVersion=latest",
"deploy-stage": "hedy -v --deploy --aws-deploy-bucket=spacecat-stage-deploy --pkgVersion=latest",
"deploy-dev": "hedy -v --deploy --pkgVersion=latest$CI_BUILD_NUM -l latest --aws-deploy-bucket=spacecat-dev-deploy --cleanup-ci=24h --aws-api vldld6qz1d",
"deploy-dev": "hedy -v --deploy --pkgVersion=latest$CI_BUILD_NUM -l sandsinh --aws-deploy-bucket=spacecat-dev-deploy --cleanup-ci=24h --aws-api vldld6qz1d",
"deploy-secrets": "hedy --aws-update-secrets --params-file=secrets/secrets.env",
"docs": "npm run docs:lint && npm run docs:build",
"docs:build": "npx @redocly/cli build-docs -o ./docs/index.html --config docs/openapi/redocly-config.yaml",
Expand Down Expand Up @@ -74,7 +74,7 @@
"@adobe/spacecat-helix-content-sdk": "1.4.24",
"@adobe/spacecat-shared-athena-client": "1.3.5",
"@adobe/spacecat-shared-brand-client": "1.1.24",
"@adobe/spacecat-shared-data-access": "2.65.0",
"@adobe/spacecat-shared-data-access": "https://gitpkg.now.sh/adobe/spacecat-shared/packages/spacecat-shared-data-access?SITES-35629",
"@adobe/spacecat-shared-gpt-client": "1.6.5",
"@adobe/spacecat-shared-http-utils": "1.17.6",
"@adobe/spacecat-shared-ims-client": "1.8.13",
Expand Down
7 changes: 6 additions & 1 deletion src/controllers/fixes.js
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ export class FixesController {
}

const {
executedBy, executedAt, publishedAt, changeDetails, suggestionIds,
executedBy, executedAt, publishedAt, changeDetails, suggestionIds, origin,
} = context.data;

const Suggestion = this.#Suggestion;
Expand Down Expand Up @@ -353,6 +353,11 @@ export class FixesController {
hasUpdates = true;
}

if (origin !== fix.getOrigin() && hasText(origin)) {
fix.setOrigin(origin);
hasUpdates = true;
}

if (hasUpdates) {
return ok(FixDto.toJSON(await fix.save()));
} else {
Expand Down
3 changes: 2 additions & 1 deletion src/dto/fix.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,12 @@ export const FixDto = {
opportunityId: fix.getOpportunityId(),
type: fix.getType(),
createdAt: fix.getCreatedAt(),
executedBy: fix.getExecutedAt(),
executedBy: fix.getExecutedBy(),
executedAt: fix.getExecutedAt(),
publishedAt: fix.getPublishedAt(),
changeDetails: fix.getChangeDetails(),
status: fix.getStatus(),
origin: fix.getOrigin(),
};
},
};
76 changes: 76 additions & 0 deletions test/controllers/fixes.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,27 @@ describe('Fixes Controller', () => {
expect(new Set(await fix.getSuggestions())).deep.equals(new Set(suggestions));
});

it('can patch a fix origin field', async () => {
const suggestions = await Promise.all([
createSuggestion({ type: 'CONTENT_UPDATE' }),
createSuggestion({ type: 'METADATA_UPDATE' }),
]);

const newOrigin = FixEntity.ORIGINS.ASO;
requestContext.data = {
origin: newOrigin,
suggestionIds: suggestions.map((s) => s.getId()),
};

const response = await fixesController.patchFix(requestContext);
expect(response).includes({ status: 200 });
const responseData = await response.json();
expect(responseData).deep.equals(FixDto.toJSON(fix));
expect(responseData.origin).to.equal(FixEntity.ORIGINS.ASO);
expect(fix.getOrigin()).equals(newOrigin);
expect(new Set(await fix.getSuggestions())).deep.equals(new Set(suggestions));
});

it('responds 404 if a suggestion does not exist', async () => {
requestContext.data = {
suggestionIds: ['15345195-62e6-494c-81b1-1d0da0b51d84'],
Expand Down Expand Up @@ -1001,12 +1022,67 @@ describe('Fixes Controller', () => {
});
});
});

describe('FixDto', () => {
it('serializes fix entity with origin field', async () => {
const fixData = {
type: Suggestion.TYPES.CONTENT_UPDATE,
opportunityId,
changeDetails: { arbitrary: 'test value' },
origin: FixEntity.ORIGINS.ASO,
status: FixEntity.STATUSES.DEPLOYED,
executedBy: 'test-user',
executedAt: '2025-05-19T01:23:45.678Z',
publishedAt: '2025-05-19T02:23:45.678Z',
};

const fix = await fixEntityCollection.create(fixData);
const serialized = FixDto.toJSON(fix);

expect(serialized).to.include.keys([
'id',
'opportunityId',
'type',
'createdAt',
'executedBy',
'executedAt',
'publishedAt',
'changeDetails',
'status',
'origin',
]);

expect(serialized.origin).to.equal(FixEntity.ORIGINS.ASO);
expect(serialized.status).to.equal(FixEntity.STATUSES.DEPLOYED);
expect(serialized.type).to.equal(Suggestion.TYPES.CONTENT_UPDATE);
expect(serialized.opportunityId).to.equal(opportunityId);
expect(serialized.changeDetails).to.deep.equal({ arbitrary: 'test value' });
expect(serialized.executedBy).to.equal('test-user');
expect(serialized.executedAt).to.equal('2025-05-19T01:23:45.678Z');
expect(serialized.publishedAt).to.equal('2025-05-19T02:23:45.678Z');
});

it('serializes fix entity with default origin when not specified', async () => {
const fixData = {
type: Suggestion.TYPES.METADATA_UPDATE,
opportunityId,
changeDetails: { arbitrary: 'default test' },
};

const fix = await fixEntityCollection.create(fixData);
const serialized = FixDto.toJSON(fix);

expect(serialized.origin).to.equal(FixEntity.ORIGINS.SPACECAT);
expect(serialized.status).to.equal(FixEntity.STATUSES.PENDING);
});
});
});

const ISO_DATE = '2025-05-19T01:23:45.678Z';
function fakeCreateFix(data) {
data.fixEntityId ??= crypto.randomUUID();
data.status ??= FixEntity.STATUSES.PENDING;
data.origin ??= FixEntity.ORIGINS.SPACECAT;
data.changeDetails ??= { arbitrary: 'details' };
data.createdAt ??= ISO_DATE;
data.executedAt ??= ISO_DATE;
Expand Down