1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-05-22 01:16:07 +02:00

fix: e2e tests should only set up one database per test file (#504)

* fix: e2e tests should only set up one database per test file

* fix: Allow e2e-tests to reset db content
This commit is contained in:
Ivar Conradi Østhus 2019-10-03 15:01:33 +02:00
parent b717ad7e2f
commit d1fd5d3900
13 changed files with 294 additions and 253 deletions

View File

@ -1,24 +1,35 @@
'use strict'; 'use strict';
const test = require('ava'); const test = require('ava');
const { setupApp } = require('./../../helpers/test-helper'); const { setupApp } = require('../../helpers/test-helper');
const dbInit = require('../../helpers/database-init');
const getLogger = require('../../../fixtures/no-logger');
let stores;
test.before(async () => {
const db = await dbInit('event_api_serial', getLogger);
stores = db.stores;
});
test.after(async () => {
await stores.db.destroy();
});
test.serial('returns events', async t => { test.serial('returns events', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('event_api_serial'); const request = await setupApp(stores);
return request return request
.get('/api/admin/events') .get('/api/admin/events')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(200) .expect(200);
.then(destroy);
}); });
test.serial('returns events given a name', async t => { test.serial('returns events given a name', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('event_api_serial'); const request = await setupApp(stores);
return request return request
.get('/api/admin/events/myname') .get('/api/admin/events/myname')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(200) .expect(200);
.then(destroy);
}); });

View File

@ -2,49 +2,56 @@
const test = require('ava'); const test = require('ava');
const { setupApp } = require('./../../helpers/test-helper'); const { setupApp } = require('./../../helpers/test-helper');
const dbInit = require('../../helpers/database-init');
const getLogger = require('../../../fixtures/no-logger');
let stores;
test.before(async () => {
const db = await dbInit('archive_serial', getLogger);
stores = db.stores;
});
test.after(async () => {
await stores.db.destroy();
});
test.serial('returns three archived toggles', async t => { test.serial('returns three archived toggles', async t => {
t.plan(1); t.plan(1);
const { request, destroy } = await setupApp('archive_serial'); const request = await setupApp(stores);
return request return request
.get('/api/admin/archive/features') .get('/api/admin/archive/features')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(200) .expect(200)
.expect(res => { .expect(res => {
t.true(res.body.features.length === 3); t.true(res.body.features.length === 3);
}) });
.then(destroy);
}); });
test.serial('revives a feature by name', async t => { test.serial('revives a feature by name', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('archive_serial'); const request = await setupApp(stores);
return request return request
.post('/api/admin/archive/revive/featureArchivedX') .post('/api/admin/archive/revive/featureArchivedX')
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.expect(200) .expect(200);
.then(destroy);
}); });
test.serial( test.serial(
'archived feature is not accessible via /features/:featureName', 'archived feature is not accessible via /features/:featureName',
async t => { async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('archive_serial2'); const request = await setupApp(stores);
return request return request
.get('/api/admin/features/featureArchivedX') .get('/api/admin/features/featureArchivedZ')
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.expect(404) .expect(404);
.then(destroy);
} }
); );
test.serial('must set name when reviving toggle', async t => { test.serial('must set name when reviving toggle', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('archive_serial'); const request = await setupApp(stores);
return request return request.post('/api/admin/archive/revive/').expect(404);
.post('/api/admin/archive/revive/')
.expect(404)
.then(destroy);
}); });

View File

