diff --git a/packages/spacecat-shared-data-access/src/dto/audit.js b/packages/spacecat-shared-data-access/src/dto/audit.js index 13c427152..e04712058 100644 --- a/packages/spacecat-shared-data-access/src/dto/audit.js +++ b/packages/spacecat-shared-data-access/src/dto/audit.js @@ -32,10 +32,16 @@ export const AuditDto = { * @returns {{siteId, auditedAt, auditResult, auditType, expiresAt, fullAuditRef, SK: string}} */ toDynamoItem: (audit, latestAudit = false) => { - const latestAuditProps = latestAudit ? { - GSI1PK: 'ALL_LATEST_AUDITS', - GSI1SK: `${audit.getAuditType()}#${Object.values(audit.getScores()).join('#')}`, - } : {}; + const GSI1PK = 'ALL_LATEST_AUDITS'; + let GSI1SK; + + if (audit.isError()) { + GSI1SK = `${audit.getAuditType()}#error`; + } else { + GSI1SK = `${audit.getAuditType()}#${Object.values(audit.getScores()).join('#')}`; + } + + const latestAuditProps = latestAudit ? { GSI1PK, GSI1SK } : {}; return { siteId: audit.getSiteId(), diff --git a/packages/spacecat-shared-data-access/src/models/audit.js b/packages/spacecat-shared-data-access/src/models/audit.js index 91d7d3b5f..827c97a18 100644 --- a/packages/spacecat-shared-data-access/src/models/audit.js +++ b/packages/spacecat-shared-data-access/src/models/audit.js @@ -32,6 +32,10 @@ const AUDIT_TYPE_PROPERTIES = { * @returns {boolean} - True if valid, false otherwise. */ const validateScores = (auditResult, auditType) => { + if (isObject(auditResult.runtimeError)) { + return true; + } + const expectedProperties = AUDIT_TYPE_PROPERTIES[auditType]; if (!expectedProperties) { throw new Error(`Unknown audit type: ${auditType}`); diff --git a/packages/spacecat-shared-data-access/test/unit/service/audits/index.test.js b/packages/spacecat-shared-data-access/test/unit/service/audits/index.test.js index e6d19c687..07317a948 100644 --- a/packages/spacecat-shared-data-access/test/unit/service/audits/index.test.js +++ b/packages/spacecat-shared-data-access/test/unit/service/audits/index.test.js @@ -206,6 +206,30 @@ describe('Audit Access Pattern Tests', () => { expect(result.getScores()).to.be.an('object'); }); + it('successfully adds an error audit', async () => { + const auditResult = { + ...auditData.auditResult, + runtimeError: { + code: 'NO_FCP', + message: 'No FCP found', + }, + }; + const result = await exportedFunctions.addAudit({ + ...auditData, + auditResult, + }); + + // Once for 'audits' and once for 'latest_audits' + expect(mockDynamoClient.putItem.calledTwice).to.be.true; + expect(result.getSiteId()).to.equal(auditData.siteId); + expect(result.getAuditType()).to.equal(auditData.auditType); + expect(result.getAuditedAt()).to.equal(auditData.auditedAt); + expect(result.getAuditResult()).to.deep.equal(auditResult); + expect(result.getFullAuditRef()).to.equal(auditData.fullAuditRef); + expect(result.isError()).to.be.true; + expect(result.getScores()).to.be.an('object'); + }); + it('throws an error if audit already exists', async () => { mockDynamoClient.getItem.resolves(auditData);