263 lines
11 KiB
JavaScript
263 lines
11 KiB
JavaScript
/* global it:false */
|
|
/* global describe:false */
|
|
/* global before:false */
|
|
/* global after:false */
|
|
|
|
'use strict';
|
|
|
|
const apps = require('../apps.js'),
|
|
BoxError = require('../boxerror.js'),
|
|
common = require('./common.js'),
|
|
expect = require('expect.js'),
|
|
safe = require('safetydance');
|
|
|
|
describe('Apps', function () {
|
|
const { domainSetup, cleanup, app, admin, user } = common;
|
|
|
|
before(domainSetup);
|
|
after(cleanup);
|
|
|
|
describe('validatePortBindings', function () {
|
|
it('does not allow invalid host port', function () {
|
|
expect(apps._validatePortBindings({ port: -1 }, { tcpPorts: { port: 5000 } })).to.be.an(Error);
|
|
expect(apps._validatePortBindings({ port: 0 }, { tcpPorts: { port: 5000 } })).to.be.an(Error);
|
|
expect(apps._validatePortBindings({ port: 'text' }, { tcpPorts: { port: 5000 } })).to.be.an(Error);
|
|
expect(apps._validatePortBindings({ port: 65536 }, { tcpPorts: { port: 5000 } })).to.be.an(Error);
|
|
expect(apps._validatePortBindings({ port: 470 }, { tcpPorts: { port: 5000 } })).to.be.an(Error);
|
|
});
|
|
|
|
it('does not allow ports not as part of manifest', function () {
|
|
expect(apps._validatePortBindings({ port: 1567 }, { tcpPorts: { } })).to.be.an(Error);
|
|
expect(apps._validatePortBindings({ port: 1567 }, { tcpPorts: { port3: null } })).to.be.an(Error);
|
|
});
|
|
|
|
it('does not allow reserved ports', function () {
|
|
expect(apps._validatePortBindings({ port: 443 }, { tcpPorts: { port: 5000 } })).to.be.an(Error);
|
|
expect(apps._validatePortBindings({ port: 50000 }, { tcpPorts: { port: 5000 } })).to.be.an(Error);
|
|
expect(apps._validatePortBindings({ port: 51000 }, { tcpPorts: { port: 5000 } })).to.be.an(Error);
|
|
expect(apps._validatePortBindings({ port: 50100 }, { tcpPorts: { port: 5000 } })).to.be.an(Error);
|
|
});
|
|
|
|
it('allows valid bindings', function () {
|
|
expect(apps._validatePortBindings({ port: 1024 }, { tcpPorts: { port: 5000 } })).to.be(null);
|
|
|
|
expect(apps._validatePortBindings({
|
|
port1: 4033,
|
|
port2: 3242,
|
|
port3: 1234
|
|
}, { tcpPorts: { port1: null, port2: null, port3: null } })).to.be(null);
|
|
});
|
|
});
|
|
|
|
describe('validateAccessRestriction', function () {
|
|
it('allows null input', function () {
|
|
expect(apps._validateAccessRestriction(null)).to.eql(null);
|
|
});
|
|
|
|
it('does not allow wrong user type', function () {
|
|
expect(apps._validateAccessRestriction({ users: {} })).to.be.an(Error);
|
|
});
|
|
|
|
it('allows user input', function () {
|
|
expect(apps._validateAccessRestriction({ users: [] })).to.eql(null);
|
|
});
|
|
|
|
it('allows single user input', function () {
|
|
expect(apps._validateAccessRestriction({ users: [ 'someuserid' ] })).to.eql(null);
|
|
});
|
|
|
|
it('allows multi user input', function () {
|
|
expect(apps._validateAccessRestriction({ users: [ 'someuserid', 'someuserid1', 'someuserid2', 'someuserid3' ] })).to.eql(null);
|
|
});
|
|
});
|
|
|
|
describe('canAccess', function () {
|
|
const someuser = { id: 'someuser', groupIds: [], role: 'user' };
|
|
const adminuser = { id: 'adminuser', groupIds: [ 'groupie' ], role: 'admin' };
|
|
|
|
it('returns true for unrestricted access', function () {
|
|
expect(apps.canAccess({ accessRestriction: null }, someuser)).to.be(true);
|
|
});
|
|
|
|
it('returns true for allowed user', function () {
|
|
expect(apps.canAccess({ accessRestriction: { users: [ 'someuser' ] } }, someuser)).to.be(true);
|
|
});
|
|
|
|
it('returns true for allowed user with multiple allowed', function () {
|
|
expect(apps.canAccess({ accessRestriction: { users: [ 'foo', 'someuser', 'anotheruser' ] } }, someuser)).to.be(true);
|
|
});
|
|
|
|
it('returns false for not allowed user', function () {
|
|
expect(apps.canAccess({ accessRestriction: { users: [ 'foo' ] } }, someuser)).to.be(false);
|
|
});
|
|
|
|
it('returns false for not allowed user with multiple allowed', function () {
|
|
expect(apps.canAccess({ accessRestriction: { users: [ 'foo', 'anotheruser' ] } }, someuser)).to.be(false);
|
|
});
|
|
|
|
it('returns false for no group or user', function () {
|
|
expect(apps.canAccess({ accessRestriction: { users: [ ], groups: [ ] } }, someuser)).to.be(false);
|
|
});
|
|
|
|
it('returns false for invalid group or user', function () {
|
|
expect(apps.canAccess({ accessRestriction: { users: [ ], groups: [ 'nop' ] } }, someuser)).to.be(false);
|
|
});
|
|
|
|
it('returns true for admin user', function () {
|
|
expect(apps.canAccess({ accessRestriction: { users: [ ], groups: [ 'nop' ] } }, adminuser)).to.be(true);
|
|
});
|
|
});
|
|
|
|
describe('crud', function () {
|
|
it('cannot get invalid app', async function () {
|
|
const result = await apps.get('nope');
|
|
expect(result).to.be(null);
|
|
});
|
|
|
|
it('can add app', async function () {
|
|
await apps.add(app.id, app.appStoreId, app.manifest, app.location, app.domain, app.portBindings, app);
|
|
});
|
|
|
|
it('cannot add with same app id', async function () {
|
|
const [error] = await safe(apps.add(app.id, app.appStoreId, app.manifest, app.location, app.domain, app.portBindings, app));
|
|
expect(error.reason).to.be(BoxError.ALREADY_EXISTS);
|
|
});
|
|
|
|
it('cannot add with same app id', async function () {
|
|
const [error] = await safe(apps.add(app.id, app.appStoreId, app.manifest, app.location, app.domain, app.portBindings, app));
|
|
expect(error.reason).to.be(BoxError.ALREADY_EXISTS);
|
|
});
|
|
|
|
it('can get app', async function () {
|
|
const result = await apps.get(app.id);
|
|
expect(result.manifest).to.eql(app.manifest);
|
|
expect(result.portBindings).to.eql({});
|
|
expect(result.location).to.eql(app.location);
|
|
});
|
|
|
|
it('can list apps', async function () {
|
|
const result = await apps.list();
|
|
expect(result.length).to.be(1);
|
|
expect(result[0].manifest).to.eql(app.manifest);
|
|
expect(result[0].portBindings).to.eql({});
|
|
expect(result[0].location).to.eql(app.location);
|
|
});
|
|
|
|
it('can listByUser', async function () {
|
|
let result = await apps.listByUser(admin);
|
|
expect(result.length).to.be(1);
|
|
|
|
result = await apps.listByUser(user);
|
|
expect(result.length).to.be(1);
|
|
});
|
|
|
|
it('update succeeds', async function () {
|
|
const data = {
|
|
installationState: 'some-other-status',
|
|
location:'some-other-location',
|
|
domain: app.domain, // needs to be set whenever location is set
|
|
manifest: Object.assign({}, app.manifest, { version: '0.2.0' }),
|
|
accessRestriction: '',
|
|
memoryLimit: 1337,
|
|
cpuShares: 102,
|
|
};
|
|
|
|
await apps.update(app.id, data);
|
|
const newApp = await apps.get(app.id);
|
|
expect(newApp.installationState).to.be('some-other-status');
|
|
expect(newApp.location).to.be('some-other-location');
|
|
expect(newApp.manifest.version).to.be('0.2.0');
|
|
expect(newApp.accessRestriction).to.be('');
|
|
expect(newApp.memoryLimit).to.be(1337);
|
|
expect(newApp.cpuShares).to.be(102);
|
|
});
|
|
|
|
it('update of nonexisting app fails', async function () {
|
|
const [error] = await safe(apps.update('random', { installationState: app.installationState, location: app.location }));
|
|
expect(error.reason).to.be(BoxError.NOT_FOUND);
|
|
});
|
|
|
|
it('delete succeeds', async function () {
|
|
await apps.del(app.id);
|
|
});
|
|
|
|
it('cannot delete previously delete record', async function () {
|
|
const [error] = await safe(apps.del(app.id));
|
|
expect(error.reason).to.be(BoxError.NOT_FOUND);
|
|
});
|
|
});
|
|
|
|
describe('setHealth', function () {
|
|
before(async function () {
|
|
await apps.add(app.id, app.appStoreId, app.manifest, app.location, app.domain, app.portBindings, app);
|
|
});
|
|
|
|
it('can set app as healthy', async function () {
|
|
const result = await apps.get(app.id);
|
|
expect(result.health).to.be(null);
|
|
|
|
await apps.setHealth(app.id, apps.HEALTH_HEALTHY, new Date());
|
|
});
|
|
|
|
it('did set app as healthy', async function () {
|
|
const result = await apps.get(app.id);
|
|
expect(result.health).to.be(apps.HEALTH_HEALTHY);
|
|
});
|
|
|
|
it('cannot set health of unknown app', async function () {
|
|
const [error] = await safe(apps.setHealth('randomId', apps.HEALTH_HEALTHY, new Date()));
|
|
expect(error.reason).to.be(BoxError.NOT_FOUND);
|
|
});
|
|
});
|
|
|
|
describe('configureInstalledApps', function () {
|
|
const app1 = Object.assign({}, app, { id: 'id1', installationState: apps.ISTATE_ERROR, location: 'loc1' });
|
|
const app2 = Object.assign({}, app, { id: 'id2', installationState: apps.ISTATE_INSTALLED, location: 'loc2' });
|
|
|
|
before(async function () {
|
|
await apps.update(app.id, { installationState: apps.ISTATE_INSTALLED });
|
|
await apps.add(app1.id, app1.appStoreId, app1.manifest, app1.location, app1.domain, app1.portBindings, app1);
|
|
await apps.add(app2.id, app2.appStoreId, app2.manifest, app2.location, app2.domain, app2.portBindings, app2);
|
|
});
|
|
|
|
after(async function () {
|
|
await apps.del(app1.id);
|
|
await apps.del(app2.id);
|
|
});
|
|
|
|
it('can mark apps for reconfigure', async function () {
|
|
await apps.configureInstalledApps();
|
|
|
|
const result = await apps.list();
|
|
expect(result[0].installationState).to.be(apps.ISTATE_PENDING_CONFIGURE);
|
|
expect(result[1].installationState).to.be(apps.ISTATE_ERROR);
|
|
expect(result[2].installationState).to.be(apps.ISTATE_PENDING_CONFIGURE);
|
|
});
|
|
});
|
|
|
|
describe('restoreInstalledApps', function () {
|
|
const app1 = Object.assign({}, app, { id: 'id1', installationState: apps.ISTATE_ERROR, location: 'loc1' });
|
|
const app2 = Object.assign({}, app, { id: 'id2', installationState: apps.ISTATE_INSTALLED, location: 'loc2' });
|
|
|
|
before(async function () {
|
|
await apps.update(app.id, { installationState: apps.ISTATE_INSTALLED });
|
|
await apps.add(app1.id, app1.appStoreId, app1.manifest, app1.location, app1.domain, app1.portBindings, app1);
|
|
await apps.add(app2.id, app2.appStoreId, app2.manifest, app2.location, app2.domain, app2.portBindings, app2);
|
|
});
|
|
|
|
after(async function () {
|
|
await apps.del(app1.id);
|
|
await apps.del(app2.id);
|
|
});
|
|
|
|
it('can mark apps for reconfigure', async function () {
|
|
await apps.restoreInstalledApps({});
|
|
|
|
const result = await apps.list();
|
|
expect(result[0].installationState).to.be(apps.ISTATE_PENDING_INSTALL);
|
|
expect(result[1].installationState).to.be(apps.ISTATE_ERROR);
|
|
expect(result[2].installationState).to.be(apps.ISTATE_PENDING_INSTALL);
|
|
});
|
|
});
|
|
});
|