mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-04 04:22:50 +00:00
210 lines
8.2 KiB
TypeScript
210 lines
8.2 KiB
TypeScript
/*
|
|
* Copyright (C) 2019 StApps
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as
|
|
* published by the Free Software Foundation, either version 3 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* 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 {
|
|
SCNotFoundErrorResponse,
|
|
SCPluginAdd,
|
|
SCPluginAlreadyRegisteredErrorResponse,
|
|
SCPluginRegisterResponse,
|
|
SCPluginRegisterRoute,
|
|
SCPluginRemove,
|
|
SCValidationErrorResponse,
|
|
} from '@openstapps/core';
|
|
import nock from 'nock';
|
|
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 {DEFAULT_TEST_TIMEOUT} from '../common.js';
|
|
import {testApp} from '../tests-setup.js';
|
|
import {backendConfig} from '../../src/config.js';
|
|
import registerRequest from '@openstapps/core/test/resources/PluginRegisterRequest.1.json' assert {type: 'json'};
|
|
|
|
// for using promises in expectations (to.eventually.be...)
|
|
use(chaiAsPromised);
|
|
|
|
// cast it because of "TS2322: Type 'string' is not assignable to type '"add"'"
|
|
export const registerAddRequest: SCPluginAdd = registerRequest.instance as SCPluginAdd;
|
|
|
|
export const registerRemoveRequest: SCPluginRemove = {
|
|
action: 'remove',
|
|
route: registerAddRequest.plugin.route,
|
|
};
|
|
|
|
describe('Plugin registration', async function () {
|
|
const bodySuccess: SCPluginRegisterResponse = {success: true};
|
|
describe('Middleware', async function () {
|
|
after(function () {
|
|
// remove plugins
|
|
plugins.clear();
|
|
backendConfig.app.features = {};
|
|
});
|
|
|
|
it('should register a plugin', async function () {
|
|
// register one plugin
|
|
const response = await pluginRegisterHandler(registerAddRequest, {});
|
|
|
|
expect(response).to.deep.equal(bodySuccess) &&
|
|
expect(plugins.size).to.equal(1) &&
|
|
expect(backendConfig.app.features.plugins!['Foo Plugin']).to.not.be.empty;
|
|
});
|
|
|
|
it('should allow re-registering the same plugin', async function () {
|
|
// register one plugin
|
|
await pluginRegisterHandler(registerAddRequest, {});
|
|
|
|
// register the same plugin again
|
|
const response = await pluginRegisterHandler(registerAddRequest, {});
|
|
|
|
return (
|
|
expect(response).to.deep.equal(bodySuccess) &&
|
|
expect(plugins.size).to.equal(1) &&
|
|
expect(backendConfig.app.features.plugins!['Foo Plugin']).to.not.be.empty
|
|
);
|
|
});
|
|
|
|
it('should show an error if a plugin has already been registered', async function () {
|
|
// register one plugin
|
|
await pluginRegisterHandler(registerAddRequest, {});
|
|
|
|
// create new request for adding a plugin with only name that changed
|
|
const registerAddRequestAltered: SCPluginAdd = {
|
|
...registerAddRequest,
|
|
plugin: {...registerAddRequest.plugin, name: registerAddRequest.plugin.name + 'foo'},
|
|
};
|
|
|
|
// register the same plugin again
|
|
expect(pluginRegisterHandler(registerAddRequestAltered, {}))
|
|
.to.eventually.be.rejectedWith('Plugin already registered')
|
|
.and.be.an.instanceOf(SCPluginAlreadyRegisteredErrorResponse)
|
|
// check that the right plugin information (of the previously registered plugin) is provided with the error
|
|
.and.have.property('additionalData', registerAddRequest.plugin);
|
|
});
|
|
|
|
it('should remove plugin if it exists', async function () {
|
|
// register one plugin
|
|
await pluginRegisterHandler(registerAddRequest, {});
|
|
|
|
expect(plugins.size).to.equal(1);
|
|
|
|
const response = await pluginRegisterHandler(registerRemoveRequest, {});
|
|
|
|
expect(response).to.deep.equal(bodySuccess) &&
|
|
expect(plugins.size).to.equal(0) &&
|
|
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 () {
|
|
// register one plugin
|
|
await pluginRegisterHandler(registerAddRequest, {});
|
|
|
|
expect(pluginRegisterHandler({...registerRemoveRequest, route: '/not-foo'}, {}))
|
|
.to.eventually.be.rejectedWith('Resource not found')
|
|
.and.be.an.instanceOf(SCNotFoundErrorResponse);
|
|
});
|
|
});
|
|
|
|
describe('Routes', async function () {
|
|
// increase timeout for the suite
|
|
this.timeout(DEFAULT_TEST_TIMEOUT);
|
|
const pluginRegisterRoute = new SCPluginRegisterRoute();
|
|
const validationError = new SCValidationErrorResponse([]);
|
|
const notFoundError = new SCNotFoundErrorResponse();
|
|
// @ts-expect-error not assignable
|
|
const alreadyRegisteredError = new SCPluginAlreadyRegisteredErrorResponse('Foo Message', {});
|
|
|
|
afterEach(async function () {
|
|
// remove routes
|
|
plugins.clear();
|
|
// clean up request mocks (fixes issue with receiving response from mock from previous test case)
|
|
nock.cleanAll();
|
|
});
|
|
|
|
it('should provide "not found" (404) if plugin/route is not registered', async function () {
|
|
// lets simulate that the plugin is already registered
|
|
plugins.set(registerAddRequest.plugin.route, registerAddRequest.plugin);
|
|
// mock response of the plugin address
|
|
nock('http://foo.com:1234')
|
|
.post('/foo')
|
|
.reply(200, {result: [{foo: 'bar'}, {bar: 'foo'}]});
|
|
|
|
const {status} = await testApp
|
|
.post('/not-foo')
|
|
.set('Content-Type', 'application/json')
|
|
.set('Accept', 'application/json')
|
|
.send({query: 'foo'});
|
|
|
|
expect(status).to.be.equal(notFoundError.statusCode);
|
|
});
|
|
|
|
it('should respond with bad request if when providing invalid request', async function () {
|
|
const {status} = await testApp
|
|
.post(pluginRegisterRoute.urlPath)
|
|
.set('Content-Type', 'application/json')
|
|
.set('Accept', 'application/json')
|
|
.send({foo: 'bar'});
|
|
|
|
expect(status).to.be.equal(validationError.statusCode);
|
|
});
|
|
|
|
it('should respond with an error if something went wrong with a valid request', async function () {
|
|
// lets simulate that a plugin is already registered
|
|
plugins.set(registerAddRequest.plugin.route, registerAddRequest.plugin);
|
|
// registering a different plugin for the same route causes the expected error
|
|
const registerAddRequestAltered = {
|
|
...registerAddRequest,
|
|
plugin: {...registerAddRequest.plugin, name: 'FooBar Plugin'},
|
|
};
|
|
|
|
const {status, body} = await testApp
|
|
.post(pluginRegisterRoute.urlPath)
|
|
.set('Content-Type', 'application/json')
|
|
.set('Accept', 'application/json')
|
|
.send(registerAddRequestAltered);
|
|
|
|
expect(status).to.be.equal(alreadyRegisteredError.statusCode);
|
|
expect(body).to.haveOwnProperty('name', 'SCPluginAlreadyRegisteredError');
|
|
});
|
|
|
|
it('should respond with success when de-registering already registered plugin', async function () {
|
|
// lets simulate that a plugin is already registered
|
|
plugins.set(registerAddRequest.plugin.route, registerAddRequest.plugin);
|
|
|
|
const {status, body} = await testApp
|
|
.post('/plugin/register')
|
|
.set('Content-Type', 'application/json')
|
|
.set('Accept', 'application/json')
|
|
.send(registerRemoveRequest);
|
|
|
|
expect(status).to.be.equal(new SCPluginRegisterRoute().statusCodeSuccess);
|
|
expect(body).to.be.deep.equal(bodySuccess);
|
|
});
|
|
|
|
it('should response with 404 when deleting a plugin which was not registered', async function () {
|
|
// lets simulate that the plugin is already registered
|
|
plugins.set(registerAddRequest.plugin.route, registerAddRequest.plugin);
|
|
|
|
const {status} = await testApp
|
|
.post('/plugin/register')
|
|
.set('Content-Type', 'application/json')
|
|
.set('Accept', 'application/json')
|
|
// using a different route for the remove request
|
|
.send({action: 'remove', route: '/not-foo'} as SCPluginRemove);
|
|
|
|
expect(status).to.be.equal(notFoundError.statusCode);
|
|
});
|
|
});
|
|
});
|