mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-04-23 06:39:13 +00:00
feat: migrate backend to cosmiconfig
This commit is contained in:
@@ -20,11 +20,12 @@ import {
|
||||
SCUnsupportedMediaTypeErrorResponse,
|
||||
} from '@openstapps/core';
|
||||
import {expect} from 'chai';
|
||||
import {configFile, DEFAULT_TIMEOUT} from '../src/common.js';
|
||||
import {DEFAULT_TIMEOUT} from '../src/common.js';
|
||||
import {DEFAULT_TEST_TIMEOUT} from './common.js';
|
||||
import {testApp} from './tests-setup.js';
|
||||
import sinon from 'sinon';
|
||||
import mockedEnv from 'mocked-env';
|
||||
import {backendConfig} from '../src/config.js';
|
||||
|
||||
describe('App', async function () {
|
||||
// increase timeout for the suite
|
||||
@@ -39,6 +40,7 @@ describe('App', async function () {
|
||||
const clock = sandbox.useFakeTimers();
|
||||
const processExitStub = sandbox.stub(process, 'exit');
|
||||
// fake NODE_ENV as integration test
|
||||
// @ts-expect-error type definitions are not working for some reason
|
||||
const restore = mockedEnv({
|
||||
NODE_ENV: 'integration-test',
|
||||
});
|
||||
@@ -55,7 +57,7 @@ describe('App', async function () {
|
||||
});
|
||||
|
||||
it('should provide request body too large error in case of a body larger than the max size', async function () {
|
||||
sandbox.stub(configFile.backend, 'maxRequestBodySize').value('3');
|
||||
sandbox.stub(backendConfig.backend, 'maxRequestBodySize').value('3');
|
||||
|
||||
const {status} = await testApp
|
||||
.post('/')
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {yearSlice} from '../config/default.js';
|
||||
import {expect} from 'chai';
|
||||
import {yearSlice} from '../config/default/tools/semester-acronym.js';
|
||||
|
||||
describe('Common', function () {
|
||||
describe('yearSlice', function () {
|
||||
|
||||
@@ -20,12 +20,12 @@ import {getIndexUID} from '../src/storage/elasticsearch/util.js';
|
||||
import {configureApp} from '../src/app.js';
|
||||
import express from 'express';
|
||||
import http from 'http';
|
||||
import {configFile} from '../src/common.js';
|
||||
import {MailQueue} from '../src/notification/mail-queue.js';
|
||||
import {Bulk, BulkStorage} from '../src/storage/bulk-storage.js';
|
||||
import getPort from 'get-port';
|
||||
import {Database} from '../src/storage/database.js';
|
||||
import {v4} from 'uuid';
|
||||
import {backendConfig} from '../src/config.js';
|
||||
|
||||
/**
|
||||
* Adds routers and configures an (express) app
|
||||
@@ -108,7 +108,7 @@ export class ElasticsearchMock implements Database {
|
||||
}
|
||||
}
|
||||
|
||||
export const bulkStorageMock = new BulkStorage(new ElasticsearchMock(configFile));
|
||||
export const bulkStorageMock = new BulkStorage(new ElasticsearchMock(backendConfig));
|
||||
|
||||
export const bulk: Bulk = {
|
||||
expiration: moment().add(3600, 'seconds').format(),
|
||||
|
||||
@@ -13,8 +13,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {SMTP} from '@openstapps/logger/lib/smtp';
|
||||
import {Transport} from '@openstapps/logger/lib/transport';
|
||||
import {SMTP, Transport} from '@openstapps/logger';
|
||||
import {expect} from 'chai';
|
||||
import mockedEnv from 'mocked-env';
|
||||
import {BackendTransport, isTransportWithVerification} from '../../src/notification/backend-transport.js';
|
||||
@@ -54,6 +53,7 @@ describe('Backend transport', function () {
|
||||
|
||||
it('should not throw in case of error getting SMTP instance when transport not allowed', function () {
|
||||
sandbox.stub(SMTP, 'getInstance').throws('Foo Error');
|
||||
// @ts-expect-error wrong type defs for some reason
|
||||
const restore = mockedEnv({
|
||||
ALLOW_NO_TRANSPORT: 'true',
|
||||
});
|
||||
@@ -66,6 +66,7 @@ describe('Backend transport', function () {
|
||||
|
||||
it('should throw in case of error getting SMTP instance when transport is allowed', function () {
|
||||
sandbox.stub(SMTP, 'getInstance').throws('Foo Error');
|
||||
// @ts-expect-error wrong type defs for some reason
|
||||
const restore = mockedEnv({
|
||||
ALLOW_NO_TRANSPORT: undefined,
|
||||
});
|
||||
|
||||
@@ -21,9 +21,13 @@ import {
|
||||
SCNotFoundErrorResponse,
|
||||
} from '@openstapps/core';
|
||||
import {expect} from 'chai';
|
||||
import {instance as book} from '@openstapps/core/test/resources/indexable/Book.1.json';
|
||||
import {bulk, DEFAULT_TEST_TIMEOUT} from '../common.js';
|
||||
import {testApp} from '../tests-setup.js';
|
||||
import {readFile} from 'fs/promises';
|
||||
|
||||
const book = JSON.parse(
|
||||
await readFile('node_modules/@openstapps/core/test/resources/indexable/Book.1.json', 'utf8'),
|
||||
);
|
||||
|
||||
describe('Bulk routes', async function () {
|
||||
// increase timeout for the suite
|
||||
|
||||
@@ -23,19 +23,24 @@ import {
|
||||
SCValidationErrorResponse,
|
||||
} from '@openstapps/core';
|
||||
import nock from 'nock';
|
||||
import {configFile, plugins} from '../../src/common.js';
|
||||
import {plugins} from '../../src/common.js';
|
||||
import {pluginRegisterHandler} from '../../src/routes/plugin-register-route.js';
|
||||
import {expect, use} from 'chai';
|
||||
import chaiAsPromised from 'chai-as-promised';
|
||||
import {instance as registerRequest} from '@openstapps/core/test/resources/PluginRegisterRequest.1.json';
|
||||
import {DEFAULT_TEST_TIMEOUT} from '../common.js';
|
||||
import {testApp} from '../tests-setup.js';
|
||||
import {backendConfig} from '../../src/config.js';
|
||||
import {readFile} from 'fs/promises';
|
||||
|
||||
// for using promises in expectations (to.eventually.be...)
|
||||
use(chaiAsPromised);
|
||||
|
||||
const registerRequest = JSON.parse(
|
||||
await readFile('node_modules/@openstapps/core/test/resources/PluginRegisterRequest.1.json', 'utf8'),
|
||||
);
|
||||
|
||||
// cast it because of "TS2322: Type 'string' is not assignable to type '"add"'"
|
||||
export const registerAddRequest: SCPluginAdd = registerRequest as SCPluginAdd;
|
||||
export const registerAddRequest: SCPluginAdd = registerRequest.instance as SCPluginAdd;
|
||||
|
||||
export const registerRemoveRequest: SCPluginRemove = {
|
||||
action: 'remove',
|
||||
@@ -48,7 +53,7 @@ describe('Plugin registration', async function () {
|
||||
after(function () {
|
||||
// remove plugins
|
||||
plugins.clear();
|
||||
configFile.app.features = {};
|
||||
backendConfig.app.features = {};
|
||||
});
|
||||
|
||||
it('should register a plugin', async function () {
|
||||
@@ -57,7 +62,7 @@ describe('Plugin registration', async function () {
|
||||
|
||||
expect(response).to.deep.equal(bodySuccess) &&
|
||||
expect(plugins.size).to.equal(1) &&
|
||||
expect(configFile.app.features.plugins!['Foo Plugin']).to.not.be.empty;
|
||||
expect(backendConfig.app.features.plugins!['Foo Plugin']).to.not.be.empty;
|
||||
});
|
||||
|
||||
it('should allow re-registering the same plugin', async function () {
|
||||
@@ -70,7 +75,7 @@ describe('Plugin registration', async function () {
|
||||
return (
|
||||
expect(response).to.deep.equal(bodySuccess) &&
|
||||
expect(plugins.size).to.equal(1) &&
|
||||
expect(configFile.app.features.plugins!['Foo Plugin']).to.not.be.empty
|
||||
expect(backendConfig.app.features.plugins!['Foo Plugin']).to.not.be.empty
|
||||
);
|
||||
});
|
||||
|
||||
@@ -102,7 +107,7 @@ describe('Plugin registration', async function () {
|
||||
|
||||
expect(response).to.deep.equal(bodySuccess) &&
|
||||
expect(plugins.size).to.equal(0) &&
|
||||
expect(configFile.app.features.plugins).to.be.empty;
|
||||
expect(backendConfig.app.features.plugins).to.be.empty;
|
||||
});
|
||||
|
||||
it('should throw a "not found" error when removing a plugin whose registered route does not exist', async function () {
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
SCRouteHttpVerbs,
|
||||
SCValidationErrorResponse,
|
||||
} from '@openstapps/core';
|
||||
import * as bodyParser from 'body-parser';
|
||||
import bodyParser from 'body-parser';
|
||||
import sinon from 'sinon';
|
||||
import {expect} from 'chai';
|
||||
import {Application} from 'express';
|
||||
|
||||
@@ -21,10 +21,10 @@ import {
|
||||
SCTooManyRequestsErrorResponse,
|
||||
} from '@openstapps/core';
|
||||
import {expect} from 'chai';
|
||||
import {configFile} from '../../src/common.js';
|
||||
import {DEFAULT_TEST_TIMEOUT} from '../common.js';
|
||||
import {testApp} from '../tests-setup.js';
|
||||
import sinon from 'sinon';
|
||||
import {backendConfig} from '../../src/config.js';
|
||||
|
||||
describe('Search route', async function () {
|
||||
// increase timeout for the suite
|
||||
@@ -96,7 +96,7 @@ describe('Search route', async function () {
|
||||
|
||||
it('should respond with too many requests error if the number of sub-queries exceed their max number', async function () {
|
||||
const sandbox = sinon.createSandbox();
|
||||
sandbox.stub(configFile.backend, 'maxMultiSearchRouteQueries').value(2);
|
||||
sandbox.stub(backendConfig.backend, 'maxMultiSearchRouteQueries').value(2);
|
||||
|
||||
const {status} = await testApp
|
||||
.post(multiSearchRoute.urlPath)
|
||||
|
||||
@@ -17,11 +17,15 @@ import {SCThingUpdateRoute} from '@openstapps/core';
|
||||
import chaiAsPromised from 'chai-as-promised';
|
||||
import {bulkStorageMock, DEFAULT_TEST_TIMEOUT} from '../common.js';
|
||||
import {expect, use} from 'chai';
|
||||
import {instance as book} from '@openstapps/core/test/resources/indexable/Book.1.json';
|
||||
import {testApp} from '../tests-setup.js';
|
||||
import {readFile} from 'fs/promises';
|
||||
|
||||
use(chaiAsPromised);
|
||||
|
||||
const book = JSON.parse(
|
||||
await readFile('node_modules/@openstapps/core/test/resources/indexable/Book.1.json', 'utf8'),
|
||||
);
|
||||
|
||||
describe('Thing update route', async function () {
|
||||
// increase timeout for the suite
|
||||
this.timeout(DEFAULT_TEST_TIMEOUT);
|
||||
|
||||
@@ -25,7 +25,7 @@ import {mockReq} from 'sinon-express-mock';
|
||||
import {plugins, validator} from '../../src/common.js';
|
||||
import {virtualPluginRoute} from '../../src/routes/virtual-plugin-route.js';
|
||||
import {DEFAULT_TEST_TIMEOUT, FooError} from '../common.js';
|
||||
import {registerAddRequest} from './plugin-register-route.spec';
|
||||
import {registerAddRequest} from './plugin-register-route.spec.js';
|
||||
import {testApp} from '../tests-setup.js';
|
||||
|
||||
use(chaiAsPromised);
|
||||
@@ -154,12 +154,12 @@ describe('Virtual plugin routes', async function () {
|
||||
plugins.clear();
|
||||
// // restore everything to default methods (remove stubs)
|
||||
sandbox.restore();
|
||||
// clean up request mocks (fixes issue with receiving response from mock from previous test case)
|
||||
// cleanup request mocks (fixes issue with receiving response from mock from previous test case)
|
||||
nock.cleanAll();
|
||||
});
|
||||
|
||||
it('should properly provide the response of a plugin', async function () {
|
||||
// lets simulate that the plugin is already registered
|
||||
// let's simulate that the plugin is already registered
|
||||
plugins.set(registerAddRequest.plugin.route, registerAddRequest.plugin);
|
||||
// mock responses of the plugin, depending on the body sent
|
||||
nock('http://foo.com:1234')
|
||||
@@ -174,20 +174,20 @@ describe('Virtual plugin routes', async function () {
|
||||
.set('Content-Type', 'application/json')
|
||||
.set('Accept', 'application/json')
|
||||
.send({query: 'foo'});
|
||||
expect(fooResponse.status).to.be.equal(OK);
|
||||
expect(fooResponse.body).to.be.deep.equal({result: [{foo: 'foo'}, {bar: 'foo'}]});
|
||||
|
||||
const barResponse = await testApp
|
||||
.post('/foo')
|
||||
.set('Content-Type', 'application/json')
|
||||
.set('Accept', 'application/json')
|
||||
.send({query: 'bar'});
|
||||
|
||||
expect(fooResponse.status).to.be.equal(OK);
|
||||
expect(fooResponse.body).to.be.deep.equal({result: [{foo: 'foo'}, {bar: 'foo'}]});
|
||||
expect(barResponse.status).to.be.equal(OK);
|
||||
expect(barResponse.body).to.be.deep.equal({result: [{foo: 'bar'}, {bar: 'bar'}]});
|
||||
});
|
||||
|
||||
it('should return error response if plugin address is not responding', async function () {
|
||||
// lets simulate that the plugin is already registered
|
||||
// let's simulate that the plugin is already registered
|
||||
plugins.set(registerAddRequest.plugin.route, registerAddRequest.plugin);
|
||||
|
||||
class FooError extends Error {}
|
||||
|
||||
@@ -17,12 +17,12 @@ import {SCBulkRequest, SCThingType} from '@openstapps/core';
|
||||
import moment from 'moment';
|
||||
// eslint-disable-next-line unicorn/import-style
|
||||
import util from 'util';
|
||||
import {configFile} from '../../src/common.js';
|
||||
import {Bulk, BulkStorage} from '../../src/storage/bulk-storage.js';
|
||||
import {expect} from 'chai';
|
||||
import {ElasticsearchMock} from '../common.js';
|
||||
import sinon from 'sinon';
|
||||
import NodeCache from 'node-cache';
|
||||
import {backendConfig} from '../../src/config.js';
|
||||
|
||||
describe('Bulk Storage', function () {
|
||||
describe('Bulk', function () {
|
||||
@@ -58,7 +58,7 @@ describe('Bulk Storage', function () {
|
||||
let database: ElasticsearchMock;
|
||||
|
||||
beforeEach(function () {
|
||||
database = new ElasticsearchMock(configFile);
|
||||
database = new ElasticsearchMock(backendConfig);
|
||||
esMock = sandbox.stub(database, 'bulkExpired');
|
||||
});
|
||||
|
||||
|
||||
@@ -31,10 +31,7 @@ import {
|
||||
SCThings,
|
||||
SCThingType,
|
||||
} from '@openstapps/core';
|
||||
import {instance as book} from '@openstapps/core/test/resources/indexable/Book.1.json';
|
||||
import {instance as message} from '@openstapps/core/test/resources/indexable/Message.1.json';
|
||||
import {Logger} from '@openstapps/logger';
|
||||
import {SMTP} from '@openstapps/logger/lib/smtp';
|
||||
import {Logger, SMTP} from '@openstapps/logger';
|
||||
import {expect, use} from 'chai';
|
||||
import chaiAsPromised from 'chai-as-promised';
|
||||
import {beforeEach} from 'mocha';
|
||||
@@ -58,6 +55,8 @@ import * as Monitoring from '../../../src/storage/elasticsearch/monitoring.js';
|
||||
import * as templating from '../../../src/storage/elasticsearch/templating.js';
|
||||
import {bulk, DEFAULT_TEST_TIMEOUT, getTransport, getIndex} from '../../common.js';
|
||||
import fs from 'fs';
|
||||
import {backendConfig} from '../../../src/config.js';
|
||||
import {readFile} from 'fs/promises';
|
||||
|
||||
use(chaiAsPromised);
|
||||
|
||||
@@ -68,6 +67,13 @@ function searchResponse<T>(...hits: SearchHit<T>[]): SearchResponse<T> {
|
||||
return {hits: {hits}, took: 0, timed_out: false, _shards: {total: 1, failed: 0, successful: 1}};
|
||||
}
|
||||
|
||||
const message = JSON.parse(
|
||||
await readFile('node_modules/@openstapps/core/test/resources/indexable/Message.1.json', 'utf8'),
|
||||
);
|
||||
const book = JSON.parse(
|
||||
await readFile('node_modules/@openstapps/core/test/resources/indexable/Book.1.json', 'utf8'),
|
||||
);
|
||||
|
||||
describe('Elasticsearch', function () {
|
||||
// increase timeout for the suite
|
||||
this.timeout(DEFAULT_TEST_TIMEOUT);
|
||||
@@ -85,6 +91,7 @@ describe('Elasticsearch', function () {
|
||||
describe('getElasticsearchUrl', function () {
|
||||
it('should provide custom elasticsearch URL if defined', function () {
|
||||
const customAddress = 'http://foo-address:9200';
|
||||
// @ts-expect-error wrong type defs for some reason
|
||||
const restore = mockedEnv({
|
||||
ES_ADDR: customAddress,
|
||||
});
|
||||
@@ -95,6 +102,7 @@ describe('Elasticsearch', function () {
|
||||
});
|
||||
|
||||
it('should provide local URL as fallback', function () {
|
||||
// @ts-expect-error wrong type defs for some reason
|
||||
const restore = mockedEnv({
|
||||
ES_ADDR: undefined,
|
||||
});
|
||||
@@ -193,16 +201,19 @@ describe('Elasticsearch', function () {
|
||||
});
|
||||
|
||||
it('should complain (throw an error) if database in config is undefined', function () {
|
||||
const config: SCConfigFile = {...configFile, internal: {...configFile.internal, database: undefined}};
|
||||
const config: SCConfigFile = {
|
||||
...backendConfig,
|
||||
internal: {...backendConfig.internal, database: undefined},
|
||||
};
|
||||
|
||||
expect(() => new Elasticsearch(config)).to.throw(Error);
|
||||
});
|
||||
|
||||
it('should complain (throw an error) if database version is not a string', function () {
|
||||
const config: SCConfigFile = {
|
||||
...configFile,
|
||||
...backendConfig,
|
||||
internal: {
|
||||
...configFile.internal,
|
||||
...backendConfig.internal,
|
||||
database: {
|
||||
name: 'foo',
|
||||
version: 123,
|
||||
@@ -218,7 +229,7 @@ describe('Elasticsearch', function () {
|
||||
const loggerErrorStub = sandbox.stub(Logger, 'error').resolves('foo');
|
||||
sandbox.stub(Diagnostic.prototype, 'on').yields(error);
|
||||
|
||||
new Elasticsearch(configFile);
|
||||
new Elasticsearch(backendConfig);
|
||||
|
||||
expect(loggerErrorStub.calledWith(error)).to.be.true;
|
||||
});
|
||||
@@ -228,13 +239,14 @@ describe('Elasticsearch', function () {
|
||||
const loggerLogStub = sandbox.stub(Logger, 'log');
|
||||
sandbox.stub(Diagnostic.prototype, 'on').yields(null, fakeResponse);
|
||||
|
||||
new Elasticsearch(configFile);
|
||||
new Elasticsearch(backendConfig);
|
||||
expect(loggerLogStub.calledWith(fakeResponse)).to.be.false;
|
||||
|
||||
// @ts-expect-error wrong type defs for some reason
|
||||
const restore = mockedEnv({
|
||||
ES_DEBUG: 'true',
|
||||
});
|
||||
new Elasticsearch(configFile);
|
||||
new Elasticsearch(backendConfig);
|
||||
|
||||
expect(loggerLogStub.calledWith(fakeResponse)).to.be.true;
|
||||
// restore env variables
|
||||
@@ -249,9 +261,9 @@ describe('Elasticsearch', function () {
|
||||
|
||||
it('should complain (throw an error) if monitoring is set but mail queue is undefined', async function () {
|
||||
const config: SCConfigFile = {
|
||||
...configFile,
|
||||
...backendConfig,
|
||||
internal: {
|
||||
...configFile.internal,
|
||||
...backendConfig.internal,
|
||||
monitoring: {
|
||||
actions: [],
|
||||
watchers: [],
|
||||
@@ -266,9 +278,9 @@ describe('Elasticsearch', function () {
|
||||
|
||||
it('should setup the monitoring if there is monitoring is set and mail queue is defined', function () {
|
||||
const config: SCConfigFile = {
|
||||
...configFile,
|
||||
...backendConfig,
|
||||
internal: {
|
||||
...configFile.internal,
|
||||
...backendConfig.internal,
|
||||
monitoring: {
|
||||
actions: [],
|
||||
watchers: [],
|
||||
@@ -420,7 +432,7 @@ describe('Elasticsearch', function () {
|
||||
const sandbox = sinon.createSandbox();
|
||||
|
||||
before(function () {
|
||||
es = new Elasticsearch(configFile);
|
||||
es = new Elasticsearch(backendConfig);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
@@ -451,7 +463,7 @@ describe('Elasticsearch', function () {
|
||||
const sandbox = sinon.createSandbox();
|
||||
|
||||
before(function () {
|
||||
es = new Elasticsearch(configFile);
|
||||
es = new Elasticsearch(backendConfig);
|
||||
});
|
||||
|
||||
beforeEach(function () {
|
||||
@@ -510,7 +522,7 @@ describe('Elasticsearch', function () {
|
||||
const sandbox = sinon.createSandbox();
|
||||
|
||||
before(function () {
|
||||
es = new Elasticsearch(configFile);
|
||||
es = new Elasticsearch(backendConfig);
|
||||
});
|
||||
afterEach(function () {
|
||||
sandbox.restore();
|
||||
|
||||
@@ -146,7 +146,7 @@ describe('Query', function () {
|
||||
tieBreaker: 0,
|
||||
};
|
||||
const config: SCConfigFile = {
|
||||
...configFile,
|
||||
...backendConfig,
|
||||
};
|
||||
beforeEach(function () {
|
||||
esConfig = {
|
||||
|
||||
Reference in New Issue
Block a user