1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-02-04 00:18:01 +01:00

Add ability to create custom stratgies. Closes #11.

This commit is contained in:
Jari Bakken 2014-11-25 15:28:08 +01:00
parent d89ce75906
commit 20c4fe6702
9 changed files with 117 additions and 56 deletions

View File

@ -1,6 +1,6 @@
var eventStore = require('./eventStore'), var eventStore = require('./eventStore');
eventType = require('./eventType'), var eventType = require('./eventType');
featureDb = require('./featureDb'); var featureDb = require('./featureDb');
module.exports = function (app) { module.exports = function (app) {
@ -44,11 +44,9 @@ module.exports = function (app) {
type: eventType.featureCreated, type: eventType.featureCreated,
createdBy: req.connection.remoteAddress, createdBy: req.connection.remoteAddress,
data: newFeature data: newFeature
}).then(function () { })
res.status(201).end(); .then(function () { res.status(201).end(); })
}, function () { .catch(function () { res.status(500).end(); });
res.status(500).end();
});
}; };
featureDb.getFeature(newFeature.name) featureDb.getFeature(newFeature.name)

View File

@ -1,25 +1,7 @@
var eventStore = require('./eventStore');
var eventType = require('./eventType');
var strategyDb = require('./strategyDb'); var strategyDb = require('./strategyDb');
var strategies = [
{
name: "default",
description: "Default on or off Strategy."
},
{
name: "usersWithEmail",
description: "Active for users defined in the comma-separated emails-parameter.",
parametersTemplate: {
emails: "String"
}
}
];
function byName(name) {
return strategies.filter(function(s) {
return s.name === name;
})[0];
}
module.exports = function (app) { module.exports = function (app) {
app.get('/strategies', function (req, res) { app.get('/strategies', function (req, res) {
@ -29,16 +11,42 @@ module.exports = function (app) {
}); });
app.get('/strategies/:name', function (req, res) { app.get('/strategies/:name', function (req, res) {
var strategy = byName(req.params.name); strategyDb.getStrategy(req.params.name)
if (strategy) { .then(function (strategy) { res.json(strategy); })
res.json(strategy); .catch(function () { res.json(404, {error: 'Could not find strategy'}); });
} else {
res.json(404, {error: 'Could not find strategy'});
}
}); });
app.post('/strategies', function (req, res) { app.post('/strategies', function (req, res) {
res.json(500, {error: 'Not implemented yet'}); req.checkBody('name', 'Name is required').notEmpty();
req.checkBody('name', 'Name must match format ^[a-zA-Z\\.\\-]+$').matches(/^[a-zA-Z\\.\\-]+$/i);
var errors = req.validationErrors();
if (errors) {
res.status(400).json(errors);
return;
}
var newStrategy = req.body;
var handleStrategyExists = function() {
var errors = [{msg: "A strategy named " + newStrategy.name + " already exists."}];
res.status(403).json(errors);
};
var handleCreateStrategy = function() {
eventStore.create({
type: eventType.strategyCreated,
createdBy: req.connection.remoteAddress,
data: newStrategy
})
.then(function () { res.status(201).end(); })
.catch(function () { res.status(500).end(); });
};
strategyDb.getStrategy(newStrategy.name)
.then(handleStrategyExists)
.catch(handleCreateStrategy);
}); });
}; };

View File

@ -41,12 +41,20 @@ var StrategiesComponent = React.createClass({
}, },
onSave: function(strategy) { onSave: function(strategy) {
var strategies = this.state.strategies.concat([strategy]); function handleSuccess() {
this.setState({ var strategies = this.state.strategies.concat([strategy]);
createView: false,
strategies: strategies this.setState({
}); createView: false,
console.log("Saved strategy: ", strategy); strategies: strategies
});
console.log("Saved strategy: ", strategy);
}
strategyStore.createStrategy(strategy)
.then(handleSuccess.bind(this))
.catch(this.onError);
}, },
render: function() { render: function() {

View File

@ -1,7 +1,7 @@
var reqwest = require('reqwest'); var reqwest = require('reqwest');
TYPE = 'json'; var TYPE = 'json';
CONTENT_TYPE = 'application/json'; var CONTENT_TYPE = 'application/json';
var EventStore = { var EventStore = {
getEvents: function () { getEvents: function () {

View File

@ -3,16 +3,16 @@ var reqwest = require('reqwest');
var FeatureStore = function () { var FeatureStore = function () {
}; };
FeatureStore.TYPE = 'json'; var TYPE = 'json';
FeatureStore.CONTENT_TYPE = 'application/json'; var CONTENT_TYPE = 'application/json';
FeatureStore.prototype = { FeatureStore.prototype = {
updateFeature: function (feature) { updateFeature: function (feature) {
return reqwest({ return reqwest({
url: 'features/' + feature.name, url: 'features/' + feature.name,
method: 'put', method: 'put',
type: FeatureStore.TYPE, type: TYPE,
contentType: FeatureStore.CONTENT_TYPE, contentType: CONTENT_TYPE,
data: JSON.stringify(feature) data: JSON.stringify(feature)
}); });
}, },
@ -21,8 +21,8 @@ FeatureStore.prototype = {
return reqwest({ return reqwest({
url: 'features', url: 'features',
method: 'post', method: 'post',
type: FeatureStore.TYPE, type: TYPE,
contentType: FeatureStore.CONTENT_TYPE, contentType: CONTENT_TYPE,
data: JSON.stringify(feature) data: JSON.stringify(feature)
}); });
}, },
@ -31,7 +31,7 @@ FeatureStore.prototype = {
return reqwest({ return reqwest({
url: 'features', url: 'features',
method: 'get', method: 'get',
type: FeatureStore.TYPE type: TYPE
}); });
} }
}; };

View File

@ -1,7 +1,7 @@
var reqwest = require('reqwest'); var reqwest = require('reqwest');
TYPE = 'json'; var TYPE = 'json';
CONTENT_TYPE = 'application/json'; var CONTENT_TYPE = 'application/json';
var StrategyStore = { var StrategyStore = {
createStrategy: function (strategy) { createStrategy: function (strategy) {

View File

@ -13,6 +13,13 @@ describe('The features api', function () {
.expect(200, done); .expect(200, done);
}); });
it('gets a feature by name', function (done) {
request
.get('/features/featureX')
.expect('Content-Type', /json/)
.expect(200, done);
});
it('creates new feature toggle', function (done) { it('creates new feature toggle', function (done) {
request request
.post('/features') .post('/features')

40
test/strategyApiSpec.js Normal file
View File

@ -0,0 +1,40 @@
var specHelper = require('./specHelper');
describe('The strategy api', function () {
var request;
before(function () { request = specHelper.setupMockServer(); });
after(specHelper.tearDownMockServer);
it('gets all strategies', function (done) {
request
.get('/strategies')
.expect('Content-Type', /json/)
.expect(200, done);
});
it('gets a strategy by name', function (done) {
request
.get('/strategies/default')
.expect('Content-Type', /json/)
.expect(200, done);
});
it('creates a new strategy', function (done) {
request
.post('/strategies')
.send({name: 'myCustomStrategy', description: 'Best strategy ever.'})
.set('Content-Type', 'application/json')
.expect(201, done);
});
it('requires new strategies to have a name', function (done) {
request
.post('/strategies')
.send({name: ''})
.set('Content-Type', 'application/json')
.expect(400, done);
});
});

View File

@ -26,10 +26,10 @@ module.exports = {
resolve(strategies); resolve(strategies);
}); });
}, },
getFeature: function(name) { getStrategy: function(name) {
var feature = byName(name); var strategy = byName(name);
if(feature) { if(strategy) {
return Promise.resolve(feature); return Promise.resolve(strategy);
} else { } else {
return Promise.reject("strategy not found"); return Promise.reject("strategy not found");
} }