mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	use ava as testrunner
This commit is contained in:
		
							parent
							
								
									142a05664c
								
							
						
					
					
						commit
						2f6c43052d
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -39,3 +39,4 @@ unleash-server.tar.gz | |||||||
| jsconfig.json | jsconfig.json | ||||||
| typings | typings | ||||||
| .vscode | .vscode | ||||||
|  | .nyc_output | ||||||
|  | |||||||
							
								
								
									
										19
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								package.json
									
									
									
									
									
								
							| @ -39,14 +39,13 @@ | |||||||
|     "start:dev:pg-chain": "export DATABASE_URL=postgres://$PGUSER:$PGPASSWORD@localhost:$PGPORT/postgres ; db-migrate up && npm run start:dev", |     "start:dev:pg-chain": "export DATABASE_URL=postgres://$PGUSER:$PGPASSWORD@localhost:$PGPORT/postgres ; db-migrate up && npm run start:dev", | ||||||
|     "db-migrate": "db-migrate up", |     "db-migrate": "db-migrate up", | ||||||
|     "db-migrate:down": "db-migrate down", |     "db-migrate:down": "db-migrate down", | ||||||
|     "test": "export PORT=4243 ; mocha --recursive test", |     "test": "PORT=4243 ava **/**test.js", | ||||||
|     "test:unit": "mocha test/unit/**/*.js ", |  | ||||||
|     "test:docker": "./scripts/docker-postgres.sh", |     "test:docker": "./scripts/docker-postgres.sh", | ||||||
|     "test:watch": "mocha --watch test test/*", |     "test:watch": "npm run test -- --watch", | ||||||
|     "test:pg-virtualenv": "pg_virtualenv npm run test:pg-virtualenv-chai", |     "test:pg-virtualenv": "pg_virtualenv npm run test:pg-virtualenv-chai", | ||||||
|     "test:pg-virtualenv-chain": "export TEST_DATABASE_URL=postgres://$PGUSER:$PGPASSWORD@localhost:$PGPORT/postgres ; npm run db-migrate-testdb && npm test", |     "test:pg-virtualenv-chain": "export TEST_DATABASE_URL=postgres://$PGUSER:$PGPASSWORD@localhost:$PGPORT/postgres ; npm run db-migrate-testdb && npm test", | ||||||
|     "test:coverage": "istanbul cover ./node_modules/mocha/bin/_mocha test --report lcovonly -- -R spec --recursive", |     "test:coverage": "nyc npm run test", | ||||||
|     "test:coverage-report": "cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage" |     "test:coverage-report": "nyc report --reporter=text-lcov | coveralls && rm -rf ./coverage" | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "body-parser": "1.15.2", |     "body-parser": "1.15.2", | ||||||
| @ -70,13 +69,13 @@ | |||||||
|     "yallist": "^2.0.0" |     "yallist": "^2.0.0" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|  |     "@types/node": "^6.0.46", | ||||||
|     "ava": "^0.16.0", |     "ava": "^0.16.0", | ||||||
|     "coveralls": "^2.11.14", |     "coveralls": "^2.11.15", | ||||||
|     "istanbul": "^0.4.5", |     "nyc": "^8.4.0", | ||||||
|     "mocha": "^3.0.2", |  | ||||||
|     "mocha-lcov-reporter": "1.2.0", |  | ||||||
|     "sinon": "^1.17.5", |     "sinon": "^1.17.5", | ||||||
|     "supertest": "^2.0.0", |     "superagent": "^2.3.0", | ||||||
|  |     "supertest": "^2.0.1", | ||||||
|     "supervisor": "^0.11.0", |     "supervisor": "^0.11.0", | ||||||
|     "unleash-frontend": "1.0.0-alpha.2" |     "unleash-frontend": "1.0.0-alpha.2" | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -1,6 +0,0 @@ | |||||||
| { |  | ||||||
|     "env": { |  | ||||||
|         "browser": true, |  | ||||||
|         "mocha": true |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,27 +1,27 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| const specHelper = require('./util/test-helper'); | const test = require('ava'); | ||||||
| let request; | const { setupApp } = require('./util/test-helper'); | ||||||
|  | const logger = require('../../lib/logger'); | ||||||
| 
 | 
 | ||||||
| describe('The event api', () => { | test.beforeEach(() =>  { | ||||||
|     beforeEach(done => { |     logger.setLevel('FATAL'); | ||||||
|         specHelper.setupApp().then((app) => { | }); | ||||||
|             request = app.request; | 
 | ||||||
|             done(); | test.serial('returns events', async (t) => { | ||||||
|         }); |     const { request, destroy } = await setupApp('event_api_serial'); | ||||||
|     }); |     return request | ||||||
| 
 |         .get('/api/events') | ||||||
|     it('returns events', done => { |         .expect('Content-Type', /json/) | ||||||
|         request |         .expect(200) | ||||||
|             .get('/api/events') |         .then(destroy); | ||||||
|             .expect('Content-Type', /json/) | }); | ||||||
|             .expect(200, done); | 
 | ||||||
|     }); | test.serial('returns events given a name', async (t) => { | ||||||
| 
 |     const { request, destroy } = await setupApp('event_api_serial'); | ||||||
|     it('returns events given a name', done => { |     return request | ||||||
|         request |         .get('/api/events/myname') | ||||||
|             .get('/api/events/myname') |         .expect('Content-Type', /json/) | ||||||
|             .expect('Content-Type', /json/) |         .expect(200) | ||||||
|             .expect(200, done); |         .then(destroy); | ||||||
|     }); |  | ||||||
| }); | }); | ||||||
|  | |||||||
| @ -1,176 +1,190 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
|  | const { test } = require('ava'); | ||||||
|  | const { setupApp } = require('./util/test-helper'); | ||||||
| const logger = require('../../lib/logger'); | const logger = require('../../lib/logger'); | ||||||
| const assert     = require('assert'); |  | ||||||
| const specHelper = require('./util/test-helper'); |  | ||||||
| const stringify  = function (o) { |  | ||||||
|     return JSON.stringify(o, null, ' '); |  | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| let request; | test.beforeEach(() =>  { | ||||||
| 
 |     logger.setLevel('FATAL'); | ||||||
| describe('The features api', () => { |  | ||||||
|     beforeEach(done => { |  | ||||||
|         specHelper.setupApp().then((app) => { |  | ||||||
|             request = app.request; |  | ||||||
|             done(); |  | ||||||
|         }); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('returns three feature toggles', done => { |  | ||||||
|         request |  | ||||||
|             .get('/features') |  | ||||||
|             .expect('Content-Type', /json/) |  | ||||||
|             .expect(200) |  | ||||||
|             .end((err, res) => { |  | ||||||
|                 assert(res.body.features.length === 3, `expected 3 features, got ${stringify(res.body)}`); |  | ||||||
|                 done(); |  | ||||||
|             }); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('gets a feature by name', done => { |  | ||||||
|         request |  | ||||||
|             .get('/features/featureX') |  | ||||||
|             .expect('Content-Type', /json/) |  | ||||||
|             .expect(200, done); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('cant get feature that dose not exist', done => { |  | ||||||
|         logger.setLevel('FATAL'); |  | ||||||
|         request |  | ||||||
|             .get('/features/myfeature') |  | ||||||
|             .expect('Content-Type', /json/) |  | ||||||
|             .expect(404, done); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('creates new feature toggle', done => { |  | ||||||
|         request |  | ||||||
|             .post('/features') |  | ||||||
|             .send({ name: 'com.test.feature', enabled: false }) |  | ||||||
|             .set('Content-Type', 'application/json') |  | ||||||
|             .expect(201, done); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('creates new feature toggle with createdBy', done => { |  | ||||||
|         logger.setLevel('FATAL'); |  | ||||||
|         request |  | ||||||
|             .post('/features') |  | ||||||
|             .send({ name: 'com.test.Username', enabled: false }) |  | ||||||
|             .set('Cookie', ['username=ivaosthu']) |  | ||||||
|             .set('Content-Type', 'application/json') |  | ||||||
|             .end(() => { |  | ||||||
|                 request |  | ||||||
|                     .get('/api/events') |  | ||||||
|                     .end((err, res) => { |  | ||||||
|                         assert.equal(res.body.events[0].createdBy, 'ivaosthu'); |  | ||||||
|                         done(); |  | ||||||
|                     }); |  | ||||||
|             }); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('require new feature toggle to have a name', done => { |  | ||||||
|         logger.setLevel('FATAL'); |  | ||||||
|         request |  | ||||||
|             .post('/features') |  | ||||||
|             .send({ name: '' }) |  | ||||||
|             .set('Content-Type', 'application/json') |  | ||||||
|             .expect(400, done); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('can not change status of feature toggle that does not exist', done => { |  | ||||||
|         logger.setLevel('FATAL'); |  | ||||||
|         request |  | ||||||
|             .put('/features/should-not-exist') |  | ||||||
|             .send({ name: 'should-not-exist', enabled: false }) |  | ||||||
|             .set('Content-Type', 'application/json') |  | ||||||
|             .expect(404, done); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('can change status of feature toggle that does exist', done => { |  | ||||||
|         logger.setLevel('FATAL'); |  | ||||||
|         request |  | ||||||
|             .put('/features/featureY') |  | ||||||
|             .send({ name: 'featureY', enabled: true }) |  | ||||||
|             .set('Content-Type', 'application/json') |  | ||||||
|             .expect(200, done); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('archives a feature by name', done => { |  | ||||||
|         request |  | ||||||
|             .delete('/features/featureX') |  | ||||||
|             .expect(200, done); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('can not archive unknown feature', done => { |  | ||||||
|         request |  | ||||||
|             .delete('/features/featureUnknown') |  | ||||||
|             .expect(404, done); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('refuses to create a feature with an existing name', done => { |  | ||||||
|         request |  | ||||||
|             .post('/features') |  | ||||||
|             .send({ name: 'featureX' }) |  | ||||||
|             .set('Content-Type', 'application/json') |  | ||||||
|             .expect(403, done); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('refuses to validate a feature with an existing name', done => { |  | ||||||
|         request |  | ||||||
|             .post('/features-validate') |  | ||||||
|             .send({ name: 'featureX' }) |  | ||||||
|             .set('Content-Type', 'application/json') |  | ||||||
|             .expect(403, done); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     describe('new strategies api', () => { |  | ||||||
|         it('automatically map existing strategy to strategies array', (done) => { |  | ||||||
|             request |  | ||||||
|                 .get('/features/featureY') |  | ||||||
|                 .expect('Content-Type', /json/) |  | ||||||
|                 .end((err, res) => { |  | ||||||
|                     assert.equal(res.body.strategies.length, 1, 'expected strategy added to strategies'); |  | ||||||
|                     assert.equal(res.body.strategy, res.body.strategies[0].name); |  | ||||||
|                     assert.deepEqual(res.body.parameters, res.body.strategies[0].parameters); |  | ||||||
|                     done(); |  | ||||||
|                 }); |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|         it('can add two strategies to a feature toggle', (done) => { |  | ||||||
|             request |  | ||||||
|                 .put('/features/featureY') |  | ||||||
|                 .send({ |  | ||||||
|                     name: 'featureY', |  | ||||||
|                     description: 'soon to be the #14 feature', |  | ||||||
|                     enabled: false, |  | ||||||
|                     strategies: [ |  | ||||||
|                         { |  | ||||||
|                             name: 'baz', |  | ||||||
|                             parameters: { foo: 'bar' }, |  | ||||||
|                         }, |  | ||||||
|                     ] }) |  | ||||||
|                 .set('Content-Type', 'application/json') |  | ||||||
|                 .expect(200, done); |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|         it('should not be allowed to post both strategy and strategies', (done) => { |  | ||||||
|             logger.setLevel('FATAL'); |  | ||||||
|             request |  | ||||||
|                 .post('/features') |  | ||||||
|                 .send({ |  | ||||||
|                     name: 'featureConfusing', |  | ||||||
|                     description: 'soon to be the #14 feature', |  | ||||||
|                     enabled: false, |  | ||||||
|                     strategy: 'baz', |  | ||||||
|                     parameters: {}, |  | ||||||
|                     strategies: [ |  | ||||||
|                         { |  | ||||||
|                             name: 'baz', |  | ||||||
|                             parameters: { foo: 'bar' }, |  | ||||||
|                         }, |  | ||||||
|                     ] }) |  | ||||||
|                 .set('Content-Type', 'application/json') |  | ||||||
|                 .expect(400, done); |  | ||||||
|         }); |  | ||||||
|     }); |  | ||||||
| }); | }); | ||||||
|  | 
 | ||||||
|  | test.serial('returns three feature toggles', async t => { | ||||||
|  |     const { request, destroy } = await setupApp('feature_api_serial'); | ||||||
|  |     return request | ||||||
|  |         .get('/features') | ||||||
|  |         .expect('Content-Type', /json/) | ||||||
|  |         .expect(200) | ||||||
|  |         .expect((res) => { | ||||||
|  |             t.true(res.body.features.length === 3); | ||||||
|  |         }) | ||||||
|  |         .then(destroy); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test.serial('gets a feature by name', async t => { | ||||||
|  |     const { request, destroy } = await setupApp('feature_api_serial'); | ||||||
|  |     return request | ||||||
|  |         .get('/features/featureX') | ||||||
|  |         .expect('Content-Type', /json/) | ||||||
|  |         .expect(200) | ||||||
|  |         .then(destroy); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test.serial('cant get feature that dose not exist', async t => { | ||||||
|  |     const { request, destroy } = await setupApp('feature_api_serial'); | ||||||
|  |     logger.setLevel('FATAL'); | ||||||
|  |     return request | ||||||
|  |         .get('/features/myfeature') | ||||||
|  |         .expect('Content-Type', /json/) | ||||||
|  |         .expect(404) | ||||||
|  |         .then(destroy); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test.serial('creates new feature toggle', async t => { | ||||||
|  |     const { request, destroy } = await setupApp('feature_api_serial'); | ||||||
|  |     return request | ||||||
|  |         .post('/features') | ||||||
|  |         .send({ name: 'com.test.feature', enabled: false }) | ||||||
|  |         .set('Content-Type', 'application/json') | ||||||
|  |         .expect(201) | ||||||
|  |         .then(destroy); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test.serial('creates new feature toggle with createdBy', async t => { | ||||||
|  |     const { request, destroy } = await setupApp('feature_api_serial'); | ||||||
|  |     logger.setLevel('FATAL'); | ||||||
|  |     request | ||||||
|  |         .post('/features') | ||||||
|  |         .send({ name: 'com.test.Username', enabled: false }) | ||||||
|  |         .set('Cookie', ['username=ivaosthu']) | ||||||
|  |         .set('Content-Type', 'application/json') | ||||||
|  |         .end(() => { | ||||||
|  |             return request | ||||||
|  |                 .get('/api/events') | ||||||
|  |                 .expect((res) => { | ||||||
|  |                     t.true(res.body.events[0].createdBy === 'ivaosthu'); | ||||||
|  |                 }) | ||||||
|  |                 .then(destroy); | ||||||
|  |         }); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test.serial('require new feature toggle to have a name', async t => { | ||||||
|  |     const { request, destroy } = await setupApp('feature_api_serial'); | ||||||
|  |     logger.setLevel('FATAL'); | ||||||
|  |     return request | ||||||
|  |         .post('/features') | ||||||
|  |         .send({ name: '' }) | ||||||
|  |         .set('Content-Type', 'application/json') | ||||||
|  |         .expect(400) | ||||||
|  |         .then(destroy); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test.serial('can not change status of feature toggle that does not exist', async t => { | ||||||
|  |     const { request, destroy } = await setupApp('feature_api_serial'); | ||||||
|  |     logger.setLevel('FATAL'); | ||||||
|  |     return request | ||||||
|  |         .put('/features/should-not-exist') | ||||||
|  |         .send({ name: 'should-not-exist', enabled: false }) | ||||||
|  |         .set('Content-Type', 'application/json') | ||||||
|  |         .expect(404).then(destroy); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test.serial('can change status of feature toggle that does exist', async t => { | ||||||
|  |     const { request, destroy } = await setupApp('feature_api_serial'); | ||||||
|  |     logger.setLevel('FATAL'); | ||||||
|  |     return request | ||||||
|  |         .put('/features/featureY') | ||||||
|  |         .send({ name: 'featureY', enabled: true }) | ||||||
|  |         .set('Content-Type', 'application/json') | ||||||
|  |         .expect(200).then(destroy); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test.serial('archives a feature by name', async t => { | ||||||
|  |     const { request, destroy } = await setupApp('feature_api_serial'); | ||||||
|  |     return request | ||||||
|  |         .delete('/features/featureX') | ||||||
|  |         .expect(200).then(destroy); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test.serial('can not archive unknown feature', async t => { | ||||||
|  |     const { request, destroy } = await setupApp('feature_api_serial'); | ||||||
|  |     return request | ||||||
|  |         .delete('/features/featureUnknown') | ||||||
|  |         .expect(404).then(destroy); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test.serial('refuses to create a feature with an existing name', async t => { | ||||||
|  |     const { request, destroy } = await setupApp('feature_api_serial'); | ||||||
|  |     return request | ||||||
|  |         .post('/features') | ||||||
|  |         .send({ name: 'featureX' }) | ||||||
|  |         .set('Content-Type', 'application/json') | ||||||
|  |         .expect(403).then(destroy); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test.serial('refuses to validate a feature with an existing name', async t => { | ||||||
|  |     const { request, destroy } = await setupApp('feature_api_serial'); | ||||||
|  |     return request | ||||||
|  |         .post('/features-validate') | ||||||
|  |         .send({ name: 'featureX' }) | ||||||
|  |         .set('Content-Type', 'application/json') | ||||||
|  |         .expect(403).then(destroy); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | test.serial('new strategies api automatically map existing strategy to strategies array', async t => { | ||||||
|  |     const { request, destroy } = await setupApp('feature_api_serial'); | ||||||
|  |     t.plan(3); | ||||||
|  |     return request | ||||||
|  |         .get('/features/featureY') | ||||||
|  |         .expect('Content-Type', /json/) | ||||||
|  |         .expect((res) => { | ||||||
|  |             t.true(res.body.strategies.length === 1, 'expected strategy added to strategies'); | ||||||
|  |             t.true(res.body.strategy === res.body.strategies[0].name); | ||||||
|  |             t.deepEqual(res.body.parameters, res.body.strategies[0].parameters); | ||||||
|  |         }) | ||||||
|  |         .then(destroy); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test.serial('new strategies api can add two strategies to a feature toggle', async t => { | ||||||
|  |     const { request, destroy } = await setupApp('feature_api_serial'); | ||||||
|  |     return request | ||||||
|  |         .put('/features/featureY') | ||||||
|  |         .send({ | ||||||
|  |             name: 'featureY', | ||||||
|  |             description: 'soon to be the #14 feature', | ||||||
|  |             enabled: false, | ||||||
|  |             strategies: [ | ||||||
|  |                 { | ||||||
|  |                     name: 'baz', | ||||||
|  |                     parameters: { foo: 'bar' }, | ||||||
|  |                 }, | ||||||
|  |             ], | ||||||
|  |         }) | ||||||
|  |         .set('Content-Type', 'application/json') | ||||||
|  |         .expect(200) | ||||||
|  |         .then(destroy); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test.serial('new strategies api should not be allowed to post both strategy and strategies', async t => { | ||||||
|  |     const { request, destroy } = await setupApp('feature_api_serial'); | ||||||
|  |     logger.setLevel('FATAL'); | ||||||
|  |     return request | ||||||
|  |         .post('/features') | ||||||
|  |         .send({ | ||||||
|  |             name: 'featureConfusing', | ||||||
|  |             description: 'soon to be the #14 feature', | ||||||
|  |             enabled: false, | ||||||
|  |             strategy: 'baz', | ||||||
|  |             parameters: {}, | ||||||
|  |             strategies: [ | ||||||
|  |                 { | ||||||
|  |                     name: 'baz', | ||||||
|  |                     parameters: { foo: 'bar' }, | ||||||
|  |                 }, | ||||||
|  |             ], | ||||||
|  |         }) | ||||||
|  |         .set('Content-Type', 'application/json') | ||||||
|  |         .expect(400) | ||||||
|  |         .then(destroy); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | |||||||
| @ -1,45 +1,40 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| const assert     = require('assert'); | const test = require('ava'); | ||||||
| const specHelper = require('./util/test-helper'); | const { setupApp } = require('./util/test-helper'); | ||||||
| const stringify  = function (o) { | const logger = require('../../lib/logger'); | ||||||
|     return JSON.stringify(o, null, ' '); |  | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| let request; | test.beforeEach(() =>  { | ||||||
| 
 |     logger.setLevel('FATAL'); | ||||||
| describe('The archive features api', () => { | }); | ||||||
|     beforeEach(done => { | 
 | ||||||
|         specHelper.setupApp().then((app) => { | test.serial('returns three archived toggles', async t => { | ||||||
|             request = app.request; |     const { request, destroy } = await setupApp('archive_serial'); | ||||||
|             done(); |     return request | ||||||
|         }); |         .get('/api/archive/features') | ||||||
|     });     |         .expect('Content-Type', /json/) | ||||||
| 
 |         .expect(200) | ||||||
| 
 |         .expect((res) => { | ||||||
|     it('returns three archived toggles', done => { |             t.true(res.body.features.length === 3); | ||||||
|         request |         }) | ||||||
|             .get('/api/archive/features') |         .then(destroy); | ||||||
|             .expect('Content-Type', /json/) | }); | ||||||
|             .expect(200) | 
 | ||||||
|             .end((err, res) => { | test.serial('revives a feature by name', async t => { | ||||||
|                 assert(res.body.features.length === 3, `expected 3 features, got ${stringify(res.body)}`); |     const { request, destroy  } = await setupApp('archive_serial'); | ||||||
|                 done(); |     return request | ||||||
|             }); |         .post('/api/archive/revive') | ||||||
|     }); |         .send({ name: 'featureArchivedX' }) | ||||||
| 
 |         .set('Content-Type', 'application/json') | ||||||
|     it('revives a feature by name', done => { |         .expect(200) | ||||||
|         request |         .then(destroy); | ||||||
|             .post('/api/archive/revive') | }); | ||||||
|             .send({ name: 'featureArchivedX' }) | 
 | ||||||
|             .set('Content-Type', 'application/json') | test.serial('must set name when reviving toggle', async t => { | ||||||
|             .expect(200, done); |     const { request, destroy  } = await setupApp('archive_serial'); | ||||||
|     }); |     return request | ||||||
| 
 |         .post('/api/archive/revive') | ||||||
|     it('must set name when reviving toggle', done => { |         .send({ name: '' }) | ||||||
|         request |         .expect(400) | ||||||
|             .post('/api/archive/revive') |         .then(destroy); | ||||||
|             .send({ name: '' }) |  | ||||||
|             .expect(400, done); |  | ||||||
|     }); |  | ||||||
| }); | }); | ||||||
|  | |||||||
| @ -1,64 +1,65 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
|  | const test = require('ava'); | ||||||
|  | const { setupApp } = require('./util/test-helper'); | ||||||
|  | const logger = require('../../lib/logger'); | ||||||
| 
 | 
 | ||||||
| const specHelper = require('./util/test-helper'); | test.beforeEach(() =>  { | ||||||
| const assert     = require('assert'); |     logger.setLevel('FATAL'); | ||||||
| let request; |  | ||||||
| 
 |  | ||||||
| describe('The metrics api', () => { |  | ||||||
|     beforeEach(done => { |  | ||||||
|         specHelper.setupApp().then((app) => { |  | ||||||
|             request = app.request; |  | ||||||
|             done(); |  | ||||||
|         }); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('should register client', (done) => { |  | ||||||
|         request |  | ||||||
|             .post('/api/client/register') |  | ||||||
|             .send({  |  | ||||||
|                 appName: 'demo', |  | ||||||
|                 instanceId: 'test', |  | ||||||
|                 strategies: ['default'], |  | ||||||
|                 started: Date.now(), |  | ||||||
|                 interval: 10  |  | ||||||
|             }) |  | ||||||
|             .expect(202, done); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('should accept client metrics', (done) => { |  | ||||||
|         request |  | ||||||
|             .post('/api/client/metrics') |  | ||||||
|             .send({  |  | ||||||
|                 appName: 'demo', |  | ||||||
|                 instanceId: '1', |  | ||||||
|                 bucket: { |  | ||||||
|                     start: Date.now(), |  | ||||||
|                     stop: Date.now(), |  | ||||||
|                     toggles: {} |  | ||||||
|                 } |  | ||||||
|             }) |  | ||||||
|             .expect(202, done) |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('should get client strategies', done => { |  | ||||||
|         request |  | ||||||
|             .get('/api/client/strategies') |  | ||||||
|             .expect('Content-Type', /json/) |  | ||||||
|             .end((err, res) => { |  | ||||||
|                 assert(res.status, 200); |  | ||||||
|                 assert(res.body.length === 1, `expected 1 registerd client, got ${res.body}`); |  | ||||||
|                 done(); |  | ||||||
|             });; |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('should get client instances', done => { |  | ||||||
|         request |  | ||||||
|             .get('/api/client/instances') |  | ||||||
|             .expect('Content-Type', /json/) |  | ||||||
|             .end((err, res) => { |  | ||||||
|                 assert(res.status, 200); |  | ||||||
|                 assert(res.body.length === 1, `expected 1 registerd client, got ${res.body}`); |  | ||||||
|                 done(); |  | ||||||
|             });; |  | ||||||
|     }); |  | ||||||
| }); | }); | ||||||
|  | 
 | ||||||
|  | test.serial('should register client', async (t) => { | ||||||
|  |     const { request, destroy  } = await setupApp('metrics_serial'); | ||||||
|  |     return request | ||||||
|  |         .post('/api/client/register') | ||||||
|  |         .send({ | ||||||
|  |             appName: 'demo', | ||||||
|  |             instanceId: 'test', | ||||||
|  |             strategies: ['default'], | ||||||
|  |             started: Date.now(), | ||||||
|  |             interval: 10 | ||||||
|  |         }) | ||||||
|  |         .expect(202) | ||||||
|  |         .then(destroy); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test.serial('should accept client metrics', async t => { | ||||||
|  |     const { request, destroy  } = await setupApp('metrics_serial'); | ||||||
|  |     return request | ||||||
|  |         .post('/api/client/metrics') | ||||||
|  |         .send({ | ||||||
|  |             appName: 'demo', | ||||||
|  |             instanceId: '1', | ||||||
|  |             bucket: { | ||||||
|  |                 start: Date.now(), | ||||||
|  |                 stop: Date.now(), | ||||||
|  |                 toggles: {} | ||||||
|  |             } | ||||||
|  |         }) | ||||||
|  |         .expect(202) | ||||||
|  |         .then(destroy); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test.serial('should get client strategies', async t => { | ||||||
|  |     const { request, destroy  } = await setupApp('metrics_serial'); | ||||||
|  |     return request | ||||||
|  |         .get('/api/client/strategies') | ||||||
|  |         .expect('Content-Type', /json/) | ||||||
|  |         .expect((res) => { | ||||||
|  |             t.true(res.status === 200); | ||||||
|  |             t.true(res.body.length === 1); | ||||||
|  |         }) | ||||||
|  |         .then(destroy); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test.serial('should get client instances', async t => { | ||||||
|  |     const { request, destroy  } = await setupApp('metrics_serial'); | ||||||
|  |     return request | ||||||
|  |         .get('/api/client/instances') | ||||||
|  |         .expect('Content-Type', /json/) | ||||||
|  |         .expect((res) => { | ||||||
|  |             t.true(res.status === 200); | ||||||
|  |             t.true(res.body.length === 1); | ||||||
|  |         }) | ||||||
|  |         .then(destroy); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | |||||||
| @ -1,23 +1,18 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| const specHelper = require('./util/test-helper'); | const test = require('ava'); | ||||||
|  | const { setupApp } = require('./util/test-helper'); | ||||||
|  | const logger = require('../../lib/logger'); | ||||||
| 
 | 
 | ||||||
| let request; | test.beforeEach(() =>  { | ||||||
| 
 |     logger.setLevel('FATAL'); | ||||||
| describe('The routes', () => { | }); | ||||||
|     beforeEach(done => { | 
 | ||||||
|         specHelper.setupApp().then((app) => { | test('returns health good', async (t) => { | ||||||
|             request = app.request; |     const { request, destroy } = await setupApp('health'); | ||||||
|             done(); |     return request.get('/health') | ||||||
|         }); |         .expect('Content-Type', /json/) | ||||||
|     }); |         .expect(200) | ||||||
| 
 |         .expect('{"health":"GOOD"}') | ||||||
|     describe('healthcheck', () => { |         .then(destroy); | ||||||
|         it('returns health good', done => { |  | ||||||
|             request.get('/health') |  | ||||||
|             .expect('Content-Type', /json/) |  | ||||||
|             .expect(200) |  | ||||||
|             .expect('{"health":"GOOD"}', done); |  | ||||||
|         }); |  | ||||||
|     }); |  | ||||||
| }); | }); | ||||||
|  | |||||||
| @ -1,70 +1,81 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| const specHelper = require('./util/test-helper'); | const test = require('ava'); | ||||||
| let request; | const { setupApp } = require('./util/test-helper'); | ||||||
|  | const logger = require('../../lib/logger'); | ||||||
| 
 | 
 | ||||||
| describe('The strategy api', () => { | test.beforeEach(() =>  { | ||||||
|     beforeEach(done => { |     logger.setLevel('FATAL'); | ||||||
|         specHelper.setupApp().then((app) => { | }); | ||||||
|             request = app.request; | 
 | ||||||
|             done(); | test.serial('gets all strategies', async (t) => { | ||||||
|         }); |     const { request, destroy } = await setupApp('strategy_api_serial'); | ||||||
|     }); |     return request | ||||||
| 
 |         .get('/api/strategies') | ||||||
|     it('gets all strategies', done => { |         .expect('Content-Type', /json/) | ||||||
|         request |         .expect(200) | ||||||
|             .get('/api/strategies') |         .then(destroy); | ||||||
|             .expect('Content-Type', /json/) | }); | ||||||
|             .expect(200, done); | 
 | ||||||
|     }); | test.serial('gets a strategy by name', async (t) => { | ||||||
| 
 |     const { request, destroy } = await setupApp('strategy_api_serial'); | ||||||
|     it('gets a strategy by name', done => { |     return request | ||||||
|         request |         .get('/api/strategies/default') | ||||||
|             .get('/api/strategies/default') |         .expect('Content-Type', /json/) | ||||||
|             .expect('Content-Type', /json/) |         .expect(200) | ||||||
|             .expect(200, done); |         .then(destroy); | ||||||
|     }); | }); | ||||||
| 
 | 
 | ||||||
|     it('cant get a strategy by name that dose not exist', done => { | test.serial('cant get a strategy by name that dose not exist', async (t) => { | ||||||
|         request |     const { request, destroy } = await setupApp('strategy_api_serial'); | ||||||
|             .get('/api/strategies/mystrategy') |     return request | ||||||
|             .expect('Content-Type', /json/) |         .get('/api/strategies/mystrategy') | ||||||
|             .expect(404, done); |         .expect('Content-Type', /json/) | ||||||
|     }); |         .expect(404) | ||||||
| 
 |         .then(destroy); | ||||||
|     it('creates a new strategy', done => { | }); | ||||||
|         request | 
 | ||||||
|             .post('/api/strategies') | test.serial('creates a new strategy', async (t) => { | ||||||
|             .send({ name: 'myCustomStrategy', description: 'Best strategy ever.' }) |     const { request, destroy } = await setupApp('strategy_api_serial'); | ||||||
|             .set('Content-Type', 'application/json') |     return request | ||||||
|             .expect(201, done); |         .post('/api/strategies') | ||||||
|     }); |         .send({ name: 'myCustomStrategy', description: 'Best strategy ever.' }) | ||||||
| 
 |         .set('Content-Type', 'application/json') | ||||||
|     it('requires new strategies to have a name', done => { |         .expect(201) | ||||||
|         request |         .then(destroy); | ||||||
|             .post('/api/strategies') | }); | ||||||
|             .send({ name: '' }) | 
 | ||||||
|             .set('Content-Type', 'application/json') | test.serial('requires new strategies to have a name', async (t) => { | ||||||
|             .expect(400, done); |     const { request, destroy } = await setupApp('strategy_api_serial'); | ||||||
|     }); |     return request | ||||||
| 
 |         .post('/api/strategies') | ||||||
|     it('refuses to create a strategy with an existing name', done => { |         .send({ name: '' }) | ||||||
|         request |         .set('Content-Type', 'application/json') | ||||||
|             .post('/api/strategies') |         .expect(400) | ||||||
|             .send({ name: 'default' }) |         .then(destroy); | ||||||
|             .set('Content-Type', 'application/json') | }); | ||||||
|             .expect(403, done); | 
 | ||||||
|     }); | test.serial('refuses to create a strategy with an existing name', async (t) => { | ||||||
| 
 |     const { request, destroy } = await setupApp('strategy_api_serial'); | ||||||
|     it('deletes a new strategy', done => { |     return request | ||||||
|         request |         .post('/api/strategies') | ||||||
|             .delete('/api/strategies/usersWithEmail') |         .send({ name: 'default' }) | ||||||
|             .expect(200, done); |         .set('Content-Type', 'application/json') | ||||||
|     }); |         .expect(403) | ||||||
| 
 |         .then(destroy); | ||||||
|     it('can\'t delete a strategy that dose not exist', done => { | }); | ||||||
|         request | 
 | ||||||
|             .delete('/api/strategies/unknown') | test.serial('deletes a new strategy', async (t) => { | ||||||
|             .expect(404, done); |     const { request, destroy } = await setupApp('strategy_api_serial'); | ||||||
|     }); |     return request | ||||||
|  |         .delete('/api/strategies/usersWithEmail') | ||||||
|  |         .expect(200) | ||||||
|  |         .then(destroy); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test.serial('can\'t delete a strategy that dose not exist', async (t) => { | ||||||
|  |     const { request, destroy } = await setupApp('strategy_api_serial', false); | ||||||
|  |     return request | ||||||
|  |         .delete('/api/strategies/unknown') | ||||||
|  |         .expect(404); | ||||||
| }); | }); | ||||||
|  | |||||||
| @ -2,28 +2,39 @@ | |||||||
| 
 | 
 | ||||||
| process.env.NODE_ENV = 'test'; | process.env.NODE_ENV = 'test'; | ||||||
| 
 | 
 | ||||||
| let supertest = require('supertest'); | const supertest = require('supertest'); | ||||||
| 
 |  | ||||||
| const options = { |  | ||||||
|     databaseUri: require('./database-config').getDatabaseUri(), |  | ||||||
|     databaseSchema: 'test' |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| const migrator = require('../../../migrator'); | const migrator = require('../../../migrator'); | ||||||
| const { createStores } = require('../../../lib/db'); | const { createStores } = require('../../../lib/db'); | ||||||
|  | const { createDb } = require('../../../lib/db/db-pool'); | ||||||
|  | const _app = require('../../../app'); | ||||||
| 
 | 
 | ||||||
| // because of migrator bug
 | // because of migrator bug
 | ||||||
| delete process.env.DATABASE_URL; | delete process.env.DATABASE_URL; | ||||||
| 
 | 
 | ||||||
| const db = require('../../../lib/db/db-pool').createDb(options.databaseUri); | function createApp (databaseSchema = 'test') { | ||||||
|  |     const options = { | ||||||
|  |         databaseUri: require('./database-config').getDatabaseUri(), | ||||||
|  |         databaseSchema, | ||||||
|  |         minPool: 0, | ||||||
|  |         maxPool: 0, | ||||||
|  |     }; | ||||||
|  |     const db = createDb({ databaseUri: options.databaseUri, minPool: 0, maxPool: 0 }); | ||||||
| 
 | 
 | ||||||
| const createApp = db.raw(`DROP SCHEMA IF EXISTS ${options.databaseSchema} CASCADE; CREATE SCHEMA ${options.databaseSchema}`) |     return db.raw(`DROP SCHEMA IF EXISTS ${options.databaseSchema} CASCADE; CREATE SCHEMA ${options.databaseSchema}`) | ||||||
|     .then(() => migrator(options.databaseUri, options.databaseSchema)) |         .then(() => migrator(options)) | ||||||
|     .then(() => { |         .then(() => { | ||||||
|         const stores = createStores(options); |             db.destroy(); | ||||||
|         const app = require('../../../app')({stores}); |             const stores = createStores(options); | ||||||
|         return { stores, request: supertest(app) }; |             const app = _app({ stores }); | ||||||
|     }); |             return { | ||||||
|  |                 stores, | ||||||
|  |                 request: supertest(app), | ||||||
|  |                 destroy () { | ||||||
|  |                     return stores.db.destroy(); | ||||||
|  |                 }, | ||||||
|  |             }; | ||||||
|  |         }); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| function createStrategies (stores) { | function createStrategies (stores) { | ||||||
|     return [ |     return [ | ||||||
| @ -49,7 +60,7 @@ function createClientStrategy (stores) { | |||||||
|             instanceId: 'test-1', |             instanceId: 'test-1', | ||||||
|             strategies: ['default'], |             strategies: ['default'], | ||||||
|             started: Date.now(), |             started: Date.now(), | ||||||
|             interval: 10  |             interval: 10, | ||||||
|         }, |         }, | ||||||
|     ].map(client => stores.clientStrategyStore.insert(client)); |     ].map(client => stores.clientStrategyStore.insert(client)); | ||||||
| } | } | ||||||
| @ -61,7 +72,7 @@ function createClientInstance (stores) { | |||||||
|             instanceId: 'test-1', |             instanceId: 'test-1', | ||||||
|             strategies: ['default'], |             strategies: ['default'], | ||||||
|             started: Date.now(), |             started: Date.now(), | ||||||
|             interval: 10  |             interval: 10, | ||||||
|         }, |         }, | ||||||
|     ].map(client => stores.clientInstanceStore.insert(client)); |     ].map(client => stores.clientInstanceStore.insert(client)); | ||||||
| } | } | ||||||
| @ -132,10 +143,10 @@ function createFeatures (stores) { | |||||||
| 
 | 
 | ||||||
| function resetDatabase (stores) { | function resetDatabase (stores) { | ||||||
|     return Promise.all([ |     return Promise.all([ | ||||||
|         stores.db('strategies').del(),  |         stores.db('strategies').del(), | ||||||
|         stores.db('features').del(), |         stores.db('features').del(), | ||||||
|         stores.db('client_strategies').del(), |         stores.db('client_strategies').del(), | ||||||
|         stores.db('client_instances').del() |         stores.db('client_instances').del(), | ||||||
|     ]); |     ]); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -144,15 +155,15 @@ function setupDatabase (stores) { | |||||||
|         createStrategies(stores) |         createStrategies(stores) | ||||||
|         .concat(createFeatures(stores) |         .concat(createFeatures(stores) | ||||||
|         .concat(createClientInstance(stores)) |         .concat(createClientInstance(stores)) | ||||||
|         .concat(createClientStrategy(stores)))) |         .concat(createClientStrategy(stores)))); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| module.exports = { | module.exports = { | ||||||
|     setupApp () { |     setupApp (name) { | ||||||
|         return createApp.then((app) => { |         return createApp(name).then((app) => { | ||||||
|             return resetDatabase(app.stores) |             return resetDatabase(app.stores) | ||||||
|             .then(() => setupDatabase(app.stores)) |                 .then(() => setupDatabase(app.stores)) | ||||||
|             .then(() => app); |                 .then(() => app); | ||||||
|         }); |         }); | ||||||
|     } |     }, | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -1,99 +1,103 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
|  | const test = require('ava'); | ||||||
| const eventDiffer = require('../../lib/event-differ'); | const eventDiffer = require('../../lib/event-differ'); | ||||||
| const eventType   = require('../../lib/event-type'); | const eventType = require('../../lib/event-type'); | ||||||
| const assert      = require('assert'); | const logger = require('../../lib/logger'); | ||||||
| 
 | 
 | ||||||
| describe('eventDiffer', () => { | test.beforeEach(() =>  { | ||||||
|     it('fails if events include an unknown event type', () => { |     logger.setLevel('FATAL'); | ||||||
|         const events = [ | }); | ||||||
|             { type: eventType.featureCreated, data: {} }, |  | ||||||
|             { type: 'unknown-type', data: {} }, |  | ||||||
|         ]; |  | ||||||
| 
 | 
 | ||||||
|         assert.throws(() => { | test('fails if events include an unknown event type', t => { | ||||||
|             eventDiffer.addDiffs(events); |     const events = [ | ||||||
|         }); |         { type: eventType.featureCreated, data: {} }, | ||||||
|     }); |         { type: 'unknown-type', data: {} }, | ||||||
| 
 |     ]; | ||||||
|     it('diffs a feature-update event', () => { |  | ||||||
|         const feature = 'foo'; |  | ||||||
|         const desc = 'bar'; |  | ||||||
| 
 |  | ||||||
|         const events = [ |  | ||||||
|             { |  | ||||||
|                 type: eventType.featureUpdated, |  | ||||||
|                 data: { name: feature, description: desc, strategy: 'default', enabled: true, parameters: { value: 2 } }, |  | ||||||
|             }, |  | ||||||
|             { |  | ||||||
|                 type: eventType.featureCreated, |  | ||||||
|                 data: { name: feature, description: desc, strategy: 'default', enabled: false, parameters: { value: 1 } }, |  | ||||||
|             }, |  | ||||||
|         ]; |  | ||||||
| 
 | 
 | ||||||
|  |     t.throws(() => { | ||||||
|         eventDiffer.addDiffs(events); |         eventDiffer.addDiffs(events); | ||||||
| 
 |  | ||||||
|         assert.deepEqual(events[0].diffs, [ |  | ||||||
|             { kind: 'E', path: ['enabled'], lhs: false, rhs: true }, |  | ||||||
|             { kind: 'E', path: ['parameters', 'value'], lhs: 1, rhs: 2 }, |  | ||||||
|         ]); |  | ||||||
| 
 |  | ||||||
|         assert.strictEqual(events[1].diffs, null); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('diffs only against features with the same name', () => { |  | ||||||
|         const events = [ |  | ||||||
|             { |  | ||||||
|                 type: eventType.featureUpdated, |  | ||||||
|                 data: { name: 'bar', description: 'desc', strategy: 'default', enabled: true, parameters: {} }, |  | ||||||
|             }, |  | ||||||
|             { |  | ||||||
|                 type: eventType.featureUpdated, |  | ||||||
|                 data: { name: 'foo', description: 'desc', strategy: 'default', enabled: false, parameters: {} }, |  | ||||||
|             }, |  | ||||||
|             { |  | ||||||
|                 type: eventType.featureCreated, |  | ||||||
|                 data: { name: 'bar', description: 'desc', strategy: 'default', enabled: false, parameters: {} }, |  | ||||||
|             }, |  | ||||||
|             { |  | ||||||
|                 type: eventType.featureCreated, |  | ||||||
|                 data: { name: 'foo', description: 'desc', strategy: 'default', enabled: true, parameters: {} }, |  | ||||||
|             }, |  | ||||||
|         ]; |  | ||||||
| 
 |  | ||||||
|         eventDiffer.addDiffs(events); |  | ||||||
| 
 |  | ||||||
|         assert.strictEqual(events[0].diffs[0].rhs, true); |  | ||||||
|         assert.strictEqual(events[1].diffs[0].rhs, false); |  | ||||||
|         assert.strictEqual(events[2].diffs, null); |  | ||||||
|         assert.strictEqual(events[3].diffs, null); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('sets an empty array of diffs if nothing was changed', () => { |  | ||||||
|         const events = [ |  | ||||||
|             { |  | ||||||
|                 type: eventType.featureUpdated, |  | ||||||
|                 data: { name: 'foo', description: 'desc', strategy: 'default', enabled: true, parameters: {} }, |  | ||||||
|             }, |  | ||||||
|             { |  | ||||||
|                 type: eventType.featureCreated, |  | ||||||
|                 data: { name: 'foo', description: 'desc', strategy: 'default', enabled: true, parameters: {} }, |  | ||||||
|             }, |  | ||||||
|         ]; |  | ||||||
| 
 |  | ||||||
|         eventDiffer.addDiffs(events); |  | ||||||
|         assert.deepEqual(events[0].diffs, []); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('sets diffs to null if there was nothing to diff against', () => { |  | ||||||
|         const events = [ |  | ||||||
|             { |  | ||||||
|                 type: eventType.featureUpdated, |  | ||||||
|                 data: { name: 'foo', description: 'desc', strategy: 'default', enabled: true, parameters: {} }, |  | ||||||
|             }, |  | ||||||
|         ]; |  | ||||||
| 
 |  | ||||||
|         eventDiffer.addDiffs(events); |  | ||||||
|         assert.strictEqual(events[0].diffs, null); |  | ||||||
|     }); |     }); | ||||||
| }); | }); | ||||||
|  | 
 | ||||||
|  | test('diffs a feature-update event', t => { | ||||||
|  |     const feature = 'foo'; | ||||||
|  |     const desc = 'bar'; | ||||||
|  | 
 | ||||||
|  |     const events = [ | ||||||
|  |         { | ||||||
|  |             type: eventType.featureUpdated, | ||||||
|  |             data: { name: feature, description: desc, strategy: 'default', enabled: true, parameters: { value: 2 } }, | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             type: eventType.featureCreated, | ||||||
|  |             data: { name: feature, description: desc, strategy: 'default', enabled: false, parameters: { value: 1 } }, | ||||||
|  |         }, | ||||||
|  |     ]; | ||||||
|  | 
 | ||||||
|  |     eventDiffer.addDiffs(events); | ||||||
|  | 
 | ||||||
|  |     t.deepEqual(events[0].diffs, [ | ||||||
|  |         { kind: 'E', path: ['enabled'], lhs: false, rhs: true }, | ||||||
|  |         { kind: 'E', path: ['parameters', 'value'], lhs: 1, rhs: 2 }, | ||||||
|  |     ]); | ||||||
|  | 
 | ||||||
|  |     t.true(events[1].diffs === null); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test('diffs only against features with the same name', t => { | ||||||
|  |     const events = [ | ||||||
|  |         { | ||||||
|  |             type: eventType.featureUpdated, | ||||||
|  |             data: { name: 'bar', description: 'desc', strategy: 'default', enabled: true, parameters: {} }, | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             type: eventType.featureUpdated, | ||||||
|  |             data: { name: 'foo', description: 'desc', strategy: 'default', enabled: false, parameters: {} }, | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             type: eventType.featureCreated, | ||||||
|  |             data: { name: 'bar', description: 'desc', strategy: 'default', enabled: false, parameters: {} }, | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             type: eventType.featureCreated, | ||||||
|  |             data: { name: 'foo', description: 'desc', strategy: 'default', enabled: true, parameters: {} }, | ||||||
|  |         }, | ||||||
|  |     ]; | ||||||
|  | 
 | ||||||
|  |     eventDiffer.addDiffs(events); | ||||||
|  | 
 | ||||||
|  |     t.true(events[0].diffs[0].rhs === true); | ||||||
|  |     t.true(events[1].diffs[0].rhs === false); | ||||||
|  |     t.true(events[2].diffs === null); | ||||||
|  |     t.true(events[3].diffs === null); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test('sets an empty array of diffs if nothing was changed', t => { | ||||||
|  |     const events = [ | ||||||
|  |         { | ||||||
|  |             type: eventType.featureUpdated, | ||||||
|  |             data: { name: 'foo', description: 'desc', strategy: 'default', enabled: true, parameters: {} }, | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             type: eventType.featureCreated, | ||||||
|  |             data: { name: 'foo', description: 'desc', strategy: 'default', enabled: true, parameters: {} }, | ||||||
|  |         }, | ||||||
|  |     ]; | ||||||
|  | 
 | ||||||
|  |     eventDiffer.addDiffs(events); | ||||||
|  |     t.deepEqual(events[0].diffs, []); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test('sets diffs to null if there was nothing to diff against', t => { | ||||||
|  |     const events = [ | ||||||
|  |         { | ||||||
|  |             type: eventType.featureUpdated, | ||||||
|  |             data: { name: 'foo', description: 'desc', strategy: 'default', enabled: true, parameters: {} }, | ||||||
|  |         }, | ||||||
|  |     ]; | ||||||
|  | 
 | ||||||
|  |     eventDiffer.addDiffs(events); | ||||||
|  |     t.true(events[0].diffs === null); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | |||||||
| @ -1,66 +1,63 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| const assert = require('assert'); | const test = require('ava'); | ||||||
| 
 |  | ||||||
| const mapper = require('../../../lib/helper/legacy-feature-mapper'); | const mapper = require('../../../lib/helper/legacy-feature-mapper'); | ||||||
| 
 | 
 | ||||||
| describe('legacy-feature-mapper', () => { | test('adds old fields to feature', t => { | ||||||
|     it('adds old fields to feature', () => { |     const feature = { | ||||||
|         const feature = { |         name: 'test', | ||||||
|             name: 'test', |         enabled: 0, | ||||||
|             enabled: 0, |         strategies: [{ | ||||||
|             strategies: [{ |             name: 'default', | ||||||
|                 name: 'default', |  | ||||||
|                 parameters: { |  | ||||||
|                     val: 'bar', |  | ||||||
|                 }, |  | ||||||
|             }], |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         const mappedFeature = mapper.addOldFields(feature); |  | ||||||
| 
 |  | ||||||
|         assert.equal(mappedFeature.name, feature.name); |  | ||||||
|         assert.equal(mappedFeature.enabled, feature.enabled); |  | ||||||
|         assert.equal(mappedFeature.strategy, feature.strategies[0].name); |  | ||||||
|         assert.notEqual(mappedFeature.parameters, feature.strategies[0].parameters); |  | ||||||
|         assert.deepEqual(mappedFeature.parameters, feature.strategies[0].parameters); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('transforms fields to new format', () => { |  | ||||||
|         const feature = { |  | ||||||
|             name: 'test', |  | ||||||
|             enabled: 0, |  | ||||||
|             strategy: 'default', |  | ||||||
|             parameters: { |             parameters: { | ||||||
|                 val: 'bar', |                 val: 'bar', | ||||||
|             }, |             }, | ||||||
|         }; |         }], | ||||||
|  |     }; | ||||||
| 
 | 
 | ||||||
|         const mappedFeature = mapper.toNewFormat(feature); |     const mappedFeature = mapper.addOldFields(feature); | ||||||
| 
 | 
 | ||||||
|         assert.equal(mappedFeature.name, feature.name); |     t.true(mappedFeature.name === feature.name); | ||||||
|         assert.equal(mappedFeature.enabled, feature.enabled); |     t.true(mappedFeature.enabled === feature.enabled); | ||||||
|         assert.equal(mappedFeature.strategies.length, 1); |     t.true(mappedFeature.strategy === feature.strategies[0].name); | ||||||
|         assert.equal(mappedFeature.strategies[0].name, feature.strategy); |     t.true(mappedFeature.parameters !== feature.strategies[0].parameters); | ||||||
|         assert.deepEqual(mappedFeature.strategies[0].parameters, feature.parameters); |     t.deepEqual(mappedFeature.parameters, feature.strategies[0].parameters); | ||||||
|         assert(mappedFeature.strategy === undefined); | }); | ||||||
|         assert(mappedFeature.parameters === undefined); | 
 | ||||||
|     }); | test('transforms fields to new format', t => { | ||||||
| 
 |     const feature = { | ||||||
|     it('should not transform if it already is the new format', () => { |         name: 'test', | ||||||
|         const feature = { |         enabled: 0, | ||||||
|             name: 'test', |         strategy: 'default', | ||||||
|             enabled: 0, |         parameters: { | ||||||
|             strategies: [{ |             val: 'bar', | ||||||
|                 name: 'default', |         }, | ||||||
|                 parameters: { |     }; | ||||||
|                     val: 'bar', | 
 | ||||||
|                 }, |     const mappedFeature = mapper.toNewFormat(feature); | ||||||
|             }], | 
 | ||||||
|         }; |     t.true(mappedFeature.name === feature.name); | ||||||
| 
 |     t.true(mappedFeature.enabled === feature.enabled); | ||||||
|         const mappedFeature = mapper.toNewFormat(feature); |     t.true(mappedFeature.strategies.length === 1); | ||||||
| 
 |     t.true(mappedFeature.strategies[0].name === feature.strategy); | ||||||
|         assert.equal(mappedFeature, feature); |     t.deepEqual(mappedFeature.strategies[0].parameters, feature.parameters); | ||||||
|     }); |     t.true(mappedFeature.strategy === undefined); | ||||||
|  |     t.true(mappedFeature.parameters === undefined); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test('should not transform if it already is the new format', t => { | ||||||
|  |     const feature = { | ||||||
|  |         name: 'test', | ||||||
|  |         enabled: 0, | ||||||
|  |         strategies: [{ | ||||||
|  |             name: 'default', | ||||||
|  |             parameters: { | ||||||
|  |                 val: 'bar', | ||||||
|  |             }, | ||||||
|  |         }], | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     const mappedFeature = mapper.toNewFormat(feature); | ||||||
|  | 
 | ||||||
|  |     t.true(mappedFeature === feature); | ||||||
| }); | }); | ||||||
|  | |||||||
| @ -1,61 +1,63 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
|  | const test = require('ava'); | ||||||
| const store = require('./mocks/store'); | const store = require('./mocks/store'); | ||||||
| 
 |  | ||||||
| const supertest = require('supertest'); | const supertest = require('supertest'); | ||||||
| const assert = require('assert'); | const logger = require('../../../lib/logger'); | ||||||
| 
 | 
 | ||||||
| 
 | test.beforeEach(() =>  { | ||||||
| let request; |     logger.setLevel('FATAL'); | ||||||
| let featureToggleStore; |  | ||||||
| 
 |  | ||||||
| describe('Unit: The features api', () => { |  | ||||||
|     beforeEach(done => { |  | ||||||
|         const stores = store.createStores();  |  | ||||||
|         const app = require('../../../app')({ |  | ||||||
|             baseUriPath: '', |  | ||||||
|             stores: stores, |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|         featureToggleStore = stores.featureToggleStore; |  | ||||||
|         request = supertest(app); |  | ||||||
|         done(); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('should get empty getFeatures', (done) => { |  | ||||||
|         request |  | ||||||
|             .get('/features') |  | ||||||
|             .expect('Content-Type', /json/) |  | ||||||
|             .expect(200) |  | ||||||
|             .end((err, res) => { |  | ||||||
|                 assert(res.body.features.length === 0); |  | ||||||
|                 done(); |  | ||||||
|             }); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('should get one getFeature', (done) => { |  | ||||||
|         featureToggleStore.addFeature( { name: 'test', strategies: [{ name: 'default' }] } ); |  | ||||||
| 
 |  | ||||||
|         request |  | ||||||
|             .get('/features') |  | ||||||
|             .expect('Content-Type', /json/) |  | ||||||
|             .expect(200) |  | ||||||
|             .end((err, res) => { |  | ||||||
|                 assert(res.body.features.length === 1); |  | ||||||
|                 done(); |  | ||||||
|             }); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('should add version numbers for /features', (done) => { |  | ||||||
|         featureToggleStore.addFeature( { name: 'test', strategies: [{ name: 'default' }] } ); |  | ||||||
| 
 |  | ||||||
|         request |  | ||||||
|             .get('/features') |  | ||||||
|             .expect('Content-Type', /json/) |  | ||||||
|             .expect(200) |  | ||||||
|             .end((err, res) => { |  | ||||||
|                 assert.equal(res.body.version, 1); |  | ||||||
|                 done(); |  | ||||||
|             }); |  | ||||||
|     }); |  | ||||||
| }); | }); | ||||||
|  | 
 | ||||||
|  | function getSetup () { | ||||||
|  |     const base = `/random${Math.round(Math.random() * 1000)}`; | ||||||
|  |     const stores = store.createStores(); | ||||||
|  |     const app = require('../../../app')({ | ||||||
|  |         baseUriPath: base, | ||||||
|  |         stores, | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     return { | ||||||
|  |         base, | ||||||
|  |         featureToggleStore: stores.featureToggleStore, | ||||||
|  |         request: supertest(app), | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | test('should get empty getFeatures', t => { | ||||||
|  |     const { request, base } = getSetup(); | ||||||
|  |     return request | ||||||
|  |         .get(`${base}/features`) | ||||||
|  |         .expect('Content-Type', /json/) | ||||||
|  |         .expect(200) | ||||||
|  |         .expect((res) => { | ||||||
|  |             t.true(res.body.features.length === 0); | ||||||
|  |         }); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test('should get one getFeature', t => { | ||||||
|  |     const { request, featureToggleStore, base } = getSetup(); | ||||||
|  |     featureToggleStore.addFeature({ name: 'test_', strategies: [{ name: 'default_' }] }); | ||||||
|  | 
 | ||||||
|  |     return request | ||||||
|  |         .get(`${base}/features`) | ||||||
|  |         .expect('Content-Type', /json/) | ||||||
|  |         .expect(200) | ||||||
|  |         .expect((res) => { | ||||||
|  |             t.true(res.body.features.length === 1); | ||||||
|  |         }); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test('should add version numbers for /features', t => { | ||||||
|  |     const { request, featureToggleStore, base } = getSetup(); | ||||||
|  |     featureToggleStore.addFeature({ name: 'test2', strategies: [{ name: 'default' }] }); | ||||||
|  | 
 | ||||||
|  |     return request | ||||||
|  |         .get(`${base}/features`) | ||||||
|  |         .expect('Content-Type', /json/) | ||||||
|  |         .expect(200) | ||||||
|  |         .expect((res) => { | ||||||
|  |             t.true(res.body.version === 1); | ||||||
|  |         }); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | |||||||
| @ -1,68 +1,74 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
|  | const test = require('ava'); | ||||||
| const store = require('./mocks/store'); | const store = require('./mocks/store'); | ||||||
| const supertest = require('supertest'); | const supertest = require('supertest'); | ||||||
| const assert = require('assert'); | const logger = require('../../../lib/logger'); | ||||||
| 
 | 
 | ||||||
| let request; | test.beforeEach(() =>  { | ||||||
| 
 |     logger.setLevel('FATAL'); | ||||||
| describe('Unit: The metrics api', () => { | }); | ||||||
|     beforeEach(done => { | 
 | ||||||
|         const stores = store.createStores();  | function getSetup () { | ||||||
|         const app = require('../../../app')({ |     const stores = store.createStores(); | ||||||
|             baseUriPath: '', |     const app = require('../../../app')({ | ||||||
|             stores: stores, |         baseUriPath: '', | ||||||
|         }); |         stores, | ||||||
| 
 |     }); | ||||||
|         request = supertest(app); | 
 | ||||||
|         done(); |     return { | ||||||
|     }); |         request: supertest(app), | ||||||
| 
 |     }; | ||||||
|     it('should register client', (done) => { | } | ||||||
|         request | 
 | ||||||
|             .post('/api/client/register') | test('should register client', () => { | ||||||
|             .send({  |     const { request } = getSetup(); | ||||||
|                 appName: 'demo', |     return request | ||||||
|                 instanceId: 'test', |         .post('/api/client/register') | ||||||
|                 strategies: ['default'], |         .send({ | ||||||
|                 started: Date.now(), |             appName: 'demo', | ||||||
|                 interval: 10  |             instanceId: 'test', | ||||||
|             }) |             strategies: ['default'], | ||||||
|             .expect(202, done); |             started: Date.now(), | ||||||
|     }); |             interval: 10, | ||||||
| 
 |         }) | ||||||
|     it('should require appName field', (done) => { |         .expect(202); | ||||||
|         request | }); | ||||||
|             .post('/api/client/register') | 
 | ||||||
|             .expect(400, done) | test('should require appName field', () => { | ||||||
|     }); |     const { request } = getSetup(); | ||||||
| 
 |     return request | ||||||
|     it('should require strategies field', (done) => { |         .post('/api/client/register') | ||||||
|         request |         .expect(400); | ||||||
|             .post('/api/client/register') | }); | ||||||
|             .send({  | 
 | ||||||
|                 appName: 'demo', | test('should require strategies field', () => { | ||||||
|                 instanceId: 'test', |     const { request } = getSetup(); | ||||||
|                 //strategies: ['default'],
 |     return request | ||||||
|                 started: Date.now(), |         .post('/api/client/register') | ||||||
|                 interval: 10  |         .send({ | ||||||
|             }) |             appName: 'demo', | ||||||
|             .expect(400, done) |             instanceId: 'test', | ||||||
|     }); |             // strategies: ['default'],
 | ||||||
| 
 |             started: Date.now(), | ||||||
| 
 |             interval: 10, | ||||||
|     it('should accept client metrics', (done) => { |         }) | ||||||
|         request |         .expect(400); | ||||||
|             .post('/api/client/metrics') | }); | ||||||
|             .send({  | 
 | ||||||
|                 appName: 'demo', | 
 | ||||||
|                 instanceId: '1', | test('should accept client metrics', () => { | ||||||
|                 bucket: { |     const { request } = getSetup(); | ||||||
|                     start: Date.now(), |     return request | ||||||
|                     stop: Date.now(), |         .post('/api/client/metrics') | ||||||
|                     toggles: {} |         .send({ | ||||||
|                 } |             appName: 'demo', | ||||||
|             }) |             instanceId: '1', | ||||||
|             .expect(202, done) |             bucket: { | ||||||
|     }); |                 start: Date.now(), | ||||||
|  |                 stop: Date.now(), | ||||||
|  |                 toggles: {}, | ||||||
|  |             }, | ||||||
|  |         }) | ||||||
|  |         .expect(202); | ||||||
| }); | }); | ||||||
|  | |||||||
| @ -1,6 +1,5 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| module.exports = { | module.exports = () => ({ | ||||||
|     reset: () => {}, |  | ||||||
|     insert: () => Promise.resolve(), |     insert: () => Promise.resolve(), | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,6 +1,5 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| module.exports = { | module.exports = () => ({ | ||||||
|     reset: () => {}, |  | ||||||
|     insert: () => Promise.resolve(), |     insert: () => Promise.resolve(), | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,11 +1,10 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| const _features = []; |  | ||||||
| 
 | 
 | ||||||
| module.exports = { | module.exports =  () => { | ||||||
|     getFeatures: () => Promise.resolve(_features), |     const _features = []; | ||||||
|     addFeature: (feature) => _features.push(feature), |     return { | ||||||
|     reset: () => { |         getFeatures: () => Promise.resolve(_features), | ||||||
|         _features.lengyh = 0; |         addFeature: (feature) => _features.push(feature), | ||||||
|     }, |     }; | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -1,7 +1,6 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| module.exports = { | module.exports = () => ({ | ||||||
|     reset: () => {}, |  | ||||||
|     getMetricsLastHour: () => Promise.resolve([]), |     getMetricsLastHour: () => Promise.resolve([]), | ||||||
|     insert: () => Promise.resolve(), |     insert: () => Promise.resolve(), | ||||||
| }; | }); | ||||||
|  | |||||||
| @ -1,12 +1,13 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| const _strategies = [{ name: 'default', parameters: {} }]; |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| module.exports = { | 
 | ||||||
|     getStrategies: () => Promise.resolve(_strategies), | module.exports = () => { | ||||||
|     addStrategy: (strat) => _strategies.push(strat), |     const _strategies = [{ name: 'default', parameters: {} }]; | ||||||
|     reset: () => { | 
 | ||||||
|         _strategies.length = 0; |     return { | ||||||
|     }, |         getStrategies: () => Promise.resolve(_strategies), | ||||||
|  |         addStrategy: (strat) => _strategies.push(strat), | ||||||
|  |     }; | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| const sinon = require('sinon'); | 'use strict'; | ||||||
| 
 | 
 | ||||||
| const clientMetricsStore = require('./fake-metrics-store'); | const clientMetricsStore = require('./fake-metrics-store'); | ||||||
| const clientStrategyStore = require('./fake-client-strategy-store'); | const clientStrategyStore = require('./fake-client-strategy-store'); | ||||||
| @ -11,27 +11,18 @@ const strategyStore = require('./fake-strategies-store'); | |||||||
| module.exports = { | module.exports = { | ||||||
|     createStores: () => { |     createStores: () => { | ||||||
|         const db = { |         const db = { | ||||||
|             select: () => { |             select: () => ({ | ||||||
|                 return { |                 from: () => Promise.resolve(), | ||||||
|                     from: () => Promise.resolve() |             }), | ||||||
|                 } |         }; | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         clientMetricsStore.reset(); |  | ||||||
|         clientStrategyStore.reset(); |  | ||||||
|         clientInstanceStore.reset(); |  | ||||||
|         featureToggleStore.reset(); |  | ||||||
|         strategyStore.reset(); |  | ||||||
| 
 | 
 | ||||||
|         return { |         return { | ||||||
|             db, |             db, | ||||||
|             clientMetricsStore, |             clientMetricsStore: clientMetricsStore(), | ||||||
|             clientStrategyStore, |             clientStrategyStore: clientStrategyStore(), | ||||||
|             clientInstanceStore, |             clientInstanceStore: clientInstanceStore(), | ||||||
|             featureToggleStore, |             featureToggleStore: featureToggleStore(), | ||||||
|             strategyStore, |             strategyStore: strategyStore(), | ||||||
|         } |         }; | ||||||
| 
 |     }, | ||||||
|     } | }; | ||||||
| }; |  | ||||||
|  | |||||||
| @ -1,35 +1,28 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
|  | const test = require('ava'); | ||||||
| const store = require('./mocks/store'); | const store = require('./mocks/store'); | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| const supertest = require('supertest'); | const supertest = require('supertest'); | ||||||
| const assert = require('assert'); | const logger = require('../../../lib/logger'); | ||||||
| const sinon = require('sinon'); |  | ||||||
| 
 | 
 | ||||||
| let request; | test.beforeEach(() =>  { | ||||||
| let strategyStore; |     logger.setLevel('FATAL'); | ||||||
| 
 | }); | ||||||
| describe('Unit: The strategies api', () => { | 
 | ||||||
|     beforeEach(done => { | test('should add version numbers for /stategies', t => { | ||||||
|        const stores = store.createStores();  |     const stores = store.createStores(); | ||||||
|         const app = require('../../../app')({ |     const app = require('../../../app')({ | ||||||
|             baseUriPath: '', |         baseUriPath: '', | ||||||
|             stores: stores, |         stores, | ||||||
|         }); |     }); | ||||||
|         strategyStore = stores.strategyStore; | 
 | ||||||
|         request = supertest(app); |     const request = supertest(app); | ||||||
|         done(); | 
 | ||||||
|     }); |     return request | ||||||
| 
 |         .get('/api/strategies') | ||||||
|     it('should add version numbers for /stategies', (done) => { |         .expect('Content-Type', /json/) | ||||||
|         request |         .expect(200) | ||||||
|             .get('/api/strategies') |         .expect((res) => { | ||||||
|             .expect('Content-Type', /json/) |             t.true(res.body.version === 1); | ||||||
|             .expect(200) |         }); | ||||||
|             .end((err, res) => { |  | ||||||
|                 assert.equal(res.body.version, 1); |  | ||||||
|                 done(); |  | ||||||
|             }); |  | ||||||
|     }); |  | ||||||
| }); | }); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user