From 06dc51ff788f64d62d980f28d8c86a3609988fbe Mon Sep 17 00:00:00 2001 From: alinarublea Date: Tue, 24 Oct 2023 20:19:24 +0200 Subject: [PATCH] feat: partially write tests and fix get site command --- src/db.js | 8 +-- test/db-wrapper.test.js | 52 +++++++++++++++++ test/db.test.js | 93 +++++++++++++++++++++++++++++++ test/dynamo-db-doc-client-mock.js | 37 ++++++++++++ 4 files changed, 186 insertions(+), 4 deletions(-) create mode 100644 test/db-wrapper.test.js create mode 100644 test/db.test.js create mode 100644 test/dynamo-db-doc-client-mock.js diff --git a/src/db.js b/src/db.js index 369cdbe3..ba9e0b13 100644 --- a/src/db.js +++ b/src/db.js @@ -10,7 +10,7 @@ * governing permissions and limitations under the License. */ import { DynamoDBClient } from '@aws-sdk/client-dynamodb'; -import { DynamoDBDocumentClient, GetItemCommand, PutCommand } from '@aws-sdk/lib-dynamodb'; +import { DynamoDBDocumentClient, GetCommand, PutCommand } from '@aws-sdk/lib-dynamodb'; const TABLE_SITES = 'spacecat-site'; const TABLE_AUDITS = 'spacecat-audit-index'; @@ -82,7 +82,7 @@ export default class DB { ], }; await this.saveRecord(newAudit, TABLE_AUDITS); - this.log.info(`Audit for domain ${site.domain} saved successfully at ${now}`); + this.log.info(`Audit for domain ${site.domain} saved successfully`); return Promise.resolve(newAudit); } @@ -119,8 +119,8 @@ export default class DB { }; try { - const command = new GetItemCommand(commandParams); - const response = await this.client.send(command); + const command = new GetCommand(commandParams); + const response = await this.docClient.send(command); const item = response.Item; if (item) { this.log.info(`Item retrieved successfully: ${item}`); diff --git a/test/db-wrapper.test.js b/test/db-wrapper.test.js new file mode 100644 index 00000000..cc20669b --- /dev/null +++ b/test/db-wrapper.test.js @@ -0,0 +1,52 @@ +/* + * 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 assert from 'assert'; +import dynamoDBWrapper from '../src/db-wrapper.js'; +import DB from '../src/db.js'; + +describe('DB Wrapper Tests', () => { + let mockFunc; + let mockRequest; + let mockContext; + + beforeEach(() => { + mockFunc = async () => {}; + mockRequest = {}; + mockContext = { + attributes: {}, + runtime: { + region: 'test-region', + }, + log: { + info: () => {}, + error: () => {}, + }, + }; + }); + + it('should create db if not present in context', async () => { + await dynamoDBWrapper(mockFunc)(mockRequest, mockContext); + assert(mockContext.db instanceof DB, 'context.db was not correctly instantiated.'); + }); + + it('should not re-initialize db if already present in context', async () => { + const mockDB = new DB(mockContext); + mockContext.db = mockDB; + + await dynamoDBWrapper(mockFunc)(mockRequest, mockContext); + + assert.strictEqual(mockContext.db, mockDB, 'context.db was re-initialized.'); + }); +}); diff --git a/test/db.test.js b/test/db.test.js new file mode 100644 index 00000000..5ae74a2b --- /dev/null +++ b/test/db.test.js @@ -0,0 +1,93 @@ +/* + * 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 nock from 'nock'; +import assert from 'assert'; +import esmock from 'esmock'; +import DB from '../src/db.js'; +import DBDocClientMock from './dynamo-db-doc-client-mock.js'; + +describe('DB Tests', () => { + const region = 'test-region'; + + let mockContext; + let logInfo = ''; + let logError = ''; + let testSite = { domain: 'www.testdomain.com', path: '/testpath' }; + + beforeEach(() => { + mockContext = { + runtime: { region }, + log: { + info: (message) => { + logInfo = message; + }, + error: (message) => { + logError = message; + }, + }, + }; + }); + + afterEach(() => { + nock.cleanAll(); + }); + + it('should initialize with provided context', () => { + const db = new DB(mockContext); + assert.strictEqual(db.log, mockContext.log); + }); + + it('should save the record to dynamodb and log success', async () => { + const DBDocMock = await esmock('../src/db.js', { + '@aws-sdk/lib-dynamodb': { + DynamoDBDocumentClient: DBDocClientMock, + }, + }); + const db = new DBDocMock(mockContext); + await db.saveAuditIndex(testSite, { + result: { + mobile: { + categories: { + performance: { score: 0.90 }, + seo: { score: 0.90 }, + 'best-practices': { score: 0.90 }, + accessibility: { score: 0.90 }, + }, + }, + desktop: { + categories: { + performance: { score: 0.90 }, + seo: { score: 0.90 }, + 'best-practices': { score: 0.90 }, + accessibility: { score: 0.90 }, + }, + }, + }, + }); + assert.strictEqual(logInfo, 'Audit for domain www.testdomain.com saved successfully'); + }); + + it('should get the site from dynamodb', async () => { + const DBDocMock = await esmock('../src/db.js', { + '@aws-sdk/lib-dynamodb': { + DynamoDBDocumentClient: DBDocClientMock, + }, + }); + const db = new DBDocMock(mockContext); + const site = await db.getSite(testSite.domain, testSite.path); + assert.strictEqual(logInfo, `Item retrieved successfully: ${testSite}`); + assert.deepStrictEqual(site, testSite); + }); +}); diff --git a/test/dynamo-db-doc-client-mock.js b/test/dynamo-db-doc-client-mock.js new file mode 100644 index 00000000..79f6440c --- /dev/null +++ b/test/dynamo-db-doc-client-mock.js @@ -0,0 +1,37 @@ +/* + * 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 { GetCommand, PutCommand } from '@aws-sdk/lib-dynamodb'; + +export default class DBDocClientMock { + constructor(config) { + this.config = config; + } + + static from() { + return new DBDocClientMock(); + } + + send(command) { + if (command instanceof PutCommand) { + return Promise.resolve({ }); + } else if (command instanceof GetCommand) { + return Promise.resolve({ + Item: { + domain: 'www.testdomain.com', + path: '/testpath', + }, + }); + } else { + return Promise.reject(new Error('Unknown command in mock')); + } + } +}