@ -2,10 +2,23 @@
const test = require('ava'); const test = require('ava');
const { setupAppWithAuth } = require('./../../helpers/test-helper'); const { setupAppWithAuth } = require('./../../helpers/test-helper');
const dbInit = require('../../helpers/database-init');
const getLogger = require('../../../fixtures/no-logger');
let stores;
test.before(async () => {
const db = await dbInit('feature_api_auth', getLogger);
stores = db.stores;
});
test.after(async () => {
await stores.db.destroy();
});
test.serial('creates new feature toggle with createdBy', async t => { test.serial('creates new feature toggle with createdBy', async t => {
t.plan(1); t.plan(1);
const { request, destroy } = await setupAppWithAuth('feature_api_auth'); const request = await setupAppWithAuth(stores);
// Login // Login
await request.post('/api/admin/login').send({ await request.post('/api/admin/login').send({
email: 'user@mail.com', email: 'user@mail.com',
@ -18,19 +31,13 @@ test.serial('creates new feature toggle with createdBy', async t => {
strategies: [{ name: 'default' }], strategies: [{ name: 'default' }],
}); });
await request await request.get('/api/admin/events').expect(res => {
.get('/api/admin/events')
.expect(res => {
t.true(res.body.events[0].createdBy === 'user@mail.com'); t.true(res.body.events[0].createdBy === 'user@mail.com');
}) });
.then(destroy);
}); });
test.serial('should require authenticated user', async t => { test.serial('should require authenticated user', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupAppWithAuth('feature_api_auth'); const request = await setupAppWithAuth(stores);
return request return request.get('/api/admin/features').expect(401);
.get('/api/admin/features')
.expect(401)
.then(destroy);
}); });

View File

@ -5,6 +5,20 @@ const { setupAppWithCustomAuth } = require('./../../helpers/test-helper');
const AuthenticationRequired = require('./../../../../lib/authentication-required'); const AuthenticationRequired = require('./../../../../lib/authentication-required');
const User = require('./../../../../lib/user'); const User = require('./../../../../lib/user');
const dbInit = require('../../helpers/database-init');
const getLogger = require('../../../fixtures/no-logger');
let stores;
test.before(async () => {
const db = await dbInit('feature_api_custom_auth', getLogger);
stores = db.stores;
});
test.after(async () => {
await stores.db.destroy();
});
test.serial('should require authenticated user', async t => { test.serial('should require authenticated user', async t => {
t.plan(0); t.plan(0);
const preHook = app => { const preHook = app => {
@ -21,14 +35,8 @@ test.serial('should require authenticated user', async t => {
.end() .end()
); );
}; };
const { request, destroy } = await setupAppWithCustomAuth( const request = await setupAppWithCustomAuth(stores, preHook);
'feature_api_custom_auth', return request.get('/api/admin/features').expect(401);
preHook
);
return request
.get('/api/admin/features')
.expect(401)
.then(destroy);
}); });
test.serial('creates new feature toggle with createdBy', async t => { test.serial('creates new feature toggle with createdBy', async t => {
@ -41,10 +49,7 @@ test.serial('creates new feature toggle with createdBy', async t => {
next(); next();
}); });
}; };
const { request, destroy } = await setupAppWithCustomAuth( const request = await setupAppWithCustomAuth(stores, preHook);
'feature_api_custom_auth',
preHook
);
// create toggle // create toggle
await request.post('/api/admin/features').send({ await request.post('/api/admin/features').send({
@ -53,10 +58,7 @@ test.serial('creates new feature toggle with createdBy', async t => {
strategies: [{ name: 'default' }], strategies: [{ name: 'default' }],
}); });
await request await request.get('/api/admin/events').expect(res => {
.get('/api/admin/events')
.expect(res => {
t.true(res.body.events[0].createdBy === user.email); t.true(res.body.events[0].createdBy === user.email);
}) });
.then(destroy);
}); });

View File

