From a30bfb7d576f9931a7cf6efbe5954c225dcdd755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominique=20J=C3=A4ggi?= Date: Fri, 15 Dec 2023 14:26:23 +0100 Subject: [PATCH 1/2] feat: add audit config --- .../docs/schema.json | 4 +++ .../src/dto/site.js | 2 ++ .../src/index.d.ts | 13 +++++++++ .../src/models/audit.js | 1 + .../src/models/site.js | 10 ++++++- .../test/unit/models/site.test.js | 28 +++++++++++++++++++ 6 files changed, 57 insertions(+), 1 deletion(-) diff --git a/packages/spacecat-shared-data-access/docs/schema.json b/packages/spacecat-shared-data-access/docs/schema.json index e1518f393..fc99d3886 100644 --- a/packages/spacecat-shared-data-access/docs/schema.json +++ b/packages/spacecat-shared-data-access/docs/schema.json @@ -38,6 +38,10 @@ "AttributeName": "GSI1PK", "AttributeType": "S" }, + { + "AttributeName": "auditConfig", + "AttributeType": "M" + }, { "AttributeName": "createdAt", "AttributeType": "S" diff --git a/packages/spacecat-shared-data-access/src/dto/site.js b/packages/spacecat-shared-data-access/src/dto/site.js index 5f13a78cb..35c934658 100644 --- a/packages/spacecat-shared-data-access/src/dto/site.js +++ b/packages/spacecat-shared-data-access/src/dto/site.js @@ -30,6 +30,7 @@ export const SiteDto = { createdAt: site.getCreatedAt(), updatedAt: site.getUpdatedAt(), GSI1PK: 'ALL_SITES', + auditConfig: site.getAuditConfig(), }), /** @@ -46,6 +47,7 @@ export const SiteDto = { isLive: dynamoItem.isLive, createdAt: dynamoItem.createdAt, updatedAt: dynamoItem.updatedAt, + auditConfig: dynamoItem.auditConfig, }; return createSite(siteData); diff --git a/packages/spacecat-shared-data-access/src/index.d.ts b/packages/spacecat-shared-data-access/src/index.d.ts index 3a967add5..d07966db4 100644 --- a/packages/spacecat-shared-data-access/src/index.d.ts +++ b/packages/spacecat-shared-data-access/src/index.d.ts @@ -20,9 +20,21 @@ export interface Audit { getExpiresAt: () => Date; getFullAuditRef: () => string; isLive: () => boolean; + isError: () => boolean; getScores: () => object; } +// AuditConfigType defines the structure for specific audit type configurations +export interface AuditConfigType { + disabled(): boolean; +} + +// AuditConfig defines the structure for the overall audit configuration of a site +export interface AuditConfig { + auditsDisabled: boolean; + auditTypeConfigs: Record; +} + export interface Site { getId: () => string; getBaseURL: () => string; @@ -30,6 +42,7 @@ export interface Site { getImsOrgId: () => string; getCreatedAt: () => string; getUpdatedAt: () => string; + getAuditConfig: () => AuditConfig; getAudits: () => Audit[]; isLive: () => boolean; setAudits: (audits: Audit[]) => Site; diff --git a/packages/spacecat-shared-data-access/src/models/audit.js b/packages/spacecat-shared-data-access/src/models/audit.js index a74295d9f..91d7d3b5f 100644 --- a/packages/spacecat-shared-data-access/src/models/audit.js +++ b/packages/spacecat-shared-data-access/src/models/audit.js @@ -61,6 +61,7 @@ const Audit = (data = {}) => { self.getExpiresAt = () => self.state.expiresAt; self.getFullAuditRef = () => self.state.fullAuditRef; self.isLive = () => self.state.isLive; + self.isError = () => hasText(self.getAuditResult().runtimeError?.code); self.getScores = () => self.getAuditResult().scores; return Object.freeze(self); diff --git a/packages/spacecat-shared-data-access/src/models/site.js b/packages/spacecat-shared-data-access/src/models/site.js index 25ad4e24f..18ae832da 100644 --- a/packages/spacecat-shared-data-access/src/models/site.js +++ b/packages/spacecat-shared-data-access/src/models/site.js @@ -10,7 +10,7 @@ * governing permissions and limitations under the License. */ -import { hasText, isValidUrl } from '@adobe/spacecat-shared-utils'; +import { hasText, isObject, isValidUrl } from '@adobe/spacecat-shared-utils'; import { Base } from './base.js'; /** @@ -22,6 +22,7 @@ import { Base } from './base.js'; const Site = (data = {}) => { const self = Base(data); + self.getAuditConfig = () => self.state.auditConfig; self.getAudits = () => self.state.audits; self.getBaseURL = () => self.state.baseURL; self.getGitHubURL = () => self.state.gitHubURL; @@ -135,5 +136,12 @@ export const createSite = (data) => { newState.audits = []; } + if (!isObject(newState.auditConfig)) { + newState.auditConfig = { + auditsDisabled: false, + auditTypeConfigs: {}, + }; + } + return Site(newState); }; diff --git a/packages/spacecat-shared-data-access/test/unit/models/site.test.js b/packages/spacecat-shared-data-access/test/unit/models/site.test.js index 60713ec51..8819dd67a 100644 --- a/packages/spacecat-shared-data-access/test/unit/models/site.test.js +++ b/packages/spacecat-shared-data-access/test/unit/models/site.test.js @@ -33,6 +33,27 @@ describe('Site Model Tests', () => { expect(site).to.be.an('object'); expect(site.getBaseURL()).to.equal(validData.baseURL); }); + + it('creates a site with default auditConfig when none provided', () => { + const site = createSite({ ...validData }); + expect(site.getAuditConfig()).to.be.an('object'); + expect(site.getAuditConfig()).to.deep.equal({ + auditsDisabled: false, + auditTypeConfigs: {}, + }); + }); + + it('creates a site with provided auditConfig', () => { + const auditConfig = { + auditsDisabled: true, + auditTypeConfigs: { + type1: { /* some config */ }, + type2: { /* some config */ }, + }, + }; + const site = createSite({ ...validData, auditConfig }); + expect(site.getAuditConfig()).to.deep.equal(auditConfig); + }); }); describe('Site Object Functionality', () => { @@ -119,5 +140,12 @@ describe('Site Model Tests', () => { expect(site.isLive()).to.be.true; }); + + it('retrieves auditConfig correctly', () => { + const auditConfig = site.getAuditConfig(); + expect(auditConfig).to.be.an('object'); + expect(auditConfig).to.have.property('auditsDisabled').that.is.a('boolean'); + expect(auditConfig).to.have.property('auditTypeConfigs').that.is.an('object'); + }); }); }); From b010b73d144f519d4be56a7bf298b9f8f0a9bd69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominique=20J=C3=A4ggi?= Date: Fri, 15 Dec 2023 17:10:39 +0100 Subject: [PATCH 2/2] fix: dto, tests --- .../src/dto/site.js | 3 +- .../src/index.d.ts | 4 +- .../src/models/site.js | 4 + .../src/models/site/audit-config-type.js | 28 ++++ .../src/models/site/audit-config.js | 41 ++++++ .../test/it/db.test.js | 16 +++ .../test/it/generateSampleData.js | 7 + .../test/unit/models/site.test.js | 49 +++++-- .../models/site/audit-config-type.test.js | 69 ++++++++++ .../unit/models/site/audit-config.test.js | 121 ++++++++++++++++++ 10 files changed, 326 insertions(+), 16 deletions(-) create mode 100644 packages/spacecat-shared-data-access/src/models/site/audit-config-type.js create mode 100644 packages/spacecat-shared-data-access/src/models/site/audit-config.js create mode 100644 packages/spacecat-shared-data-access/test/unit/models/site/audit-config-type.test.js create mode 100644 packages/spacecat-shared-data-access/test/unit/models/site/audit-config.test.js diff --git a/packages/spacecat-shared-data-access/src/dto/site.js b/packages/spacecat-shared-data-access/src/dto/site.js index 35c934658..081f48254 100644 --- a/packages/spacecat-shared-data-access/src/dto/site.js +++ b/packages/spacecat-shared-data-access/src/dto/site.js @@ -11,6 +11,7 @@ */ import { createSite } from '../models/site.js'; +import AuditConfig from '../models/site/audit-config.js'; /** * Data transfer object for Site. @@ -30,7 +31,7 @@ export const SiteDto = { createdAt: site.getCreatedAt(), updatedAt: site.getUpdatedAt(), GSI1PK: 'ALL_SITES', - auditConfig: site.getAuditConfig(), + auditConfig: AuditConfig.toDynamoItem(site.getAuditConfig()), }), /** diff --git a/packages/spacecat-shared-data-access/src/index.d.ts b/packages/spacecat-shared-data-access/src/index.d.ts index d07966db4..7c5741db9 100644 --- a/packages/spacecat-shared-data-access/src/index.d.ts +++ b/packages/spacecat-shared-data-access/src/index.d.ts @@ -31,8 +31,8 @@ export interface AuditConfigType { // AuditConfig defines the structure for the overall audit configuration of a site export interface AuditConfig { - auditsDisabled: boolean; - auditTypeConfigs: Record; + auditsDisabled: () => boolean; + getAuditConfigForType: (auditType: string) => AuditConfigType; } export interface Site { diff --git a/packages/spacecat-shared-data-access/src/models/site.js b/packages/spacecat-shared-data-access/src/models/site.js index 18ae832da..752e4a228 100644 --- a/packages/spacecat-shared-data-access/src/models/site.js +++ b/packages/spacecat-shared-data-access/src/models/site.js @@ -11,7 +11,9 @@ */ import { hasText, isObject, isValidUrl } from '@adobe/spacecat-shared-utils'; + import { Base } from './base.js'; +import AuditConfig from './site/audit-config.js'; /** * Creates a new Site. @@ -143,5 +145,7 @@ export const createSite = (data) => { }; } + newState.auditConfig = AuditConfig(newState.auditConfig); + return Site(newState); }; diff --git a/packages/spacecat-shared-data-access/src/models/site/audit-config-type.js b/packages/spacecat-shared-data-access/src/models/site/audit-config-type.js new file mode 100644 index 000000000..00f71fc1f --- /dev/null +++ b/packages/spacecat-shared-data-access/src/models/site/audit-config-type.js @@ -0,0 +1,28 @@ +/* + * Copyright 2023 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +const AuditConfigType = (data = {}, allAuditsDisabled = false) => ({ + disabled: () => allAuditsDisabled || data.disabled || false, +}); + +AuditConfigType.fromDynamoItem = (dynamoItem) => { + const auditConfigTypeData = { + disabled: dynamoItem.disabled, + }; + return AuditConfigType(auditConfigTypeData); +}; + +AuditConfigType.toDynamoItem = (auditConfigType) => ({ + disabled: auditConfigType.disabled(), +}); + +export default AuditConfigType; diff --git a/packages/spacecat-shared-data-access/src/models/site/audit-config.js b/packages/spacecat-shared-data-access/src/models/site/audit-config.js new file mode 100644 index 000000000..ded497bb5 --- /dev/null +++ b/packages/spacecat-shared-data-access/src/models/site/audit-config.js @@ -0,0 +1,41 @@ +/* + * Copyright 2023 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import AuditConfigType from './audit-config-type.js'; + +function getAuditTypeConfigs(auditTypeConfigs, auditsDisabled) { + return Object.entries(auditTypeConfigs || {}).reduce((acc, [key, value]) => { + acc[key] = AuditConfigType(value, auditsDisabled); + return acc; + }, {}); +} + +const AuditConfig = (data = {}) => { + const auditTypeConfigs = getAuditTypeConfigs(data.auditTypeConfigs, data.auditsDisabled); + return { + auditsDisabled: () => data.auditsDisabled || false, + getAuditTypeConfigs: () => auditTypeConfigs, + getAuditTypeConfig: (type) => auditTypeConfigs[type], + }; +}; + +AuditConfig.fromDynamoItem = (dynamoItem) => AuditConfig(dynamoItem); + +AuditConfig.toDynamoItem = (auditConfig) => ({ + auditsDisabled: auditConfig.auditsDisabled(), + auditTypeConfigs: Object.entries(auditConfig.getAuditTypeConfigs()) + .reduce((acc, [key, value]) => { + acc[key] = AuditConfigType.toDynamoItem(value); + return acc; + }, {}), +}); + +export default AuditConfig; diff --git a/packages/spacecat-shared-data-access/test/it/db.test.js b/packages/spacecat-shared-data-access/test/it/db.test.js index 10a8410fa..97ca1c31f 100644 --- a/packages/spacecat-shared-data-access/test/it/db.test.js +++ b/packages/spacecat-shared-data-access/test/it/db.test.js @@ -36,6 +36,15 @@ function checkSite(site) { expect(isIsoDate(site.getUpdatedAt())).to.be.true; expect(site.getAudits()).to.be.an('array'); expect(site.isLive()).to.be.a('boolean'); + + const auditConfig = site.getAuditConfig(); + expect(auditConfig).to.be.an('object'); + expect(auditConfig.auditsDisabled()).to.be.a('boolean').which.is.false; + expect(auditConfig.getAuditTypeConfig(AUDIT_TYPE_LHS_MOBILE)).to.be.an('object'); + expect(auditConfig.getAuditTypeConfig(AUDIT_TYPE_LHS_MOBILE).disabled()).to.be.a('boolean').which.is.false; + expect(auditConfig.getAuditTypeConfig('non-existing-type')).to.be.undefined; + expect(auditConfig.getAuditTypeConfig('cwv')).to.be.an('object'); + expect(auditConfig.getAuditTypeConfig('cwv').disabled()).to.be.a('boolean').which.is.true; } function checkAudit(audit) { @@ -152,6 +161,13 @@ describe('DynamoDB Integration Test', async () => { gitHubURL: 'https://github.com/some-org/test-repo', imsOrgId: 'newOrg123', audits: [], + auditConfig: { + auditsDisabled: false, + auditTypeConfigs: { + 'lhs-mobile': { disabled: false }, + cwv: { disabled: true }, + }, + }, }; const addedSite = await dataAccess.addSite(newSiteData); diff --git a/packages/spacecat-shared-data-access/test/it/generateSampleData.js b/packages/spacecat-shared-data-access/test/it/generateSampleData.js index 14cffb638..a477d84bf 100644 --- a/packages/spacecat-shared-data-access/test/it/generateSampleData.js +++ b/packages/spacecat-shared-data-access/test/it/generateSampleData.js @@ -169,6 +169,13 @@ export default async function generateSampleData( GSI1PK: config.pkAllSites, createdAt: nowIso, updatedAt: nowIso, + auditConfig: { + auditsDisabled: false, + auditTypeConfigs: { + 'lhs-mobile': { disabled: false }, + cwv: { disabled: true }, + }, + }, }); if (i % 10 !== 0) { // Every tenth site will not have any audits diff --git a/packages/spacecat-shared-data-access/test/unit/models/site.test.js b/packages/spacecat-shared-data-access/test/unit/models/site.test.js index 8819dd67a..7fa52a1a0 100644 --- a/packages/spacecat-shared-data-access/test/unit/models/site.test.js +++ b/packages/spacecat-shared-data-access/test/unit/models/site.test.js @@ -16,10 +16,16 @@ import { expect } from 'chai'; import { createSite } from '../../../src/models/site.js'; import { sleep } from '../util.js'; -// Constants for testing const validData = { baseURL: 'https://www.example.com', imsOrgId: 'org123', + auditConfig: { + auditsDisabled: false, + auditTypeConfigs: { + type1: { /* some config */ }, + type2: { /* some config */ }, + }, + }, }; describe('Site Model Tests', () => { @@ -36,23 +42,30 @@ describe('Site Model Tests', () => { it('creates a site with default auditConfig when none provided', () => { const site = createSite({ ...validData }); - expect(site.getAuditConfig()).to.be.an('object'); - expect(site.getAuditConfig()).to.deep.equal({ - auditsDisabled: false, - auditTypeConfigs: {}, - }); + const auditConfig = site.getAuditConfig(); + + expect(auditConfig).to.be.an('object'); + expect(auditConfig.auditsDisabled()).be.false; + expect(auditConfig.getAuditTypeConfig('type1')).to.be.an('object'); }); it('creates a site with provided auditConfig', () => { - const auditConfig = { + const newAuditConfig = { auditsDisabled: true, auditTypeConfigs: { type1: { /* some config */ }, type2: { /* some config */ }, }, }; - const site = createSite({ ...validData, auditConfig }); - expect(site.getAuditConfig()).to.deep.equal(auditConfig); + const site = createSite({ ...validData, auditConfig: newAuditConfig }); + const auditConfig = site.getAuditConfig(); + + expect(auditConfig).to.be.an('object'); + expect(auditConfig.auditsDisabled()).to.be.true; + expect(auditConfig.getAuditTypeConfig('type1')).to.be.an('object'); + expect(auditConfig.getAuditTypeConfig('type1').disabled()).to.be.true; + expect(auditConfig.getAuditTypeConfig('type2')).to.be.an('object'); + expect(auditConfig.getAuditTypeConfig('type2').disabled()).to.be.true; }); }); @@ -141,11 +154,21 @@ describe('Site Model Tests', () => { expect(site.isLive()).to.be.true; }); - it('retrieves auditConfig correctly', () => { - const auditConfig = site.getAuditConfig(); + it('handles AuditConfig and AuditConfigType correctly', () => { + const auditConfigData = { + auditsDisabled: false, + auditTypeConfigs: { + type1: { /* some config */ }, + type2: { /* some config */ }, + }, + }; + const newSite = createSite({ ...validData, auditConfig: auditConfigData }); + const auditConfig = newSite.getAuditConfig(); + expect(auditConfig).to.be.an('object'); - expect(auditConfig).to.have.property('auditsDisabled').that.is.a('boolean'); - expect(auditConfig).to.have.property('auditTypeConfigs').that.is.an('object'); + expect(auditConfig.auditsDisabled()).to.be.false; + expect(auditConfig.getAuditTypeConfig('type1')).to.be.an('object'); + expect(auditConfig.getAuditTypeConfig('type1').disabled()).to.be.false; }); }); }); diff --git a/packages/spacecat-shared-data-access/test/unit/models/site/audit-config-type.test.js b/packages/spacecat-shared-data-access/test/unit/models/site/audit-config-type.test.js new file mode 100644 index 000000000..703ec4857 --- /dev/null +++ b/packages/spacecat-shared-data-access/test/unit/models/site/audit-config-type.test.js @@ -0,0 +1,69 @@ +/* + * Copyright 2023 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +/* eslint-env mocha */ + +import { expect } from 'chai'; + +import AuditConfigType from '../../../../src/models/site/audit-config-type.js'; + +describe('AuditConfigType Tests', () => { + describe('AuditConfigType Creation', () => { + it('creates an AuditConfigType with default disabled as false', () => { + const auditConfigType = AuditConfigType(); + expect(auditConfigType.disabled()).to.be.false; + }); + + it('creates an AuditConfigType with specified disabled value', () => { + const auditConfigType = AuditConfigType({ disabled: true }); + expect(auditConfigType.disabled()).to.be.true; + }); + + it('considers allAuditsDisabled flag', () => { + const auditConfigType = AuditConfigType({}, true); + expect(auditConfigType.disabled()).to.be.true; + }); + }); + + describe('disabled Method', () => { + it('returns true when audit is disabled', () => { + const auditConfigType = AuditConfigType({ disabled: true }); + expect(auditConfigType.disabled()).to.be.true; + }); + + it('returns false when audit is not disabled', () => { + const auditConfigType = AuditConfigType({ disabled: false }); + expect(auditConfigType.disabled()).to.be.false; + }); + + it('returns true if allAuditsDisabled is true regardless of data.disabled', () => { + const auditConfigType = AuditConfigType({ disabled: false }, true); + expect(auditConfigType.disabled()).to.be.true; + }); + }); + + describe('fromDynamoItem Static Method', () => { + it('correctly converts from DynamoDB item', () => { + const dynamoItem = { disabled: true }; + const auditConfigType = AuditConfigType.fromDynamoItem(dynamoItem); + expect(auditConfigType.disabled()).to.be.true; + }); + }); + + describe('toDynamoItem Static Method', () => { + it('correctly converts to DynamoDB item format', () => { + const auditConfigType = AuditConfigType({ disabled: true }); + const dynamoItem = AuditConfigType.toDynamoItem(auditConfigType); + expect(dynamoItem.disabled).to.be.true; + }); + }); +}); diff --git a/packages/spacecat-shared-data-access/test/unit/models/site/audit-config.test.js b/packages/spacecat-shared-data-access/test/unit/models/site/audit-config.test.js new file mode 100644 index 000000000..03c4d6c83 --- /dev/null +++ b/packages/spacecat-shared-data-access/test/unit/models/site/audit-config.test.js @@ -0,0 +1,121 @@ +/* + * Copyright 2023 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +/* eslint-env mocha */ + +import { expect } from 'chai'; + +import AuditConfig from '../../../../src/models/site/audit-config.js'; + +describe('AuditConfig Tests', () => { + describe('AuditConfig Creation', () => { + it('creates an AuditConfig with defaults when no data is provided', () => { + const auditConfig = AuditConfig(); + expect(auditConfig.auditsDisabled()).to.be.false; + expect(auditConfig.getAuditTypeConfigs()).to.be.empty; + }); + + it('creates an AuditConfig with provided data', () => { + const data = { + auditsDisabled: true, + auditTypeConfigs: { + type1: { disabled: true }, + type2: { disabled: false }, + }, + }; + const auditConfig = AuditConfig(data); + expect(auditConfig.auditsDisabled()).to.be.true; + expect(auditConfig.getAuditTypeConfig('type1').disabled()).to.be.true; + expect(auditConfig.getAuditTypeConfig('type2').disabled()).to.be.true; + }); + }); + + describe('auditsDisabled Method', () => { + it('returns true when audits are disabled', () => { + const auditConfig = AuditConfig({ auditsDisabled: true }); + expect(auditConfig.auditsDisabled()).to.be.true; + }); + + it('returns false when audits are not disabled', () => { + const auditConfig = AuditConfig({ auditsDisabled: false }); + expect(auditConfig.auditsDisabled()).to.be.false; + }); + }); + + describe('getAuditTypeConfig Method', () => { + it('returns the correct AuditConfigType for a given type', () => { + const data = { + auditTypeConfigs: { type1: { disabled: true } }, + }; + const auditConfig = AuditConfig(data); + const typeConfig = auditConfig.getAuditTypeConfig('type1'); + expect(typeConfig).to.be.an('object'); + expect(typeConfig.disabled()).to.be.true; + }); + }); + + describe('getAuditTypeConfigs Method', () => { + it('returns all audit type configurations', () => { + const data = { + auditTypeConfigs: { + type1: { disabled: true }, + type2: { disabled: false }, + }, + }; + const auditConfig = AuditConfig(data); + const typeConfigs = auditConfig.getAuditTypeConfigs(); + expect(typeConfigs).to.have.keys(['type1', 'type2']); + }); + + it('returns no audit type configurations', () => { + const data = { + auditTypeConfigs: {}, + }; + const auditConfig = AuditConfig(data); + const typeConfigs = auditConfig.getAuditTypeConfigs(); + expect(typeConfigs).to.be.an('object').that.is.empty; + }); + }); + + describe('fromDynamoItem Static Method', () => { + it('correctly converts from DynamoDB item', () => { + const dynamoItem = { + auditsDisabled: false, + auditTypeConfigs: { + type1: { disabled: true }, + type2: { disabled: false }, + }, + }; + const auditConfig = AuditConfig.fromDynamoItem(dynamoItem); + expect(auditConfig.auditsDisabled()).to.be.false; + expect(auditConfig.getAuditTypeConfig('type1').disabled()).to.be.true; + expect(auditConfig.getAuditTypeConfig('type2').disabled()).to.be.false; + }); + }); + + describe('toDynamoItem Static Method', () => { + it('correctly converts to DynamoDB item format', () => { + const data = { + auditsDisabled: false, + auditTypeConfigs: { + type1: { disabled: true }, + type2: { disabled: false }, + }, + }; + const auditConfig = AuditConfig(data); + const dynamoItem = AuditConfig.toDynamoItem(auditConfig); + expect(dynamoItem.auditsDisabled).to.be.false; + expect(dynamoItem.auditTypeConfigs.type1.disabled).to.be.true; + expect(dynamoItem.auditTypeConfigs.type2.disabled).to.be.false; + }); + }); +});