1
0
mirror of https://github.com/Unleash/unleash.git synced 2024-12-28 00:06:53 +01:00

Merge branch 'master' into add-sdk-version

This commit is contained in:
Ivar Conradi Østhus 2017-06-29 09:57:55 +02:00 committed by GitHub
commit 98b0ce39a4
6 changed files with 91 additions and 33 deletions

View File

@ -2,6 +2,7 @@
## [Unreleased] ## [Unreleased]
- Add sdkVersion in client registration - Add sdkVersion in client registration
- disable edit of built-in strategies
## 3.0.0-alpha.1 ## 3.0.0-alpha.1
- upgrade unleash-frontend to 3.0.0-alpha.1 - upgrade unleash-frontend to 3.0.0-alpha.1

View File

@ -7,7 +7,7 @@ const {
} = require('../event-type'); } = require('../event-type');
const logger = require('../logger'); const logger = require('../logger');
const NotFoundError = require('../error/notfound-error'); const NotFoundError = require('../error/notfound-error');
const STRATEGY_COLUMNS = ['name', 'description', 'parameters']; const STRATEGY_COLUMNS = ['name', 'description', 'parameters', 'built_in'];
const TABLE = 'strategies'; const TABLE = 'strategies';
class StrategyStore { class StrategyStore {
@ -46,9 +46,9 @@ class StrategyStore {
if (!row) { if (!row) {
throw new NotFoundError('No strategy found'); throw new NotFoundError('No strategy found');
} }
return { return {
name: row.name, name: row.name,
editable: row.built_in !== 1,
description: row.description, description: row.description,
parameters: row.parameters, parameters: row.parameters,
}; };

View File

@ -4,6 +4,7 @@ const joi = require('joi');
const strategySchema = joi.object().keys({ const strategySchema = joi.object().keys({
name: joi.string().regex(/^[a-zA-Z0-9\\.\\-]{3,100}$/).required(), name: joi.string().regex(/^[a-zA-Z0-9\\.\\-]{3,100}$/).required(),
editable: joi.boolean().default(true),
description: joi.string(), description: joi.string(),
parameters: joi.array().required().items( parameters: joi.array().required().items(
joi.object().keys({ joi.object().keys({

View File

@ -33,6 +33,28 @@ const handleError = (req, res, error) => {
} }
}; };
function validateEditable(strategyName) {
return strategy => {
if (strategy.editable === false) {
throw new Error(
`Cannot edit strategy ${strategyName}, editable is false`
);
}
return strategy;
};
}
function validateInput(data) {
return new Promise((resolve, reject) => {
joi.validate(data, strategySchema, (err, cleaned) => {
if (err) {
return reject(err);
}
return resolve(cleaned);
});
});
}
exports.router = function(config) { exports.router = function(config) {
const { strategyStore, eventStore } = config.stores; const { strategyStore, eventStore } = config.stores;
const router = Router(); const router = Router();
@ -57,6 +79,7 @@ exports.router = function(config) {
strategyStore strategyStore
.getStrategy(strategyName) .getStrategy(strategyName)
.then(validateEditable(strategyName))
.then(() => .then(() =>
eventStore.store({ eventStore.store({
type: eventType.STRATEGY_DELETED, type: eventType.STRATEGY_DELETED,
@ -70,6 +93,17 @@ exports.router = function(config) {
.catch(error => handleError(req, res, error)); .catch(error => handleError(req, res, error));
}); });
function validateStrategyName(data) {
return new Promise((resolve, reject) => {
strategyStore
.getStrategy(data.name)
.then(() =>
reject(new NameExistsError('Feature name already exist'))
)
.catch(() => resolve(data));
});
}
router.post('/', (req, res) => { router.post('/', (req, res) => {
const data = req.body; const data = req.body;
validateInput(data) validateInput(data)
@ -93,6 +127,7 @@ exports.router = function(config) {
strategyStore strategyStore
.getStrategy(strategyName) .getStrategy(strategyName)
.then(validateEditable(strategyName))
.then(() => validateInput(updatedStrategy)) .then(() => validateInput(updatedStrategy))
.then(() => .then(() =>
eventStore.store({ eventStore.store({
@ -105,27 +140,5 @@ exports.router = function(config) {
.catch(error => handleError(req, res, error)); .catch(error => handleError(req, res, error));
}); });
function validateStrategyName(data) {
return new Promise((resolve, reject) => {
strategyStore
.getStrategy(data.name)
.then(() =>
reject(new NameExistsError('Feature name already exist'))
)
.catch(() => resolve(data));
});
}
function validateInput(data) {
return new Promise((resolve, reject) => {
joi.validate(data, strategySchema, (err, cleaned) => {
if (err) {
return reject(err);
}
return resolve(cleaned);
});
});
}
return router; return router;
}; };

View File

@ -29,7 +29,7 @@ test.beforeEach(() => {
logger.setLevel('FATAL'); logger.setLevel('FATAL');
}); });
test('should add version numbers for /stategies', t => { test('add version numbers for /stategies', t => {
t.plan(1); t.plan(1);
const { request, base } = getSetup(); const { request, base } = getSetup();
@ -42,7 +42,7 @@ test('should add version numbers for /stategies', t => {
}); });
}); });
test('should require a name when creating a new stratey', t => { test('require a name when creating a new stratey', t => {
t.plan(1); t.plan(1);
const { request, base } = getSetup(); const { request, base } = getSetup();
@ -55,7 +55,7 @@ test('should require a name when creating a new stratey', t => {
}); });
}); });
test('should require parameters array when creating a new stratey', t => { test('require parameters array when creating a new stratey', t => {
t.plan(1); t.plan(1);
const { request, base } = getSetup(); const { request, base } = getSetup();
@ -68,7 +68,7 @@ test('should require parameters array when creating a new stratey', t => {
}); });
}); });
test('should create a new stratey with empty parameters', t => { test('create a new stratey with empty parameters', t => {
t.plan(0); t.plan(0);
const { request, base } = getSetup(); const { request, base } = getSetup();
@ -78,7 +78,7 @@ test('should create a new stratey with empty parameters', t => {
.expect(201); .expect(201);
}); });
test('should not be possible to override name', t => { test('not be possible to override name', t => {
t.plan(0); t.plan(0);
const { request, base, strategyStore } = getSetup(); const { request, base, strategyStore } = getSetup();
strategyStore.addStrategy({ name: 'Testing', parameters: [] }); strategyStore.addStrategy({ name: 'Testing', parameters: [] });
@ -89,7 +89,7 @@ test('should not be possible to override name', t => {
.expect(403); .expect(403);
}); });
test('should update strategy', t => { test('update strategy', t => {
t.plan(0); t.plan(0);
const name = 'AnotherStrat'; const name = 'AnotherStrat';
const { request, base, strategyStore } = getSetup(); const { request, base, strategyStore } = getSetup();
@ -101,7 +101,7 @@ test('should update strategy', t => {
.expect(200); .expect(200);
}); });
test('should not update uknown strategy', t => { test('not update uknown strategy', t => {
t.plan(0); t.plan(0);
const name = 'UnknownStrat'; const name = 'UnknownStrat';
const { request, base } = getSetup(); const { request, base } = getSetup();
@ -112,7 +112,7 @@ test('should not update uknown strategy', t => {
.expect(404); .expect(404);
}); });
test('should validate format when updating strategy', t => { test('validate format when updating strategy', t => {
t.plan(0); t.plan(0);
const name = 'AnotherStrat'; const name = 'AnotherStrat';
const { request, base, strategyStore } = getSetup(); const { request, base, strategyStore } = getSetup();
@ -123,3 +123,46 @@ test('should validate format when updating strategy', t => {
.send({}) .send({})
.expect(400); .expect(400);
}); });
test('editable=false will stop delete request', t => {
t.plan(0);
const name = 'default';
const { request, base } = getSetup();
return request.delete(`${base}/api/admin/strategies/${name}`).expect(500);
});
test('editable=false will stop edit request', t => {
t.plan(0);
const name = 'default';
const { request, base } = getSetup();
return request
.put(`${base}/api/admin/strategies/${name}`)
.send({ name, parameters: [] })
.expect(500);
});
test('editable=true will allow delete request', t => {
t.plan(0);
const name = 'deleteStrat';
const { request, base, strategyStore } = getSetup();
strategyStore.addStrategy({ name, parameters: [] });
return request
.delete(`${base}/api/admin/strategies/${name}`)
.send({})
.expect(200);
});
test('editable=true will allow edit request', t => {
t.plan(0);
const name = 'editStrat';
const { request, base, strategyStore } = getSetup();
strategyStore.addStrategy({ name, parameters: [] });
return request
.put(`${base}/api/admin/strategies/${name}`)
.send({ name, parameters: [] })
.expect(200);
});

View File

@ -3,7 +3,7 @@
const NotFoundError = require('../../lib/error/notfound-error'); const NotFoundError = require('../../lib/error/notfound-error');
module.exports = () => { module.exports = () => {
const _strategies = [{ name: 'default', parameters: {} }]; const _strategies = [{ name: 'default', editable: false, parameters: {} }];
return { return {
getStrategies: () => Promise.resolve(_strategies), getStrategies: () => Promise.resolve(_strategies),