@ -1,43 +1,53 @@
'use strict'; 'use strict';
const test = require('ava'); const test = require('ava');
const { setupApp } = require('./../../helpers/test-helper'); const dbInit = require('../../helpers/database-init');
const { setupApp } = require('../../helpers/test-helper');
const getLogger = require('../../../fixtures/no-logger');
let stores;
test.before(async () => {
const db = await dbInit('feature_api_serial', getLogger);
stores = db.stores;
});
test.after(async () => {
await stores.db.destroy();
});
test.serial('returns list of feature toggles', async t => { test.serial('returns list of feature toggles', async t => {
const { request, destroy } = await setupApp('feature_api_serial'); const request = await setupApp(stores);
return request return request
.get('/api/admin/features') .get('/api/admin/features')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(200) .expect(200)
.expect(res => { .expect(res => {
t.true(res.body.features.length === 4); t.true(res.body.features.length === 4);
}) });
.then(destroy);
}); });
test.serial('gets a feature by name', async t => { test.serial('gets a feature by name', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('feature_api_serial'); const request = await setupApp(stores);
return request return request
.get('/api/admin/features/featureX') .get('/api/admin/features/featureX')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(200) .expect(200);
.then(destroy);
}); });
test.serial('cant get feature that dose not exist', async t => { test.serial('cant get feature that dose not exist', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('feature_api_serial'); const request = await setupApp(stores);
return request return request
.get('/api/admin/features/myfeature') .get('/api/admin/features/myfeature')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(404) .expect(404);
.then(destroy);
}); });
test.serial('creates new feature toggle', async t => { test.serial('creates new feature toggle', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('feature_api_serial'); const request = await setupApp(stores);
return request return request
.post('/api/admin/features') .post('/api/admin/features')
.send({ .send({
@ -46,13 +56,12 @@ test.serial('creates new feature toggle', async t => {
strategies: [{ name: 'default' }], strategies: [{ name: 'default' }],
}) })
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.expect(201) .expect(201);
.then(destroy);
}); });
test.serial('creates new feature toggle with variants', async t => { test.serial('creates new feature toggle with variants', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('feature_api_serial'); const request = await setupApp(stores);
return request return request
.post('/api/admin/features') .post('/api/admin/features')
.send({ .send({
@ -65,65 +74,58 @@ test.serial('creates new feature toggle with variants', async t => {
], ],
}) })
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.expect(201) .expect(201);
.then(destroy);
}); });
test.serial('fetch feature toggle with variants', async t => { test.serial('fetch feature toggle with variants', async t => {
t.plan(1); t.plan(1);
const { request, destroy } = await setupApp('feature_api_serial'); const request = await setupApp(stores);
return request return request
.get('/api/admin/features/feature.with.variants') .get('/api/admin/features/feature.with.variants')
.expect(res => { .expect(res => {
t.true(res.body.variants.length === 2); t.true(res.body.variants.length === 2);
}) });
.then(destroy);
}); });
test.serial('creates new feature toggle with createdBy unknown', async t => { test.serial('creates new feature toggle with createdBy unknown', async t => {
t.plan(1); t.plan(1);
const { request, destroy } = await setupApp('feature_api_serial'); const request = await setupApp(stores);
await request.post('/api/admin/features').send({ await request.post('/api/admin/features').send({
name: 'com.test.Username', name: 'com.test.Username',
enabled: false, enabled: false,
strategies: [{ name: 'default' }], strategies: [{ name: 'default' }],
}); });
await request await request.get('/api/admin/events').expect(res => {
.get('/api/admin/events')
.expect(res => {
t.true(res.body.events[0].createdBy === 'none@unknown.com'); t.true(res.body.events[0].createdBy === 'none@unknown.com');
}) });
.then(destroy);
}); });
test.serial('require new feature toggle to have a name', async t => { test.serial('require new feature toggle to have a name', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('feature_api_serial'); const request = await setupApp(stores);
return request return request
.post('/api/admin/features') .post('/api/admin/features')
.send({ name: '' }) .send({ name: '' })
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.expect(400) .expect(400);
.then(destroy);
}); });
test.serial( test.serial(
'can not change status of feature toggle that does not exist', 'can not change status of feature toggle that does not exist',
async t => { async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('feature_api_serial'); const request = await setupApp(stores);
return request return request
.put('/api/admin/features/should-not-exist') .put('/api/admin/features/should-not-exist')
.send({ name: 'should-not-exist', enabled: false }) .send({ name: 'should-not-exist', enabled: false })
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.expect(404) .expect(404);
.then(destroy);
} }
); );
test.serial('can change status of feature toggle that does exist', async t => { test.serial('can change status of feature toggle that does exist', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('feature_api_serial'); const request = await setupApp(stores);
return request return request
.put('/api/admin/features/featureY') .put('/api/admin/features/featureY')
.send({ .send({
@ -132,75 +134,64 @@ test.serial('can change status of feature toggle that does exist', async t => {
strategies: [{ name: 'default' }], strategies: [{ name: 'default' }],
}) })
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.expect(200) .expect(200);
.then(destroy);
}); });
test.serial('can not toggle of feature that does not exist', async t => { test.serial('can not toggle of feature that does not exist', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('feature_api_serial'); const request = await setupApp(stores);
return request return request
.post('/api/admin/features/should-not-exist/toggle') .post('/api/admin/features/should-not-exist/toggle')
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.expect(404) .expect(404);
.then(destroy);
}); });
test.serial('can toggle a feature that does exist', async t => { test.serial('can toggle a feature that does exist', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('feature_api_serial'); const request = await setupApp(stores);
return request return request
.post('/api/admin/features/featureY/toggle') .post('/api/admin/features/featureY/toggle')
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.expect(200) .expect(200);
.then(destroy);
}); });
test.serial('archives a feature by name', async t => { test.serial('archives a feature by name', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('feature_api_serial'); const request = await setupApp(stores);
return request return request.delete('/api/admin/features/featureX').expect(200);
.delete('/api/admin/features/featureX')
.expect(200)
.then(destroy);
}); });
test.serial('can not archive unknown feature', async t => { test.serial('can not archive unknown feature', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('feature_api_serial'); const request = await setupApp(stores);
return request return request.delete('/api/admin/features/featureUnknown').expect(404);
.delete('/api/admin/features/featureUnknown')
.expect(404)
.then(destroy);
}); });
test.serial('refuses to create a feature with an existing name', async t => { test.serial('refuses to create a feature with an existing name', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('feature_api_serial'); const request = await setupApp(stores);
return request return request
.post('/api/admin/features') .post('/api/admin/features')
.send({ name: 'featureX' }) .send({ name: 'featureX' })
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.expect(400) .expect(400);
.then(destroy);
}); });
test.serial('refuses to validate a feature with an existing name', async t => { test.serial('refuses to validate a feature with an existing name', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('feature_api_serial'); const request = await setupApp(stores);
return request return request
.post('/api/admin/features/validate') .post('/api/admin/features/validate')
.send({ name: 'featureX' }) .send({ name: 'featureX' })
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.expect(400) .expect(400);
.then(destroy);
}); });
test.serial( test.serial(
'new strategies api can add two strategies to a feature toggle', 'new strategies api can add two strategies to a feature toggle',
async t => { async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('feature_api_serial'); const request = await setupApp(stores);
return request return request
.put('/api/admin/features/featureY') .put('/api/admin/features/featureY')
.send({ .send({
@ -215,14 +206,13 @@ test.serial(
], ],
}) })
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.expect(200) .expect(200);
.then(destroy);
} }
); );
test.serial('should not be possible to create archived toggle', async t => { test.serial('should not be possible to create archived toggle', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('feature_api_serial'); const request = await setupApp(stores);
return request return request
.post('/api/admin/features') .post('/api/admin/features')
.send({ .send({
@ -231,17 +221,16 @@ test.serial('should not be possible to create archived toggle', async t => {
strategies: [{ name: 'default' }], strategies: [{ name: 'default' }],
}) })
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.expect(400) .expect(400);
.then(destroy);
}); });
test.serial('creates new feature toggle with variant overrides', async t => { test.serial('creates new feature toggle with variant overrides', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('feature_api_serial'); const request = await setupApp(stores);
return request return request
.post('/api/admin/features') .post('/api/admin/features')
.send({ .send({
name: 'com.test.variants', name: 'com.test.variants.overrieds',
enabled: false, enabled: false,
strategies: [{ name: 'default' }], strategies: [{ name: 'default' }],
variants: [ variants: [
@ -259,6 +248,5 @@ test.serial('creates new feature toggle with variant overrides', async t => {
], ],
}) })
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.expect(201) .expect(201);
.then(destroy);
}); });

View File

@ -1,11 +1,30 @@
'use strict'; 'use strict';
const test = require('ava'); const test = require('ava');
const { setupApp } = require('./../../helpers/test-helper'); const dbInit = require('../../helpers/database-init');
const { setupApp } = require('../../helpers/test-helper');
const getLogger = require('../../../fixtures/no-logger');
let stores;
let reset = () => {};
test.before(async () => {
const db = await dbInit('metrics_serial', getLogger);
stores = db.stores;
reset = db.reset;
});
test.after(async () => {
await stores.db.destroy();
});
test.afterEach(async () => {
await reset();
});
test.serial('should register client', async t => { test.serial('should register client', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('metrics_serial'); const request = await setupApp(stores);
return request return request
.post('/api/client/register') .post('/api/client/register')
.send({ .send({
@ -15,13 +34,12 @@ test.serial('should register client', async t => {
started: Date.now(), started: Date.now(),
interval: 10, interval: 10,
}) })
.expect(202) .expect(202);
.then(destroy);
}); });
test.serial('should allow client to register multiple times', async t => { test.serial('should allow client to register multiple times', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('metrics_serial'); const request = await setupApp(stores);
const clientRegistration = { const clientRegistration = {
appName: 'multipleRegistration', appName: 'multipleRegistration',
instanceId: 'test', instanceId: 'test',
@ -39,13 +57,12 @@ test.serial('should allow client to register multiple times', async t => {
.post('/api/client/register') .post('/api/client/register')
.send(clientRegistration) .send(clientRegistration)
.expect(202) .expect(202)
) );
.then(destroy);
}); });
test.serial('should accept client metrics', async t => { test.serial('should accept client metrics', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('metrics_serial'); const request = await setupApp(stores);
return request return request
.post('/api/client/metrics') .post('/api/client/metrics')
.send({ .send({
@ -57,13 +74,12 @@ test.serial('should accept client metrics', async t => {
toggles: {}, toggles: {},
}, },
}) })
.expect(202) .expect(202);
.then(destroy);
}); });
test.serial('should get application details', async t => { test.serial('should get application details', async t => {
t.plan(3); t.plan(3);
const { request, destroy } = await setupApp('metrics_serial'); const request = await setupApp(stores);
return request return request
.get('/api/admin/metrics/applications/demo-app-1') .get('/api/admin/metrics/applications/demo-app-1')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
@ -71,19 +87,17 @@ test.serial('should get application details', async t => {
t.true(res.status === 200); t.true(res.status === 200);
t.true(res.body.appName === 'demo-app-1'); t.true(res.body.appName === 'demo-app-1');
t.true(res.body.instances.length === 1); t.true(res.body.instances.length === 1);
}) });
.then(destroy);
}); });
test.serial('should get list of applications', async t => { test.serial('should get list of applications', async t => {
t.plan(2); t.plan(2);
const { request, destroy } = await setupApp('metrics_serial'); const request = await setupApp(stores);
return request return request
.get('/api/admin/metrics/applications') .get('/api/admin/metrics/applications')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(res => { .expect(res => {
t.true(res.status === 200); t.true(res.status === 200);
t.true(res.body.applications.length === 2); t.is(res.body.applications.length, 2);
}) });
.then(destroy);
}); });

View File

@ -1,12 +1,25 @@
'use strict'; 'use strict';
const test = require('ava'); const test = require('ava');
const { setupApp } = require('./../../helpers/test-helper');
const importData = require('../../../examples/import.json'); const importData = require('../../../examples/import.json');
const dbInit = require('../../helpers/database-init');
const { setupApp } = require('../../helpers/test-helper');
const getLogger = require('../../../fixtures/no-logger');
let stores;
test.before(async () => {
const db = await dbInit('state_api_serial', getLogger);
stores = db.stores;
});
test.after(async () => {
await stores.db.destroy();
});
test.serial('exports strategies and features as json by default', async t => { test.serial('exports strategies and features as json by default', async t => {
t.plan(2); t.plan(2);
const { request, destroy } = await setupApp('state_api_serial'); const request = await setupApp(stores);
return request return request
.get('/api/admin/state/export') .get('/api/admin/state/export')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
@ -14,67 +27,60 @@ test.serial('exports strategies and features as json by default', async t => {
.expect(res => { .expect(res => {
t.true('features' in res.body); t.true('features' in res.body);
t.true('strategies' in res.body); t.true('strategies' in res.body);
}) });
.then(destroy);
}); });
test.serial('exports strategies and features as yaml', async t => { test.serial('exports strategies and features as yaml', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('state_api_serial'); const request = await setupApp(stores);
return request return request
.get('/api/admin/state/export?format=yaml') .get('/api/admin/state/export?format=yaml')
.expect('Content-Type', /yaml/) .expect('Content-Type', /yaml/)
.expect(200) .expect(200);
.then(destroy);
}); });
test.serial('exports strategies and features as attachment', async t => { test.serial('exports strategies and features as attachment', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('state_api_serial'); const request = await setupApp(stores);
return request return request
.get('/api/admin/state/export?download=1') .get('/api/admin/state/export?download=1')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect('Content-Disposition', /attachment/) .expect('Content-Disposition', /attachment/)
.expect(200) .expect(200);
.then(destroy);
}); });
test.serial('imports strategies and features', async t => { test.serial('imports strategies and features', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('state_api_serial'); const request = await setupApp(stores);
return request return request
.post('/api/admin/state/import') .post('/api/admin/state/import')
.send(importData) .send(importData)
.expect(202) .expect(202);
.then(destroy);
}); });
test.serial('does not not accept gibberish', async t => { test.serial('does not not accept gibberish', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('state_api_serial'); const request = await setupApp(stores);
return request return request
.post('/api/admin/state/import') .post('/api/admin/state/import')
.send({ features: 'nonsense' }) .send({ features: 'nonsense' })
.expect(400) .expect(400);
.then(destroy);
}); });
test.serial('imports strategies and features from json file', async t => { test.serial('imports strategies and features from json file', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('state_api_serial'); const request = await setupApp(stores);
return request return request
.post('/api/admin/state/import') .post('/api/admin/state/import')
.attach('file', 'test/examples/import.json') .attach('file', 'test/examples/import.json')
.expect(202) .expect(202);
.then(destroy);
}); });
test.serial('imports strategies and features from yaml file', async t => { test.serial('imports strategies and features from yaml file', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('state_api_serial'); const request = await setupApp(stores);
return request return request
.post('/api/admin/state/import') .post('/api/admin/state/import')
.attach('file', 'test/examples/import.yml') .attach('file', 'test/examples/import.yml')
.expect(202) .expect(202);
.then(destroy);
}); });

