UNPKG

linagora-rse

Version:
992 lines (918 loc) 32 kB
const expect = require('chai').expect; const request = require('supertest'); describe('The configurations API', function() { const TEST_MODULE = 'test'; const TEST_CONFIG = { name: 'test_config_key', value: 'test_config_value' }; let webserver, fixtures, helpers, core, userAlice; beforeEach(function(done) { helpers = this.helpers; this.mongoose = require('mongoose'); core = this.testEnv.initCore(() => { webserver = helpers.requireBackend('webserver').webserver; fixtures = helpers.requireFixture('models/users.js')(helpers.requireBackend('core/db/mongo/models/user')); fixtures.newDummyUser(['alice@email.com']) .save(helpers.callbacks.noErrorAnd(user => { userAlice = user; core['esn-config'](TEST_CONFIG.name) .inModule(TEST_MODULE) .forUser(userAlice) .store(TEST_CONFIG.value, done); })); }); }); afterEach(function(done) { this.mongoose.connection.db .dropDatabase(helpers.callbacks.noErrorAnd(() => this.mongoose.disconnect(done))); }); function sendRequestAsUser(user, next) { helpers.api.loginAsUser( webserver.application, user.emails[0], fixtures.password, helpers.callbacks.noErrorAnd(loggedInAsUser => next(loggedInAsUser)) ); } function registerTestConfig(role, rights = 'rw') { core['esn-config'].registry.register(TEST_MODULE, { configurations: { [TEST_CONFIG.name]: { rights: { [role]: rights } } } }); } describe('POST /api/configurations', function() { const API_ENDPOINT = '/api/configurations'; it('should send back 401 if the user is not logged in', function(done) { helpers.api.requireLogin(webserver.application, 'post', API_ENDPOINT, done); }); it('should send back 400 if scope query is missing', function(done) { sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser(request(webserver.application).post(API_ENDPOINT)) .expect(400) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 400, message: 'Bad Request', details: 'missing scope in query' } }); done(); })); }); }); it('should send back 400 if scope query is invalid', function(done) { sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser( request(webserver.application) .post(API_ENDPOINT) .query('scope=invalid') ) .expect(400) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 400, message: 'Bad Request', details: 'scope must be either platform, domain or user' } }); done(); })); }); }); it('should send back 400 if body is not an array', function(done) { sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser( request(webserver.application) .post(API_ENDPOINT) .query('scope=user') .send('not and array') ) .expect(400) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 400, message: 'Bad Request', details: 'body should be an array' } }); done(); })); }); }); it('should send back 400 if body array is not well-formed', function(done) { sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser( request(webserver.application) .post(API_ENDPOINT) .query('scope=user') .send([{}, { name: TEST_MODULE }]) ) .expect(400) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 400, message: 'Bad Request', details: 'body data is not well-formed: one of modules in array does not have name' } }); done(); })); }); }); describe('when scope is user', function() { it('should send back 400 if there are unreadable configs', function(done) { sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser( request(webserver.application) .post(API_ENDPOINT) .query('scope=user') .send([{ name: TEST_MODULE, keys: [TEST_CONFIG.name] }]) ) .expect(400) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 400, message: 'Bad Request', details: 'Configurations are not readable' } }); done(); })); }); }); it('should send back 200 with requested configs in body', function(done) { registerTestConfig('user', 'r'); sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser( request(webserver.application) .post(API_ENDPOINT) .query('scope=user') .send([{ name: TEST_MODULE, keys: [TEST_CONFIG.name] }]) ) .expect(200) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual([{ name: TEST_MODULE, configurations: [TEST_CONFIG] }]); done(); })); }); }); }); describe('when scope is domain', function() { let userDomainAdmin, userDomainMember, domain; beforeEach(function(done) { helpers.api.applyDomainDeployment('linagora_test_domain', function(err, models) { expect(err).to.not.exist; userDomainAdmin = models.users[0]; userDomainMember = models.users[1]; domain = models.domain; done(); }); }); it('should send back 400 if domain_id is missing', function(done) { sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser( request(webserver.application) .post(API_ENDPOINT) .query('scope=domain') .send([{ name: TEST_MODULE, keys: [TEST_CONFIG.name] }]) ) .expect(400) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 400, message: 'Bad Request', details: 'when scope is domain, domain_id is required' } }); done(); })); }); }); it('should send back 400 if the domain_id is not an ObjectId', function(done) { sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser( request(webserver.application) .post(API_ENDPOINT) .query('scope=domain') .query('domain_id=a_domain_id') .send([{ name: TEST_MODULE, keys: [TEST_CONFIG.name] }]) ) .expect(400) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 400, message: 'Bad Request', details: 'Invalid domain_id parameter' } }); done(); })); }); }); it('should send back 404 if no domain found to match with domain_id', function(done) { sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser( request(webserver.application) .post(API_ENDPOINT) .query('scope=domain') .query('domain_id=58e522df9ea18136135c02a7') .send([{ name: TEST_MODULE, keys: [TEST_CONFIG.name] }]) ) .expect(404) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 404, message: 'Not found', details: 'The domain 58e522df9ea18136135c02a7 could not be found' } }); done(); })); }); }); it('should send back 403 if current user is not the domain admin', function(done) { sendRequestAsUser(userDomainMember, loggedInAsUser => { loggedInAsUser( request(webserver.application) .post(API_ENDPOINT) .query('scope=domain') .query(`domain_id=${domain.id}`) .send([{ name: TEST_MODULE, keys: [TEST_CONFIG.name] }]) ) .expect(403) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 403, message: 'Forbidden', details: 'User is not the domain manager' } }); done(); })); }); }); it('should send back 400 if there are unreadable configs', function(done) { sendRequestAsUser(userDomainAdmin, loggedInAsUser => { loggedInAsUser( request(webserver.application) .post(API_ENDPOINT) .query('scope=user') .query(`domain_id=${domain.id}`) .send([{ name: TEST_MODULE, keys: [TEST_CONFIG.name] }]) ) .expect(400) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 400, message: 'Bad Request', details: 'Configurations are not readable' } }); done(); })); }); }); it('should send back 200 with requested configs in body', function(done) { registerTestConfig('admin', 'r'); sendRequestAsUser(userDomainAdmin, loggedInAsUser => { loggedInAsUser( request(webserver.application) .post(API_ENDPOINT) .query('scope=domain') .query(`domain_id=${domain.id}`) .send([{ name: TEST_MODULE, keys: [TEST_CONFIG.name] }]) ) .expect(200) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual([{ name: TEST_MODULE, configurations: [TEST_CONFIG] }]); done(); })); }); }); }); describe('when scope is platform', function() { let userPlatformAdmin; beforeEach(function(done) { fixtures.newDummyUser(['platformadmin@email.com']).save(helpers.callbacks.noErrorAnd(user => { userPlatformAdmin = user; core.platformadmin .addPlatformAdmin(user) .then(() => done()) .catch(err => done(err || 'failed to add platformadmin')); })); }); it('should send back 403 if current user is not a platform admin', function(done) { sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser( request(webserver.application) .post(API_ENDPOINT) .query('scope=platform') .send([{ name: TEST_MODULE, keys: [TEST_CONFIG.name] }]) ) .expect(403) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 403, message: 'Forbidden', details: 'To perform this action, you need to be a platformadmin' } }); done(); })); }); }); it('should send back 400 if there are unreadable configs', function(done) { sendRequestAsUser(userPlatformAdmin, loggedInAsUser => { loggedInAsUser( request(webserver.application) .post(API_ENDPOINT) .query('scope=platform') .send([{ name: TEST_MODULE, keys: [TEST_CONFIG.name] }]) ) .expect(400) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 400, message: 'Bad Request', details: 'Configurations are not readable' } }); done(); })); }); }); it('should send back 200 with requested configs in body', function(done) { registerTestConfig('padmin', 'r'); sendRequestAsUser(userPlatformAdmin, loggedInAsUser => { loggedInAsUser( request(webserver.application) .post(API_ENDPOINT) .query('scope=platform') .send([{ name: TEST_MODULE, keys: [TEST_CONFIG.name] }]) ) .expect(200) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual([{ name: TEST_MODULE, configurations: [TEST_CONFIG] }]); done(); })); }); }); }); describe('when inspect is provided', function() { let userDomainMember; beforeEach(function(done) { helpers.api.applyDomainDeployment('linagora_test_domain', function(err, models) { expect(err).to.not.exist; userDomainMember = models.users[1]; done(); }); }); it('should get all readable configurations', function(done) { core['esn-config'].registry.register(TEST_MODULE, { configurations: { readOnlyKey: { rights: { user: 'r' } }, writableKey: { rights: { user: 'rw' } }, unReadableKey: { rights: { user: '' } }, [TEST_CONFIG.name]: { rights: { user: 'rw' } } } }); sendRequestAsUser(userDomainMember, loggedInAsUser => { loggedInAsUser( request(webserver.application) .post(API_ENDPOINT) .query('scope=user') .query('inspect=true') .send([{ name: TEST_MODULE, keys: [] }]) ) .expect(200) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.deep.equal([{ name: TEST_MODULE, configurations: [{ name: 'readOnlyKey', writable: false }, { name: 'writableKey', writable: true }, { name: TEST_CONFIG.name, value: TEST_CONFIG.value, writable: true }] }]); done(); })); }); }); }); }); describe('PUT /api/configurations', function() { const API_ENDPOINT = '/api/configurations'; const REQUEST_BODY = [{ name: TEST_MODULE, configurations: [{ name: TEST_CONFIG.name, value: 'new value' }] }]; it('should send back 401 if the user is not logged in', function(done) { helpers.api.requireLogin(webserver.application, 'put', API_ENDPOINT, done); }); it('should send back 400 if scope query is missing', function(done) { sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser(request(webserver.application).put(API_ENDPOINT)) .expect(400) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 400, message: 'Bad Request', details: 'missing scope in query' } }); done(); })); }); }); it('should send back 400 if scope query is invalid', function(done) { sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser( request(webserver.application) .put(API_ENDPOINT) .query('scope=invalid') ) .expect(400) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 400, message: 'Bad Request', details: 'scope must be either platform, domain or user' } }); done(); })); }); }); it('should send back 400 if body is not an array', function(done) { sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser( request(webserver.application) .put(API_ENDPOINT) .query('scope=user') .send('not and array') ) .expect(400) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 400, message: 'Bad Request', details: 'body should be an array' } }); done(); })); }); }); it('should send back 400 if body array is not well-formed (some modules have no name)', function(done) { sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser( request(webserver.application) .put(API_ENDPOINT) .query('scope=user') .send([{}, { name: TEST_MODULE }]) ) .expect(400) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 400, message: 'Bad Request', details: 'body data is not well-formed: one of modules in array does not have name' } }); done(); })); }); }); it('should send back 400 if body array is not well-formed (some modules have no configurations array)', function(done) { sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser( request(webserver.application) .put(API_ENDPOINT) .query('scope=user') .send([{ name: TEST_MODULE, configurations: 'not an array' }]) ) .expect(400) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 400, message: 'Bad Request', details: `module ${TEST_MODULE} must have "configurations" attribute as an array of {name, value}` } }); done(); })); }); }); it('should send back 400 if body array is not well-formed (some configurations have no name)', function(done) { sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser( request(webserver.application) .put(API_ENDPOINT) .query('scope=user') .send([{ name: TEST_MODULE, configurations: [{}] }]) ) .expect(400) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 400, message: 'Bad Request', details: `module ${TEST_MODULE} must have "configurations" attribute as an array of {name, value}` } }); done(); })); }); }); describe('The validation', function() { it('should send back 400 if configuration value is missing', function(done) { core['esn-config'].registry.register(TEST_MODULE, { configurations: { [TEST_CONFIG.name]: { validator() { return null; } } } }); sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser( request(webserver.application) .put(API_ENDPOINT) .query('scope=user') .send([{ name: TEST_MODULE, configurations: [{ name: TEST_CONFIG.name }] }]) ) .expect(400) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 400, message: 'Bad Request', details: `${TEST_MODULE}->${TEST_CONFIG.name}: The value is required` } }); done(); })); }); }); it('should send back 400 if configuration is considered invalid by the validator', function(done) { core['esn-config'].registry.register(TEST_MODULE, { configurations: { [TEST_CONFIG.name]: { validator() { return 'invalid value'; } } } }); sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser( request(webserver.application) .put(API_ENDPOINT) .query('scope=user') .send([{ name: TEST_MODULE, configurations: [{ name: TEST_CONFIG.name, value: 'aaa' }] }]) ) .expect(400) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 400, message: 'Bad Request', details: `${TEST_MODULE}->${TEST_CONFIG.name}: invalid value` } }); done(); })); }); }); }); describe('when scope is user', function() { it('should send back 400 if there are unwritable configs', function(done) { registerTestConfig('user', 'r'); sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser( request(webserver.application) .put(API_ENDPOINT) .query('scope=user') .send(REQUEST_BODY) ) .expect(400) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 400, message: 'Bad Request', details: 'Configurations are not writable' } }); done(); })); }); }); it('should send back 204 on success', function(done) { registerTestConfig('user', 'w'); sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser( request(webserver.application) .put(API_ENDPOINT) .query('scope=user') .send(REQUEST_BODY) ) .expect(204) .end(helpers.callbacks.noErrorAnd(() => { core['esn-config'](TEST_CONFIG.name) .inModule(TEST_MODULE) .forUser(userAlice, true) .get() .done(config => { expect(config).to.equal('new value'); done(); }); })); }); }); }); describe('when scope is domain', function() { let userDomainAdmin, userDomainMember, domain; beforeEach(function(done) { registerTestConfig('admin', 'r'); helpers.api.applyDomainDeployment('linagora_test_domain', function(err, models) { expect(err).to.not.exist; userDomainAdmin = models.users[0]; userDomainMember = models.users[1]; domain = models.domain; done(); }); }); it('should send back 400 if domain_id is missing', function(done) { sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser( request(webserver.application) .put(API_ENDPOINT) .query('scope=domain') .send(REQUEST_BODY) ) .expect(400) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 400, message: 'Bad Request', details: 'when scope is domain, domain_id is required' } }); done(); })); }); }); it('should send back 400 if the domain_id is not an ObjectId', function(done) { sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser( request(webserver.application) .put(API_ENDPOINT) .query('scope=domain') .query('domain_id=a_domain_id') .send(REQUEST_BODY) ) .expect(400) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 400, message: 'Bad Request', details: 'Invalid domain_id parameter' } }); done(); })); }); }); it('should send back 404 if no domain found to match with domain_id', function(done) { sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser( request(webserver.application) .put(API_ENDPOINT) .query('scope=domain') .query('domain_id=58e522df9ea18136135c02a7') .send(REQUEST_BODY) ) .expect(404) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 404, message: 'Not found', details: 'The domain 58e522df9ea18136135c02a7 could not be found' } }); done(); })); }); }); it('should send back 403 if current user is not the domain admin', function(done) { sendRequestAsUser(userDomainMember, loggedInAsUser => { loggedInAsUser( request(webserver.application) .put(API_ENDPOINT) .query('scope=domain') .query(`domain_id=${domain.id}`) .send(REQUEST_BODY) ) .expect(403) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 403, message: 'Forbidden', details: 'User is not the domain manager' } }); done(); })); }); }); it('should send back 400 if there are unwritable configs', function(done) { sendRequestAsUser(userDomainAdmin, loggedInAsUser => { loggedInAsUser( request(webserver.application) .put(API_ENDPOINT) .query('scope=user') .query(`domain_id=${domain.id}`) .send(REQUEST_BODY) ) .expect(400) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 400, message: 'Bad Request', details: 'Configurations are not writable' } }); done(); })); }); }); it('should send back 204 on success', function(done) { registerTestConfig('admin', 'w'); sendRequestAsUser(userDomainAdmin, loggedInAsUser => { loggedInAsUser( request(webserver.application) .put(API_ENDPOINT) .query('scope=domain') .query(`domain_id=${domain.id}`) .send(REQUEST_BODY) ) .expect(204) .end(helpers.callbacks.noErrorAnd(() => { core['esn-config'](TEST_CONFIG.name) .inModule(TEST_MODULE) .forUser({ preferredDomainId: domain.id }) .get() .done(config => { expect(config).to.equal('new value'); done(); }); })); }); }); }); describe('when scope is platform', function() { let userPlatformAdmin; beforeEach(function(done) { registerTestConfig('padmin', 'r'); fixtures.newDummyUser(['platformadmin@email.com']).save(helpers.callbacks.noErrorAnd(user => { userPlatformAdmin = user; core.platformadmin .addPlatformAdmin(user) .then(() => done()) .catch(err => done(err || 'failed to add platformadmin')); })); }); it('should send back 403 if current user is not a platform admin', function(done) { sendRequestAsUser(userAlice, loggedInAsUser => { loggedInAsUser( request(webserver.application) .put(API_ENDPOINT) .query('scope=platform') .send(REQUEST_BODY) ) .expect(403) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 403, message: 'Forbidden', details: 'To perform this action, you need to be a platformadmin' } }); done(); })); }); }); it('should send back 400 if there are unwritable configs', function(done) { sendRequestAsUser(userPlatformAdmin, loggedInAsUser => { loggedInAsUser( request(webserver.application) .put(API_ENDPOINT) .query('scope=platform') .send(REQUEST_BODY) ) .expect(400) .end(helpers.callbacks.noErrorAnd(res => { expect(res.body).to.shallowDeepEqual({ error: { code: 400, message: 'Bad Request', details: 'Configurations are not writable' } }); done(); })); }); }); it('should send back 204 on success', function(done) { registerTestConfig('padmin', 'w'); sendRequestAsUser(userPlatformAdmin, loggedInAsUser => { loggedInAsUser( request(webserver.application) .put(API_ENDPOINT) .query('scope=platform') .send(REQUEST_BODY) ) .expect(204) .end(helpers.callbacks.noErrorAnd(() => { core['esn-config'](TEST_CONFIG.name) .inModule(TEST_MODULE) .get() .done(config => { expect(config).to.equal('new value'); done(); }); })); }); }); }); }); });