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

Merge pull request #67 from finn-no/remove_strategies

Remove strategies
This commit is contained in:
Ivar Conradi Østhus 2014-12-09 15:40:09 +01:00
commit 6afd180a2e
12 changed files with 137 additions and 21 deletions

View File

@ -1,5 +1,6 @@
module.exports = {
featureCreated : 'feature-created',
featureUpdated : 'feature-updated',
strategyCreated: 'strategy-created'
strategyCreated: 'strategy-created',
strategyDeleted: 'strategy-deleted'
};

View File

@ -16,6 +16,18 @@ module.exports = function (app) {
.catch(function () { res.json(404, {error: 'Could not find strategy'}); });
});
app.delete('/strategies/:name', function (req, res) {
eventStore.create({
type: eventType.strategyDeleted,
createdBy: req.connection.remoteAddress,
data: {
name: req.params.name
}
})
.then(function () { res.status(200).end(); })
.catch(function () { res.status(500).end(); });
});
app.post('/strategies', function (req, res) {
req.checkBody('name', 'Name is required').notEmpty();
req.checkBody('name', 'Name must match format ^[a-zA-Z\\.\\-]+$').matches(/^[a-zA-Z\\.\\-]+$/i);

View File

@ -12,6 +12,15 @@ eventStore.on(eventType.strategyCreated, function (event) {
});
});
eventStore.on(eventType.strategyDeleted, function (event) {
knex('strategies')
.where('name', event.data.name)
.del()
.catch(function (err) {
logger.error('Could not delete strategy, error was: ', err);
});
});
function getStrategies() {
return knex
.select(STRATEGY_COLUMNS)

View File

@ -1,8 +1,8 @@
/** @jsx React.DOM */
jest.dontMock("../components/Menu");
jest.dontMock("../../components/Menu");
var Menu = require("../components/Menu");
var Menu = require("../../components/Menu");
var React = require("react/addons");
var TestUtils = React.addons.TestUtils;

View File

@ -0,0 +1,47 @@
jest.dontMock("../../../components/feature/FeatureForm");
var React = require("react/addons");
var TestUtils = React.addons.TestUtils;
var FeatureForm = require("../../../components/feature/FeatureForm");
var strategyStore = require("../../../stores/StrategyStore");
describe("FeatureForm", function () {
var Component;
beforeEach(function() {
strategyStore.getStrategies.mockImplementation(function() {
return {
then: function (callback) {
return callback({
strategies: [
{ name: "default"}
]
});
}
};
});
});
afterEach(function() {
React.unmountComponentAtNode(document.body);
});
describe("new", function () {
it("should render empty form", function() {
Component = TestUtils .renderIntoDocument(<FeatureForm />);
var name = Component.getDOMNode().querySelectorAll("input");
expect(name[0].value).toEqual(undefined);
});
});
describe("edit", function () {
var feature = {name: "Test", strategy: "unknown"};
it("should show unknown strategy as deleted", function () {
Component = TestUtils .renderIntoDocument(<FeatureForm feature={feature} />);
var strategySelect = Component.getDOMNode().querySelector("select");
expect(strategySelect.value).toEqual("unknown (deleted)");
});
});
});

View File

@ -1,5 +1,5 @@
var React = require('react');
var TextInput = require('../form/TextInput');
var TextInput = require('../form/TextInput');
var strategyStore = require('../../stores/StrategyStore');
var FeatureForm = React.createClass({
@ -36,20 +36,30 @@ var FeatureForm = React.createClass({
},
setSelectedStrategy: function(name) {
var selected = this.state.strategyOptions.filter(function(strategy) {
var selectedStrategy = this.state.strategyOptions.filter(function(strategy) {
return strategy.name === name;
});
})[0];
if(selectedStrategy) {
if(selectedStrategy.parametersTemplate) {
this.setStrategyParams(selectedStrategy);
}
} else {
var updatedStrategyName = name + " (deleted)";
this.setState({
currentStrategy: updatedStrategyName,
strategyOptions: this.state.strategyOptions.concat([{name: updatedStrategyName}])
});
}
},
setStrategyParams: function(strategy) {
var requiredParams = [];
var key;
if(selected[0] && selected[0].parametersTemplate) {
for(key in selected[0].parametersTemplate) {
requiredParams.push({name: key, value: this.getParameterValue(key)});
}
for(key in strategy.parametersTemplate) {
requiredParams.push({name: key, value: this.getParameterValue(key)});
}
this.setState({requiredParams: requiredParams});
},
render: function() {

View File

@ -14,9 +14,16 @@ var StrategiesComponent = React.createClass({
},
componentDidMount: function () {
strategyStore.getStrategies().then(function(res) {
this.setState({strategies: res.strategies});
}.bind(this), this.initError);
this.fetchStrategies();
},
fetchStrategies: function(res) {
strategyStore.getStrategies()
.then(function(res) {
this.setState({strategies: res.strategies})
}.bind(this))
.catch(this.initError);
},
initError: function() {
@ -57,6 +64,12 @@ var StrategiesComponent = React.createClass({
.catch(this.onError);
},
onRemove: function(strategy) {
strategyStore.removeStrategy(strategy)
.then(this.fetchStrategies)
.catch(this.onError);
},
render: function() {
return (
<div>
@ -66,7 +79,7 @@ var StrategiesComponent = React.createClass({
<hr />
<StrategyList strategies={this.state.strategies} />
<StrategyList strategies={this.state.strategies} onRemove={this.onRemove} />
</div>
);
},

View File

@ -5,12 +5,20 @@ var Strategy = React.createClass({
strategy: React.PropTypes.object.isRequired
},
onRemove: function(event) {
event.preventDefault();
if (confirm("Are you sure you want to delete strategy '"+this.props.strategy.name+"'?")) {
this.props.onRemove(this.props.strategy);
}
},
render: function() {
return (
<div className="line mal">
<div className="unit">
<strong>{this.props.strategy.name}</strong><br />
<em>{this.props.strategy.description}</em>
<strong>{this.props.strategy.name} </strong>
<a href="" title="Delete strategy" onClick={this.onRemove}>(remove)</a><br />
<em>{this.props.strategy.description}</em><br />
</div>
</div>
);

View File

@ -8,8 +8,8 @@ var StrategyList = React.createClass({
render: function() {
var strategyNodes = this.props.strategies.map(function(strategy) {
return <Strategy strategy={strategy} key={strategy.name} />;
});
return <Strategy strategy={strategy} key={strategy.name} onRemove={this.props.onRemove} />;
}.bind(this));
return (
<div>{strategyNodes}</div>
);

View File

@ -14,6 +14,14 @@ var StrategyStore = {
});
},
removeStrategy: function (strategy) {
return reqwest({
url: 'strategies/'+strategy.name,
method: 'delete',
type: TYPE
});
},
getStrategies: function () {
return reqwest({
url: 'strategies',

View File

@ -44,5 +44,9 @@ describe('The strategy api', function () {
.expect(403, done);
});
it('deletes a new strategy', function (done) {
request
.delete('/strategies/deletable')
.expect(200, done);
});
});

View File

@ -11,6 +11,10 @@ var strategies = [
parametersTemplate: {
emails: "String"
}
},
{
name: "deletable",
description: "deletable"
}
];