View File

@ -1,11 +1,25 @@
'use strict'; 'use strict';
const test = require('ava'); const test = require('ava');
const { setupApp } = require('./../../helpers/test-helper');
const dbInit = require('../../helpers/database-init');
const { setupApp } = require('../../helpers/test-helper');
const getLogger = require('../../../fixtures/no-logger');
let stores;
test.before(async () => {
const db = await dbInit('strategy_api_serial', getLogger);
stores = db.stores;
});
test.after(async () => {
await stores.db.destroy();
});
test.serial('gets all strategies', async t => { test.serial('gets all strategies', async t => {
t.plan(1); t.plan(1);
const { request, destroy } = await setupApp('strategy_api_serial'); const request = await setupApp(stores);
return request return request
.get('/api/admin/strategies') .get('/api/admin/strategies')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
@ -15,33 +29,30 @@ test.serial('gets all strategies', async t => {
res.body.strategies.length === 2, res.body.strategies.length === 2,
'expected to have two strategies' 'expected to have two strategies'
); );
}) });
.then(destroy);
}); });
test.serial('gets a strategy by name', async t => { test.serial('gets a strategy by name', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('strategy_api_serial'); const request = await setupApp(stores);
return request return request
.get('/api/admin/strategies/default') .get('/api/admin/strategies/default')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(200) .expect(200);
.then(destroy);
}); });
test.serial('cant get a strategy by name that dose not exist', async t => { test.serial('cant get a strategy by name that dose not exist', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('strategy_api_serial'); const request = await setupApp(stores);
return request return request
.get('/api/admin/strategies/mystrategy') .get('/api/admin/strategies/mystrategy')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(404) .expect(404);
.then(destroy);
}); });
test.serial('creates a new strategy', async t => { test.serial('creates a new strategy', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('strategy_api_serial'); const request = await setupApp(stores);
return request return request
.post('/api/admin/strategies') .post('/api/admin/strategies')
.send({ .send({
@ -50,53 +61,44 @@ test.serial('creates a new strategy', async t => {
parameters: [], parameters: [],
}) })
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.expect(201) .expect(201);
.then(destroy);
}); });
test.serial('requires new strategies to have a name', async t => { test.serial('requires new strategies to have a name', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('strategy_api_serial'); const request = await setupApp(stores);
return request return request
.post('/api/admin/strategies') .post('/api/admin/strategies')
.send({ name: '' }) .send({ name: '' })
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.expect(400) .expect(400);
.then(destroy);
}); });
test.serial('refuses to create a strategy with an existing name', async t => { test.serial('refuses to create a strategy with an existing name', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('strategy_api_serial'); const request = await setupApp(stores);
return request return request
.post('/api/admin/strategies') .post('/api/admin/strategies')
.send({ name: 'default', parameters: [] }) .send({ name: 'default', parameters: [] })
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.expect(400) .expect(400);
.then(destroy);
}); });
test.serial('deletes a new strategy', async t => { test.serial('deletes a new strategy', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('strategy_api_serial'); const request = await setupApp(stores);
return request return request.delete('/api/admin/strategies/usersWithEmail').expect(200);
.delete('/api/admin/strategies/usersWithEmail')
.expect(200)
.then(destroy);
}); });
test.serial("can't delete a strategy that dose not exist", async t => { test.serial("can't delete a strategy that dose not exist", async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('strategy_api_serial', false); const request = await setupApp(stores);
return request return request.delete('/api/admin/strategies/unknown').expect(404);
.delete('/api/admin/strategies/unknown')
.expect(404)
.then(destroy);
}); });
test.serial('updates a exiting strategy', async t => { test.serial('updates a exiting strategy', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('strategy_api_serial'); const request = await setupApp(stores);
return request return request
.put('/api/admin/strategies/default') .put('/api/admin/strategies/default')
.send({ .send({
@ -105,17 +107,15 @@ test.serial('updates a exiting strategy', async t => {
parameters: [], parameters: [],
}) })
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.expect(200) .expect(200);
.then(destroy);
}); });
test.serial('cant update a unknown strategy', async t => { test.serial('cant update a unknown strategy', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('strategy_api_serial'); const request = await setupApp(stores);
return request return request
.put('/api/admin/strategies/unknown') .put('/api/admin/strategies/unknown')
.send({ name: 'unkown', parameters: [] }) .send({ name: 'unkown', parameters: [] })
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.expect(404) .expect(404);
.then(destroy);
}); });

