From fe7dd09d7eced6366c928112c522660ea431b8af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jovan=20Kruni=C4=87?= Date: Fri, 23 Oct 2020 10:31:25 +0200 Subject: [PATCH] refactor: parameterize configureApp function (inject db list) Reason: easier testing (mocking) and better readability Note: did additional refactoring --- src/app.ts | 12 +----- src/cli.ts | 3 +- test/common.ts | 54 ++++++++++++++++++++++---- test/routes/bulk-route.spec.ts | 23 +++-------- test/routes/thing-update-route.spec.ts | 4 +- 5 files changed, 58 insertions(+), 38 deletions(-) diff --git a/src/app.ts b/src/app.ts index 164b117d..6f10a07e 100644 --- a/src/app.ts +++ b/src/app.ts @@ -38,12 +38,11 @@ import {thingUpdateRouter} from './routes/thing-update-route'; import {virtualPluginRoute} from './routes/virtual-plugin-route'; import {BulkStorage} from './storage/bulk-storage'; import {DatabaseConstructor} from './storage/database'; -import {Elasticsearch} from './storage/elasticsearch/elasticsearch'; /** * Configure the backend */ -export async function configureApp(app: Express) { +export async function configureApp(app: Express, databases: {[name: string]: DatabaseConstructor; }) { let integrationTestTimeout: NodeJS.Timeout; // request loggers have to be the first middleware to be set in express app.use(morgan('dev', { @@ -59,11 +58,8 @@ export async function configureApp(app: Express) { } // tslint:disable-next-line: no-magic-numbers - if (res.statusCode < 400) { - return true; - } + return res.statusCode < 400; - return false; }, stream: process.stdout, })); @@ -142,10 +138,6 @@ export async function configureApp(app: Express) { .on('end', endCallback); }); - const databases: {[name: string]: DatabaseConstructor; } = { - elasticsearch: Elasticsearch, - }; - // validate config file await validator.addSchemas(join('node_modules', '@openstapps', 'core', 'lib', 'schema')); diff --git a/src/cli.ts b/src/cli.ts index 629b82c6..9b432184 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -17,6 +17,7 @@ import {Logger} from '@openstapps/logger'; import express from 'express'; import http from 'http'; import {configureApp} from './app'; +import {Elasticsearch} from './storage/elasticsearch/elasticsearch'; const app = express(); @@ -95,7 +96,7 @@ function onListening() { Logger.ok(`Listening on ${bind}`); } -configureApp(app) +configureApp(app, {elasticsearch: Elasticsearch}) .then(() => { Logger.ok('Successfully configured express server'); // After app setup listen on provided port, on all network interfaces diff --git a/test/common.ts b/test/common.ts index edfa869f..23133030 100644 --- a/test/common.ts +++ b/test/common.ts @@ -13,14 +13,17 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -import {SCSearchQuery, SCSearchResponse, SCThings, SCUuid} from '@openstapps/core'; +import {SCConfigFile, SCSearchQuery, SCSearchResponse, SCThings, SCThingType, SCUuid} from '@openstapps/core'; import {Express} from 'express'; +import moment from 'moment'; import {configureApp} from '../src/app'; import express from 'express'; import http from 'http'; +import {configFile} from '../src/common'; +import {MailQueue} from '../src/notification/mail-queue'; import {Bulk, BulkStorage} from '../src/storage/bulk-storage'; -import {Database} from '../src/storage/database'; import getPort from 'get-port'; +import {Database} from '../src/storage/database'; /** * Adds routers and configures an (express) app @@ -29,7 +32,7 @@ import getPort from 'get-port'; export async function startApp(): Promise { const app = express(); - await configureApp(app); + await configureApp(app, {elasticsearch: ElasticsearchMock}); const server = http.createServer(app); @@ -42,9 +45,9 @@ export async function startApp(): Promise { }); return new Promise(resolve => server.on('listening', () => { - app.set( - 'bulk', - bulkStorage, + app.set( + 'bulk', + bulkStorageMock, ); resolve(app); })); @@ -58,7 +61,7 @@ export class ElasticsearchMock implements Database { private bulk: Bulk | undefined; private storageMock = new Map(); - constructor() { + constructor(_configFile: SCConfigFile, _mailQueue?: MailQueue) { // Nothing to do here } @@ -98,9 +101,44 @@ export class ElasticsearchMock implements Database { } } -export const bulkStorage = new BulkStorage(new ElasticsearchMock()); +export const bulkStorageMock = new BulkStorage(new ElasticsearchMock(configFile)); + +export const bulk: Bulk = { + expiration: moment().add(3600, 'seconds') + .format(), + source: 'some_source', + state: 'in progress', + type: SCThingType.Book, + uid: '' + }; export class FooError extends Error { } export const DEFAULT_TEST_TIMEOUT = 10000; + +export const TRANSPORT_SEND_RESPONSE = 'Send Response'; + +export const getTransport = (verified: boolean) => { + return { + cc: undefined, + from: undefined, + recipients: undefined, + transportAgent: undefined, + verified: undefined, + isVerified(): boolean { + return verified; + }, + send(_subject: string, _message: string): Promise { + return Promise.resolve(''); + }, + sendMail(_mail: any): Promise { + return Promise.resolve(TRANSPORT_SEND_RESPONSE); + }, + verify(): Promise { + return Promise.resolve(false); + } + } + } + +export const index = 'stapps_footype_foosource_foobar'; diff --git a/test/routes/bulk-route.spec.ts b/test/routes/bulk-route.spec.ts index 4501ca12..f739511c 100644 --- a/test/routes/bulk-route.spec.ts +++ b/test/routes/bulk-route.spec.ts @@ -19,32 +19,21 @@ import { SCBulkRequest, SCBulkRoute, SCNotFoundErrorResponse, - SCThingType } from '@openstapps/core'; -import {Bulk} from '../../src/storage/bulk-storage'; import {expect} from 'chai'; import {instance as book} from '@openstapps/core/test/resources/Book.1.json'; -import moment from 'moment'; -import {DEFAULT_TEST_TIMEOUT} from '../common'; +import {bulk, DEFAULT_TEST_TIMEOUT} from '../common'; import {testApp} from '../tests-setup'; describe('Bulk routes', async function () { // increase timeout for the suite this.timeout(DEFAULT_TEST_TIMEOUT); - const bulkObj: Bulk = { - expiration: moment().add(3600, 'seconds') - .format(), - source: 'some_source', - state: 'in progress', - type: SCThingType.Book, - uid: '' - }; const request: SCBulkRequest = { - expiration: bulkObj.expiration, - source: bulkObj.source, - type: bulkObj.type, - }; + expiration: bulk.expiration, + source: bulk.source, + type: bulk.type, + }; const bulkRoute = new SCBulkRoute(); const bulkAddRoute = new SCBulkAddRoute(); const bulkDoneRoute = new SCBulkDoneRoute(); @@ -62,7 +51,7 @@ describe('Bulk routes', async function () { expect(status).to.be.equal(bulkRoute.statusCodeSuccess); expect(error).to.be.equal(false); expect(body.uid).to.be.a('string'); - expect(body).to.deep.equal({...bulkObj, uid: body.uid}); + expect(body).to.deep.equal({...bulk, uid: body.uid}); }); it('should return (throw) error if a bulk with the provided UID cannot be found when adding to a bulk', async function () { diff --git a/test/routes/thing-update-route.spec.ts b/test/routes/thing-update-route.spec.ts index 110eb726..646f9160 100644 --- a/test/routes/thing-update-route.spec.ts +++ b/test/routes/thing-update-route.spec.ts @@ -15,7 +15,7 @@ */ import {SCThingUpdateRoute} from '@openstapps/core'; import chaiAsPromised from 'chai-as-promised'; -import {bulkStorage, DEFAULT_TEST_TIMEOUT} from '../common'; +import {bulkStorageMock, DEFAULT_TEST_TIMEOUT} from '../common'; import {expect, use} from 'chai'; import {instance as book} from '@openstapps/core/test/resources/Book.1.json'; import {testApp} from '../tests-setup'; @@ -38,6 +38,6 @@ describe('Thing update route', async function () { .send(book); expect(status).to.equal(thingUpdateRoute.statusCodeSuccess); - expect(bulkStorage.database.get(book.uid)).to.eventually.be.deep.equal(book); + expect(bulkStorageMock.database.get(book.uid)).to.eventually.be.deep.equal(book); }); });