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:
commit
6afd180a2e
@ -1,5 +1,6 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
featureCreated : 'feature-created',
|
featureCreated : 'feature-created',
|
||||||
featureUpdated : 'feature-updated',
|
featureUpdated : 'feature-updated',
|
||||||
strategyCreated: 'strategy-created'
|
strategyCreated: 'strategy-created',
|
||||||
|
strategyDeleted: 'strategy-deleted'
|
||||||
};
|
};
|
@ -16,6 +16,18 @@ module.exports = function (app) {
|
|||||||
.catch(function () { res.json(404, {error: 'Could not find strategy'}); });
|
.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) {
|
app.post('/strategies', function (req, res) {
|
||||||
req.checkBody('name', 'Name is required').notEmpty();
|
req.checkBody('name', 'Name is required').notEmpty();
|
||||||
req.checkBody('name', 'Name must match format ^[a-zA-Z\\.\\-]+$').matches(/^[a-zA-Z\\.\\-]+$/i);
|
req.checkBody('name', 'Name must match format ^[a-zA-Z\\.\\-]+$').matches(/^[a-zA-Z\\.\\-]+$/i);
|
||||||
|
@ -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() {
|
function getStrategies() {
|
||||||
return knex
|
return knex
|
||||||
.select(STRATEGY_COLUMNS)
|
.select(STRATEGY_COLUMNS)
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/** @jsx React.DOM */
|
/** @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 React = require("react/addons");
|
||||||
var TestUtils = React.addons.TestUtils;
|
var TestUtils = React.addons.TestUtils;
|
||||||
|
|
47
public/js/__tests__/components/feature/FeatureForm-test.js
Normal file
47
public/js/__tests__/components/feature/FeatureForm-test.js
Normal 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)");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@ -1,5 +1,5 @@
|
|||||||
var React = require('react');
|
var React = require('react');
|
||||||
var TextInput = require('../form/TextInput');
|
var TextInput = require('../form/TextInput');
|
||||||
var strategyStore = require('../../stores/StrategyStore');
|
var strategyStore = require('../../stores/StrategyStore');
|
||||||
|
|
||||||
var FeatureForm = React.createClass({
|
var FeatureForm = React.createClass({
|
||||||
@ -36,20 +36,30 @@ var FeatureForm = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
setSelectedStrategy: function(name) {
|
setSelectedStrategy: function(name) {
|
||||||
var selected = this.state.strategyOptions.filter(function(strategy) {
|
var selectedStrategy = this.state.strategyOptions.filter(function(strategy) {
|
||||||
return strategy.name === name;
|
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 requiredParams = [];
|
||||||
var key;
|
var key;
|
||||||
|
for(key in strategy.parametersTemplate) {
|
||||||
if(selected[0] && selected[0].parametersTemplate) {
|
requiredParams.push({name: key, value: this.getParameterValue(key)});
|
||||||
for(key in selected[0].parametersTemplate) {
|
|
||||||
requiredParams.push({name: key, value: this.getParameterValue(key)});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this.setState({requiredParams: requiredParams});
|
this.setState({requiredParams: requiredParams});
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
|
@ -14,9 +14,16 @@ var StrategiesComponent = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
componentDidMount: function () {
|
componentDidMount: function () {
|
||||||
strategyStore.getStrategies().then(function(res) {
|
this.fetchStrategies();
|
||||||
this.setState({strategies: res.strategies});
|
},
|
||||||
}.bind(this), this.initError);
|
|
||||||
|
fetchStrategies: function(res) {
|
||||||
|
strategyStore.getStrategies()
|
||||||
|
.then(function(res) {
|
||||||
|
this.setState({strategies: res.strategies})
|
||||||
|
}.bind(this))
|
||||||
|
.catch(this.initError);
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
initError: function() {
|
initError: function() {
|
||||||
@ -57,6 +64,12 @@ var StrategiesComponent = React.createClass({
|
|||||||
.catch(this.onError);
|
.catch(this.onError);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onRemove: function(strategy) {
|
||||||
|
strategyStore.removeStrategy(strategy)
|
||||||
|
.then(this.fetchStrategies)
|
||||||
|
.catch(this.onError);
|
||||||
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@ -66,7 +79,7 @@ var StrategiesComponent = React.createClass({
|
|||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<StrategyList strategies={this.state.strategies} />
|
<StrategyList strategies={this.state.strategies} onRemove={this.onRemove} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -5,12 +5,20 @@ var Strategy = React.createClass({
|
|||||||
strategy: React.PropTypes.object.isRequired
|
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() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<div className="line mal">
|
<div className="line mal">
|
||||||
<div className="unit">
|
<div className="unit">
|
||||||
<strong>{this.props.strategy.name}</strong><br />
|
<strong>{this.props.strategy.name} </strong>
|
||||||
<em>{this.props.strategy.description}</em>
|
<a href="" title="Delete strategy" onClick={this.onRemove}>(remove)</a><br />
|
||||||
|
<em>{this.props.strategy.description}</em><br />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -8,8 +8,8 @@ var StrategyList = React.createClass({
|
|||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var strategyNodes = this.props.strategies.map(function(strategy) {
|
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 (
|
return (
|
||||||
<div>{strategyNodes}</div>
|
<div>{strategyNodes}</div>
|
||||||
);
|
);
|
||||||
|
@ -14,6 +14,14 @@ var StrategyStore = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
removeStrategy: function (strategy) {
|
||||||
|
return reqwest({
|
||||||
|
url: 'strategies/'+strategy.name,
|
||||||
|
method: 'delete',
|
||||||
|
type: TYPE
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
getStrategies: function () {
|
getStrategies: function () {
|
||||||
return reqwest({
|
return reqwest({
|
||||||
url: 'strategies',
|
url: 'strategies',
|
||||||
|
@ -44,5 +44,9 @@ describe('The strategy api', function () {
|
|||||||
.expect(403, done);
|
.expect(403, done);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('deletes a new strategy', function (done) {
|
||||||
|
request
|
||||||
|
.delete('/strategies/deletable')
|
||||||
|
.expect(200, done);
|
||||||
|
});
|
||||||
});
|
});
|
@ -11,6 +11,10 @@ var strategies = [
|
|||||||
parametersTemplate: {
|
parametersTemplate: {
|
||||||
emails: "String"
|
emails: "String"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "deletable",
|
||||||
|
description: "deletable"
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user