1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-06 00:07:44 +01:00

Dropping bluebird as a runtime dependency.

Still use it in some test-setup, will cleanup this laster.

closes #128
This commit is contained in:
ivaosthu 2016-11-05 15:08:00 +01:00
parent 2810742055
commit bb5d11794d
6 changed files with 91 additions and 80 deletions

View File

@ -1,10 +1,9 @@
'use strict'; 'use strict';
const BPromise = require('bluebird');
const ValidationError = require('./validation-error'); const ValidationError = require('./validation-error');
function validateRequest (req) { function validateRequest (req) {
return new BPromise((resolve, reject) => { return new Promise((resolve, reject) => {
if (req.validationErrors()) { if (req.validationErrors()) {
reject(new ValidationError('Invalid syntax')); reject(new ValidationError('Invalid syntax'));
} else { } else {

View File

@ -5,6 +5,21 @@ const eventType = require('../event-type');
const ValidationError = require('../error/validation-error'); const ValidationError = require('../error/validation-error');
const validateRequest = require('../error/validate-request'); const validateRequest = require('../error/validate-request');
const handleErrors = (req, res, error) => {
switch (error.constructor) {
case ValidationError:
return res
.status(400)
.json(req.validationErrors())
.end();
default:
logger.error('Server failed executing request', error);
return res
.status(500)
.end();
}
};
module.exports = function (app, config) { module.exports = function (app, config) {
const { featureToggleStore, eventStore } = config.stores; const { featureToggleStore, eventStore } = config.stores;
@ -24,10 +39,6 @@ module.exports = function (app, config) {
data: req.body, data: req.body,
})) }))
.then(() => res.status(200).end()) .then(() => res.status(200).end())
.catch(ValidationError, () => res.status(400).json(req.validationErrors())) .catch(error => handleErrors(req, res, error));
.catch(err => {
logger.error('Could not revive feature toggle', err);
res.status(500).end();
});
}); });
}; };

View File

@ -1,6 +1,5 @@
'use strict'; 'use strict';
const BPromise = require('bluebird');
const logger = require('../logger'); const logger = require('../logger');
const eventType = require('../event-type'); const eventType = require('../event-type');
const NameExistsError = require('../error/name-exists-error'); const NameExistsError = require('../error/name-exists-error');
@ -12,6 +11,30 @@ const extractUser = require('../extract-user');
const legacyFeatureMapper = require('../helper/legacy-feature-mapper'); const legacyFeatureMapper = require('../helper/legacy-feature-mapper');
const version = 1; const version = 1;
const handleErrors = (req, res, error) => {
switch (error.constructor) {
case NotFoundError:
return res
.status(404)
.end();
case NameExistsError:
return res
.status(403)
.json([{ msg: `A feature named '${req.body.name}' already exists.` }])
.end();
case ValidationError:
return res
.status(400)
.json(req.validationErrors())
.end();
default:
logger.error('Server failed executing request', error);
return res
.status(500)
.end();
}
};
module.exports = function (app, config) { module.exports = function (app, config) {
const { featureToggleStore, eventStore } = config.stores; const { featureToggleStore, eventStore } = config.stores;
@ -36,16 +59,7 @@ module.exports = function (app, config) {
.then(validateFormat) .then(validateFormat)
.then(validateUniqueName) .then(validateUniqueName)
.then(() => res.status(201).end()) .then(() => res.status(201).end())
.catch(NameExistsError, () => { .catch(error => handleErrors(req, res, error));
res.status(403)
.json([{ msg: `A feature named '${req.body.name}' already exists.` }])
.end();
})
.catch(ValidationError, () => res.status(400).json(req.validationErrors()))
.catch(err => {
logger.error('Could not create feature toggle', err);
res.status(500).end();
});
}); });
app.post('/features', (req, res) => { app.post('/features', (req, res) => {
@ -61,16 +75,7 @@ module.exports = function (app, config) {
data: legacyFeatureMapper.toNewFormat(req.body), data: legacyFeatureMapper.toNewFormat(req.body),
})) }))
.then(() => res.status(201).end()) .then(() => res.status(201).end())
.catch(NameExistsError, () => { .catch(error => handleErrors(req, res, error));
res.status(403)
.json([{ msg: `A feature named '${req.body.name}' already exists.` }])
.end();
})
.catch(ValidationError, () => res.status(400).json(req.validationErrors()))
.catch(err => {
logger.error('Could not create feature toggle', err);
res.status(500).end();
});
}); });
app.put('/features/:featureName', (req, res) => { app.put('/features/:featureName', (req, res) => {
@ -87,11 +92,7 @@ module.exports = function (app, config) {
data: updatedFeature, data: updatedFeature,
})) }))
.then(() => res.status(200).end()) .then(() => res.status(200).end())
.catch(NotFoundError, () => res.status(404).end()) .catch(error => handleErrors(req, res, error));
.catch(err => {
logger.error(`Could not update feature toggle=${featureName}`, err);
res.status(500).end();
});
}); });
app.delete('/features/:featureName', (req, res) => { app.delete('/features/:featureName', (req, res) => {
@ -107,29 +108,22 @@ module.exports = function (app, config) {
}, },
})) }))
.then(() => res.status(200).end()) .then(() => res.status(200).end())
.catch(NotFoundError, () => res.status(404).end()) .catch(error => handleErrors(req, res, error));
.catch(err => {
logger.error(`Could not archive feature=${featureName}`, err);
res.status(500).end();
});
}); });
function validateUniqueName (req) { function validateUniqueName (req) {
return new BPromise((resolve, reject) => { return new Promise((resolve, reject) => {
featureToggleStore.getFeature(req.body.name) featureToggleStore.getFeature(req.body.name)
.then(() => { .then(() => reject(new NameExistsError('Feature name already exist')))
reject(new NameExistsError('Feature name already exist')); .catch(() => resolve(req));
}, () => {
resolve(req);
});
}); });
} }
function validateFormat (req) { function validateFormat (req) {
if (req.body.strategy && req.body.strategies) { if (req.body.strategy && req.body.strategies) {
return BPromise.reject(new ValidationError('Cannot use both "strategy" and "strategies".')); return Promise.reject(new ValidationError('Cannot use both "strategy" and "strategies".'));
} }
return BPromise.resolve(req); return Promise.resolve(req);
} }
}; };