View File

@ -1,36 +1,46 @@
'use strict'; 'use strict';
const test = require('ava'); const test = require('ava');
const { setupApp } = require('./../../helpers/test-helper'); const { setupApp } = require('../../helpers/test-helper');
const dbInit = require('../../helpers/database-init');
const getLogger = require('../../../fixtures/no-logger');
let stores;
test.before(async () => {
const db = await dbInit('feature_api_client', getLogger);
stores = db.stores;
});
test.after(async () => {
await stores.db.destroy();
});
test.serial('returns four feature toggles', async t => { test.serial('returns four feature toggles', async t => {
const { request, destroy } = await setupApp('feature_api_client'); const request = await setupApp(stores);
return request return request
.get('/api/client/features') .get('/api/client/features')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(200) .expect(200)
.expect(res => { .expect(res => {
t.true(res.body.features.length === 4); t.true(res.body.features.length === 4);
}) });
.then(destroy);
}); });
test.serial('gets a feature by name', async t => { test.serial('gets a feature by name', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('feature_api_client'); const request = await setupApp(stores);
return request return request
.get('/api/client/features/featureX') .get('/api/client/features/featureX')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(200) .expect(200);
.then(destroy);
}); });
test.serial('cant get feature that dose not exist', async t => { test.serial('cant get feature that dose not exist', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('feature_api_client'); const request = await setupApp(stores);
return request return request
.get('/api/client/features/myfeature') .get('/api/client/features/myfeature')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(404) .expect(404);
.then(destroy);
}); });

