mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-06 00:07:44 +01:00
Added version indicator to collection responses to ease migration of client parsers
relates to #102
This commit is contained in:
parent
de6ea81af8
commit
94e0e0ea98
@ -1,7 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
function addOldFields (feature) {
|
function addOldFields (feature) {
|
||||||
let modifiedFeature = Object.assign({}, feature);
|
const modifiedFeature = Object.assign({}, feature);
|
||||||
modifiedFeature.strategy = feature.strategies[0].name;
|
modifiedFeature.strategy = feature.strategies[0].name;
|
||||||
modifiedFeature.parameters = Object.assign({}, feature.strategies[0].parameters);
|
modifiedFeature.parameters = Object.assign({}, feature.strategies[0].parameters);
|
||||||
return modifiedFeature;
|
return modifiedFeature;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
const eventDiffer = require('../eventDiffer');
|
const eventDiffer = require('../eventDiffer');
|
||||||
|
const version = 1;
|
||||||
|
|
||||||
module.exports = function (app, config) {
|
module.exports = function (app, config) {
|
||||||
const eventDb = config.eventDb;
|
const eventDb = config.eventDb;
|
||||||
@ -7,7 +8,7 @@ module.exports = function (app, config) {
|
|||||||
app.get('/events', (req, res) => {
|
app.get('/events', (req, res) => {
|
||||||
eventDb.getEvents().then(events => {
|
eventDb.getEvents().then(events => {
|
||||||
eventDiffer.addDiffs(events);
|
eventDiffer.addDiffs(events);
|
||||||
res.json({ events });
|
res.json({ version, events });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ const validateRequest = require('../error/validateRequest');
|
|||||||
const extractUser = require('../extractUser');
|
const extractUser = require('../extractUser');
|
||||||
|
|
||||||
const legacyFeatureMapper = require('../helper/legacy-feature-mapper');
|
const legacyFeatureMapper = require('../helper/legacy-feature-mapper');
|
||||||
|
const version = 1;
|
||||||
|
|
||||||
module.exports = function (app, config) {
|
module.exports = function (app, config) {
|
||||||
const featureDb = config.featureDb;
|
const featureDb = config.featureDb;
|
||||||
@ -17,7 +18,7 @@ module.exports = function (app, config) {
|
|||||||
app.get('/features', (req, res) => {
|
app.get('/features', (req, res) => {
|
||||||
featureDb.getFeatures()
|
featureDb.getFeatures()
|
||||||
.then((features) => features.map(legacyFeatureMapper.addOldFields))
|
.then((features) => features.map(legacyFeatureMapper.addOldFields))
|
||||||
.then(features => res.json({ features }));
|
.then(features => res.json({ version, features }));
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/features/:featureName', (req, res) => {
|
app.get('/features/:featureName', (req, res) => {
|
||||||
|
@ -7,6 +7,7 @@ const ValidationError = require('../error/ValidationError');
|
|||||||
const NotFoundError = require('../error/NotFoundError');
|
const NotFoundError = require('../error/NotFoundError');
|
||||||
const validateRequest = require('../error/validateRequest');
|
const validateRequest = require('../error/validateRequest');
|
||||||
const extractUser = require('../extractUser');
|
const extractUser = require('../extractUser');
|
||||||
|
const version = 1;
|
||||||
|
|
||||||
module.exports = function (app, config) {
|
module.exports = function (app, config) {
|
||||||
const strategyDb = config.strategyDb;
|
const strategyDb = config.strategyDb;
|
||||||
@ -14,7 +15,7 @@ module.exports = function (app, config) {
|
|||||||
|
|
||||||
app.get('/strategies', (req, res) => {
|
app.get('/strategies', (req, res) => {
|
||||||
strategyDb.getStrategies().then(strategies => {
|
strategyDb.getStrategies().then(strategies => {
|
||||||
res.json({ strategies });
|
res.json({ version, strategies });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ GET: http://unleash.host.com/features
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
"version": 1,
|
||||||
"features": [
|
"features": [
|
||||||
{
|
{
|
||||||
"name": "Feature.A",
|
"name": "Feature.A",
|
||||||
@ -53,7 +54,9 @@ GET: http://unleash.host.com/features
|
|||||||
```
|
```
|
||||||
**Important:**
|
**Important:**
|
||||||
|
|
||||||
_strategy_ and _paramters_ are depercated fields and will go away in the next version. They are kept for backward compability with older unleash-clients.
|
_strategy_ and _paramters_ are deprecated fields and will go away in the next version, 2.
|
||||||
|
They are kept for backward compatibility with older unleash-clients. _version_ property indicates
|
||||||
|
the json-response version, making it easier for clients to parse the response.
|
||||||
|
|
||||||
|
|
||||||
## Fetch a feature
|
## Fetch a feature
|
||||||
@ -76,4 +79,5 @@ GET: http://unleash.host.com/features/[featureName]
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
_Notice that you will not get a version property when fetching a specific feature toggle by name_.
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
"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",
|
||||||
"test": "export PORT=4243 ; mocha test/**/*.js && npm run test:coverage",
|
"test": "export PORT=4243 ; mocha test/**/*.js && npm run test:coverage",
|
||||||
|
"test:unit": "mocha test/unit/**/*.js ",
|
||||||
"test:ci": "npm run db-migrate && npm run test",
|
"test:ci": "npm run db-migrate && npm run test",
|
||||||
"test:watch": "mocha --watch test test/*",
|
"test:watch": "mocha --watch test test/*",
|
||||||
"test:pg-virtualenv": "pg_virtualenv npm run test:pg-virtualenv-chai",
|
"test:pg-virtualenv": "pg_virtualenv npm run test:pg-virtualenv-chai",
|
||||||
|
@ -112,12 +112,12 @@ describe('The features api', () => {
|
|||||||
.expect(403, done);
|
.expect(403, done);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('new strategies api', function () {
|
describe('new strategies api', () => {
|
||||||
it('automatically map existing strategy to strategies array', function (done) {
|
it('automatically map existing strategy to strategies array', (done) => {
|
||||||
request
|
request
|
||||||
.get('/features/featureY')
|
.get('/features/featureY')
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.end(function (err, res) {
|
.end((err, res) => {
|
||||||
assert.equal(res.body.strategies.length, 1, 'expected strategy added to strategies');
|
assert.equal(res.body.strategies.length, 1, 'expected strategy added to strategies');
|
||||||
assert.equal(res.body.strategy, res.body.strategies[0].name);
|
assert.equal(res.body.strategy, res.body.strategies[0].name);
|
||||||
assert.deepEqual(res.body.parameters, res.body.strategies[0].parameters);
|
assert.deepEqual(res.body.parameters, res.body.strategies[0].parameters);
|
||||||
@ -125,7 +125,7 @@ describe('The features api', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can add two strategies to a feature toggle', function (done) {
|
it('can add two strategies to a feature toggle', (done) => {
|
||||||
request
|
request
|
||||||
.put('/features/featureY')
|
.put('/features/featureY')
|
||||||
.send({
|
.send({
|
||||||
@ -142,7 +142,7 @@ describe('The features api', () => {
|
|||||||
.expect(200, done);
|
.expect(200, done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not be allowed to post both strategy and strategies', function (done) {
|
it('should not be allowed to post both strategy and strategies', (done) => {
|
||||||
logger.setLevel('FATAL');
|
logger.setLevel('FATAL');
|
||||||
request
|
request
|
||||||
.post('/features')
|
.post('/features')
|
||||||
|
@ -16,7 +16,7 @@ describe('legacy-feature-mapper', () => {
|
|||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
|
|
||||||
let mappedFeature = mapper.addOldFields(feature);
|
const mappedFeature = mapper.addOldFields(feature);
|
||||||
|
|
||||||
assert.equal(mappedFeature.name, feature.name);
|
assert.equal(mappedFeature.name, feature.name);
|
||||||
assert.equal(mappedFeature.enabled, feature.enabled);
|
assert.equal(mappedFeature.enabled, feature.enabled);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
let supertest = require('supertest');
|
const supertest = require('supertest');
|
||||||
const BPromise = require('bluebird');
|
const BPromise = require('bluebird');
|
||||||
BPromise.promisifyAll(supertest);
|
BPromise.promisifyAll(supertest);
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
@ -18,7 +18,7 @@ describe('Unit: The features api', () => {
|
|||||||
db: sinon.stub(),
|
db: sinon.stub(),
|
||||||
eventDb: sinon.stub(),
|
eventDb: sinon.stub(),
|
||||||
eventStore: sinon.stub(),
|
eventStore: sinon.stub(),
|
||||||
featureDb: featureDb,
|
featureDb,
|
||||||
strategyDb: sinon.stub(),
|
strategyDb: sinon.stub(),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -49,10 +49,23 @@ describe('Unit: The features api', () => {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should add version numbers for /features', (done) => {
|
||||||
|
featureDb.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 createFeatureDb () {
|
function createFeatureDb () {
|
||||||
let _features = [];
|
const _features = [];
|
||||||
return {
|
return {
|
||||||
getFeatures: () => BPromise.resolve(_features),
|
getFeatures: () => BPromise.resolve(_features),
|
||||||
addFeature: (feature) => _features.push(feature),
|
addFeature: (feature) => _features.push(feature),
|
||||||
|
47
packages/unleash-api/test/unit/routes/strategies.test.js
Normal file
47
packages/unleash-api/test/unit/routes/strategies.test.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const supertest = require('supertest');
|
||||||
|
const BPromise = require('bluebird');
|
||||||
|
BPromise.promisifyAll(supertest);
|
||||||
|
const assert = require('assert');
|
||||||
|
const sinon = require('sinon');
|
||||||
|
|
||||||
|
let request;
|
||||||
|
let stratDb;
|
||||||
|
|
||||||
|
describe('Unit: The strategies api', () => {
|
||||||
|
beforeEach(done => {
|
||||||
|
stratDb = createStrategyDb();
|
||||||
|
|
||||||
|
const app = require('../../../app')({
|
||||||
|
baseUriPath: '',
|
||||||
|
db: sinon.stub(),
|
||||||
|
eventDb: sinon.stub(),
|
||||||
|
eventStore: sinon.stub(),
|
||||||
|
featureDb: sinon.stub(),
|
||||||
|
strategyDb: stratDb,
|
||||||
|
});
|
||||||
|
|
||||||
|
request = supertest(app);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add version numbers for /stategies', (done) => {
|
||||||
|
request
|
||||||
|
.get('/strategies')
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(200)
|
||||||
|
.end((err, res) => {
|
||||||
|
assert.equal(res.body.version, 1);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function createStrategyDb () {
|
||||||
|
const _strategies = [{ name: 'default', parameters: {} }];
|
||||||
|
return {
|
||||||
|
getStrategies: () => BPromise.resolve(_strategies),
|
||||||
|
addStrategy: (strat) => _strategies.push(strat),
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user