View File

@ -1,6 +1,5 @@
'use strict'; 'use strict';
const BPromise = require('bluebird');
const eventType = require('../event-type'); const eventType = require('../event-type');
const logger = require('../logger'); const logger = require('../logger');
const NameExistsError = require('../error/name-exists-error'); const NameExistsError = require('../error/name-exists-error');
@ -10,6 +9,30 @@ const validateRequest = require('../error/validate-request');
const extractUser = require('../extract-user'); const extractUser = require('../extract-user');
const version = 1; const version = 1;
const handleError = (req, res, error) => {
switch (error.constructor) {
case NotFoundError:
return res
.status(404)
.end();
case NameExistsError:
return res
.status(403)
.json([{ msg: `A strategy named '${req.body.name}' already exists.` }])
.end();
case ValidationError:
return res
.status(400)
.json(req.validationErrors())
.end();
default:
logger.error('Could perfom operation', error);
return res
.status(500)
.end();
}
};
module.exports = function (app, config) { module.exports = function (app, config) {
const { strategyStore, eventStore } = config.stores; const { strategyStore, eventStore } = config.stores;
@ -21,12 +44,8 @@ module.exports = function (app, config) {
app.get('/strategies/:name', (req, res) => { app.get('/strategies/:name', (req, res) => {
strategyStore.getStrategy(req.params.name) strategyStore.getStrategy(req.params.name)
.then(strategy => { .then(strategy => res.json(strategy).end())
res.json(strategy); .catch(() => res.status(404).json({ error: 'Could not find strategy' }));
})
.catch(() => {
res.status(404).json({ error: 'Could not find strategy' });
});
}); });
app.delete('/strategies/:name', (req, res) => { app.delete('/strategies/:name', (req, res) => {
@ -40,16 +59,8 @@ module.exports = function (app, config) {
name: strategyName, name: strategyName,
}, },
})) }))
.then(() => { .then(() => res.status(200).end())
res.status(200).end(); .catch(error => handleError(req, res, error));
})
.catch(NotFoundError, () => {
res.status(404).end();
})
.catch(err => {
logger.error(`Could not delete strategy=${strategyName}`, err);
res.status(500).end();
});
}); });
app.post('/strategies', (req, res) => { app.post('/strategies', (req, res) => {
@ -66,26 +77,14 @@ module.exports = function (app, config) {
data: newStrategy, data: newStrategy,
})) }))
.then(() => res.status(201).end()) .then(() => res.status(201).end())
.catch(NameExistsError, () => { .catch(error => handleError(req, res, error));
res.status(403)
.json([{ msg: `A strategy named '${req.body.name}' already exists.` }])
.end();
})
.catch(ValidationError, () => res.status(400).json(req.validationErrors()))
.catch(err => {
logger.error('Could not create strategy', err);
res.status(500).end();
});
}); });
function validateStrategyName (req) { function validateStrategyName (req) {
return new BPromise((resolve, reject) => { return new Promise((resolve, reject) => {
strategyStore.getStrategy(req.body.name) strategyStore.getStrategy(req.body.name)
.then(() => { .then(() => reject(new NameExistsError('Feature name already exist')))
reject(new NameExistsError('Feature name already exist')); .catch(() => resolve(req));
}, () => {
resolve(req);
});
}); });
} }
}; };

View File

@ -47,7 +47,6 @@
"test:coverage-report": "cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage" "test:coverage-report": "cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage"
}, },
"dependencies": { "dependencies": {
"bluebird": "^3.4.6",
"body-parser": "1.15.2", "body-parser": "1.15.2",
"cookie-parser": "^1.4.1", "cookie-parser": "^1.4.1",
"db-migrate": "0.10.0-beta.17", "db-migrate": "0.10.0-beta.17",
@ -65,6 +64,7 @@
"yallist": "^2.0.0" "yallist": "^2.0.0"
}, },
"devDependencies": { "devDependencies": {
"bluebird": "^3.4.6",
"coveralls": "^2.11.12", "coveralls": "^2.11.12",
"istanbul": "^0.4.5", "istanbul": "^0.4.5",
"mocha": "^3.0.2", "mocha": "^3.0.2",

View File

@ -113,6 +113,14 @@ describe('The features api', () => {
.expect(403, done); .expect(403, done);
}); });
it('refuses to validate a feature with an existing name', done => {
request
.post('/features-validate')
.send({ name: 'featureX' })
.set('Content-Type', 'application/json')
.expect(403, done);
});
describe('new strategies api', () => { describe('new strategies api', () => {
it('automatically map existing strategy to strategies array', (done) => { it('automatically map existing strategy to strategies array', (done) => {
request request