View File

@ -4,25 +4,36 @@ const test = require('ava');
const { setupApp } = require('./../../helpers/test-helper'); const { setupApp } = require('./../../helpers/test-helper');
const metricsExample = require('../../../examples/client-metrics.json'); const metricsExample = require('../../../examples/client-metrics.json');
const dbInit = require('../../helpers/database-init');
const getLogger = require('../../../fixtures/no-logger');
let stores;
test.before(async () => {
const db = await dbInit('metrics_api_client', getLogger);
stores = db.stores;
});
test.after(async () => {
await stores.db.destroy();
});
test.serial('should be possble to send metrics', async t => { test.serial('should be possble to send metrics', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('metrics_api_client'); const request = await setupApp(stores);
return request return request
.post('/api/client/metrics') .post('/api/client/metrics')
.send(metricsExample) .send(metricsExample)
.expect(202) .expect(202);
.then(destroy);
}); });
test.serial('should require valid send metrics', async t => { test.serial('should require valid send metrics', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('metrics_api_client'); const request = await setupApp(stores);
return request return request
.post('/api/client/metrics') .post('/api/client/metrics')
.send({ .send({
appName: 'test', appName: 'test',
}) })
.expect(400) .expect(400);
.then(destroy);
}); });

View File

@ -2,14 +2,26 @@
const test = require('ava'); const test = require('ava');
const { setupApp } = require('./helpers/test-helper'); const { setupApp } = require('./helpers/test-helper');
const dbInit = require('./helpers/database-init');
const getLogger = require('../fixtures/no-logger');
let stores;
test.before(async () => {
const db = await dbInit('health_api', getLogger);
stores = db.stores;
});
test.after(async () => {
await stores.db.destroy();
});
test('returns health good', async t => { test('returns health good', async t => {
t.plan(0); t.plan(0);
const { request, destroy } = await setupApp('health'); const request = await setupApp(stores);
return request return request
.get('/health') .get('/health')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(200) .expect(200)
.expect('{"health":"GOOD"}') .expect('{"health":"GOOD"}');
.then(destroy);
}); });

View File

@ -69,5 +69,11 @@ module.exports = async function init(databaseSchema = 'test', getLogger) {
await resetDatabase(stores); await resetDatabase(stores);
await setupDatabase(stores); await setupDatabase(stores);
return stores; return {
stores,
reset: async () => {
await resetDatabase(stores);
await setupDatabase(stores);
},
};
}; };

View File

@ -5,7 +5,6 @@ process.env.NODE_ENV = 'test';
const supertest = require('supertest'); const supertest = require('supertest');
const getApp = require('../../../lib/app'); const getApp = require('../../../lib/app');
const dbInit = require('./database-init');
const getLogger = require('../../fixtures/no-logger'); const getLogger = require('../../fixtures/no-logger');
const StateService = require('../../../lib/state-service'); const StateService = require('../../../lib/state-service');
@ -26,50 +25,18 @@ function createApp(stores, adminAuthentication = 'none', preHook) {
} }
module.exports = { module.exports = {
async setupApp(name) { async setupApp(stores) {
const stores = await dbInit(name, getLogger);
const app = createApp(stores); const app = createApp(stores);
return supertest.agent(app);
},
return { async setupAppWithAuth(stores) {
request: supertest.agent(app),
destroy: async () => {
try {
await stores.db.destroy();
} catch (error) {
console.error('Failed to destroy db', error);
}
},
};
},
async setupAppWithAuth(name) {
const stores = await dbInit(name, getLogger);
const app = createApp(stores, 'unsecure'); const app = createApp(stores, 'unsecure');
return supertest.agent(app);
return {
request: supertest.agent(app),
destroy: async () => {
try {
await stores.db.destroy();
} catch (error) {
console.error('Failed to destroy db', error);
}
},
};
}, },
async setupAppWithCustomAuth(name, preHook) { async setupAppWithCustomAuth(stores, preHook) {
const stores = await dbInit(name, getLogger);
const app = createApp(stores, 'custom', preHook); const app = createApp(stores, 'custom', preHook);
return supertest.agent(app);
return {
request: supertest.agent(app),
destroy: async () => {
try {
await stores.db.destroy();
} catch (error) {
console.error('Failed to destroy db', error);
}
},
};
}, },
}; };