mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
Begin work on running tests against the database:
* Add Travis postgresql setup. * Replace "db mocks" with a before hook that creates the same data through the HTTP API. * Reset DB and re-create all fixtures for each test. We'll need something better here. * CAVEAT: no concept of a dev vs test database. Running tests will clear data from the currently configured database.
This commit is contained in:
parent
f48b89ff87
commit
e52c1d16fe
@ -1,8 +1,11 @@
|
|||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
- "0.10"
|
- "0.10"
|
||||||
|
env: DATABASE_URL=postgres://postgres@localhost:5432/unleash_test
|
||||||
before_script:
|
before_script:
|
||||||
- echo '--timeout 10000' > test/mocha.opts
|
- echo '--timeout 10000' > test/mocha.opts
|
||||||
|
- psql -c 'create database unleash_test;' -U postgres
|
||||||
|
- ./node_modules/.bin/db-migrate up
|
||||||
script:
|
script:
|
||||||
- npm install
|
- npm install
|
||||||
- npm test
|
- npm test
|
||||||
@ -11,3 +14,5 @@ notifications:
|
|||||||
hipchat:
|
hipchat:
|
||||||
rooms:
|
rooms:
|
||||||
secure: GiIDk52xccnUKnevjLE+w6eUXg0jfV7oOmagw5VnOV5jXGUxdzMk/Q9um+oSClEPE51IvF76zoFEKPIX/CNdjgalEr+CZADy1gene/YRGrNgrXmYYmiU1/dNzelpla1WpKPrY2pkbOgKxrCR9ScID+pMs6vzvJnPwK9vu66W61U=
|
secure: GiIDk52xccnUKnevjLE+w6eUXg0jfV7oOmagw5VnOV5jXGUxdzMk/Q9um+oSClEPE51IvF76zoFEKPIX/CNdjgalEr+CZADy1gene/YRGrNgrXmYYmiU1/dNzelpla1WpKPrY2pkbOgKxrCR9ScID+pMs6vzvJnPwK9vu66W61U=
|
||||||
|
addons:
|
||||||
|
postgresql: "9.3"
|
@ -18,7 +18,7 @@ module.exports = function (app) {
|
|||||||
app.get('/strategies/:name', function (req, res) {
|
app.get('/strategies/:name', function (req, res) {
|
||||||
strategyDb.getStrategy(req.params.name)
|
strategyDb.getStrategy(req.params.name)
|
||||||
.then(function (strategy) { res.json(strategy); })
|
.then(function (strategy) { res.json(strategy); })
|
||||||
.catch(function () { res.json(404, {error: 'Could not find strategy'}); });
|
.catch(function () { res.status(404).json({error: 'Could not find strategy'}); });
|
||||||
});
|
});
|
||||||
|
|
||||||
app.delete('/strategies/:name', function (req, res) {
|
app.delete('/strategies/:name', function (req, res) {
|
||||||
|
@ -55,7 +55,6 @@
|
|||||||
"jshint": "2.5.2",
|
"jshint": "2.5.2",
|
||||||
"mocha": "1.20.1",
|
"mocha": "1.20.1",
|
||||||
"mocha-lcov-reporter": "0.0.1",
|
"mocha-lcov-reporter": "0.0.1",
|
||||||
"mockery": "1.4.0",
|
|
||||||
"pre-commit": "0.0.9",
|
"pre-commit": "0.0.9",
|
||||||
"react-tools": "^0.12.0",
|
"react-tools": "^0.12.0",
|
||||||
"supertest": "0.13.0",
|
"supertest": "0.13.0",
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
var specHelper = require('./specHelper');
|
var request = require('./specHelper').request;
|
||||||
|
|
||||||
describe('The event api', function () {
|
describe('The event api', function () {
|
||||||
var request;
|
|
||||||
|
|
||||||
before(function () { request = specHelper.setupMockServer(); });
|
|
||||||
after(specHelper.tearDownMockServer);
|
|
||||||
|
|
||||||
it('returns events', function (done) {
|
it('returns events', function (done) {
|
||||||
request
|
request
|
||||||
.get('/events')
|
.get('/events')
|
||||||
|
@ -1,111 +0,0 @@
|
|||||||
var Promise = require("bluebird");
|
|
||||||
|
|
||||||
var events = [
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"created_at": 1414159948677,
|
|
||||||
"type": "feature-create",
|
|
||||||
"created_by": "me",
|
|
||||||
"data": {
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 2,
|
|
||||||
"created_at": 1414159948677,
|
|
||||||
"type": "feature-create",
|
|
||||||
"created_by": "me",
|
|
||||||
"data": {
|
|
||||||
"foo": "bar"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 3,
|
|
||||||
"created_at": 1414159948677,
|
|
||||||
"type": "feature-create",
|
|
||||||
"created_by": "me",
|
|
||||||
"data": {
|
|
||||||
"foo": "rab",
|
|
||||||
"name": "myname"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
var filterableEvents = [
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"created_at": 1414159948677,
|
|
||||||
"type": "feature-create",
|
|
||||||
"created_by": "me",
|
|
||||||
"data": {
|
|
||||||
"name": "foo"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 2,
|
|
||||||
"created_at": 1414159948677,
|
|
||||||
"type": "feature-create",
|
|
||||||
"created_by": "me",
|
|
||||||
"data": {
|
|
||||||
"name": "bar"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 3,
|
|
||||||
"created_at": 1414159948677,
|
|
||||||
"type": "feature-create",
|
|
||||||
"created_by": "me",
|
|
||||||
"data": {
|
|
||||||
"name": "myname"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
function filterEventsByName(name) {
|
|
||||||
return filterableEvents.filter(function (n){return n.data.name===name;});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getEvent(name) {
|
|
||||||
var eventFound;
|
|
||||||
events.forEach(function (event) {
|
|
||||||
if (event.name === name) {
|
|
||||||
eventFound = event;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return eventFound;
|
|
||||||
}
|
|
||||||
|
|
||||||
function storeEvent() {
|
|
||||||
return new Promise(function (resolve) {
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
store: storeEvent,
|
|
||||||
|
|
||||||
getEvents: function() {
|
|
||||||
return new Promise(function (resolve) {
|
|
||||||
resolve(events);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
getEventsFilterByName: function(name) {
|
|
||||||
return new Promise(function (resolve) {
|
|
||||||
resolve(filterEventsByName(name));
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
getEvent: function(name) {
|
|
||||||
var event = getEvent(name);
|
|
||||||
if(event) {
|
|
||||||
return Promise.resolve(event);
|
|
||||||
} else {
|
|
||||||
return Promise.reject("Event not found");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
@ -1,28 +1,8 @@
|
|||||||
var assert = require('assert'),
|
var assert = require('assert'),
|
||||||
mockery = require('mockery'),
|
eventType = require('../lib/eventType'),
|
||||||
eventType = require('../lib/eventType'),
|
eventStore = require('../lib/eventStore');
|
||||||
eventStore;
|
|
||||||
|
|
||||||
|
|
||||||
describe('EventStore', function () {
|
describe('EventStore', function () {
|
||||||
before(function () {
|
|
||||||
mockery.enable({
|
|
||||||
warnOnReplace: false,
|
|
||||||
warnOnUnregistered: false,
|
|
||||||
useCleanCache: true
|
|
||||||
});
|
|
||||||
|
|
||||||
mockery.registerSubstitute('./eventDb', '../test/eventDbMock');
|
|
||||||
mockery.registerSubstitute('./strategyDb', '../test/strategyDbMock');
|
|
||||||
|
|
||||||
eventStore = require('../lib/eventStore');
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function () {
|
|
||||||
mockery.disable();
|
|
||||||
mockery.deregisterAll();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#create()', function () {
|
describe('#create()', function () {
|
||||||
it('should emit event', function (done) {
|
it('should emit event', function (done) {
|
||||||
eventStore.once(eventType.featureCreated, function (x) {
|
eventStore.once(eventType.featureCreated, function (x) {
|
||||||
|
@ -1,16 +1,26 @@
|
|||||||
|
var assert = require('assert');
|
||||||
var specHelper = require('./specHelper');
|
var specHelper = require('./specHelper');
|
||||||
|
var request = specHelper.request;
|
||||||
|
var stringify = function (o) { return JSON.stringify(o, null, ' '); };
|
||||||
|
|
||||||
describe('The features api', function () {
|
describe('The features api', function () {
|
||||||
var request;
|
beforeEach(function (done) {
|
||||||
|
var d = function (err) { console.log('done', err); done.bind(null, err)(); };
|
||||||
|
|
||||||
before(function () { request = specHelper.setupMockServer(); });
|
specHelper.db.resetAndSetup()
|
||||||
after(specHelper.tearDownMockServer);
|
.then(d.bind(null, null))
|
||||||
|
.catch(d);
|
||||||
|
});
|
||||||
|
|
||||||
it('returns three mocked feature toggles', function (done) {
|
it('returns three feature toggles', function (done) {
|
||||||
request
|
request
|
||||||
.get('/features')
|
.get('/features')
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect(200, done);
|
.expect(200)
|
||||||
|
.end(function (err, res) {
|
||||||
|
assert(res.body.features.length === 3, "expected 3 features, got " + stringify(res.body));
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('gets a feature by name', function (done) {
|
it('gets a feature by name', function (done) {
|
||||||
@ -23,7 +33,7 @@ describe('The features api', function () {
|
|||||||
it('creates new feature toggle', function (done) {
|
it('creates new feature toggle', function (done) {
|
||||||
request
|
request
|
||||||
.post('/features')
|
.post('/features')
|
||||||
.send({name: 'com.test.feature', 'enabled': false})
|
.send({name: 'com.test.feature', enabled: false})
|
||||||
.set('Content-Type', 'application/json')
|
.set('Content-Type', 'application/json')
|
||||||
.expect(201, done);
|
.expect(201, done);
|
||||||
});
|
});
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
var Promise = require("bluebird");
|
|
||||||
var NotFoundError = require('../lib/error/NotFoundError');
|
|
||||||
|
|
||||||
var features = [
|
|
||||||
{
|
|
||||||
"name": "featureX",
|
|
||||||
"description": "the #1 feature",
|
|
||||||
"enabled": true,
|
|
||||||
"strategy": "default"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "featureY",
|
|
||||||
"description": "soon to be the #1 feature",
|
|
||||||
"enabled": false,
|
|
||||||
"strategy": "baz",
|
|
||||||
"parameters": {
|
|
||||||
"foo": "bar"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "featureZ",
|
|
||||||
"description": "terrible feature",
|
|
||||||
"enabled": true,
|
|
||||||
"strategy": "baz",
|
|
||||||
"parameters": {
|
|
||||||
"foo": "rab"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
function getFeature(name) {
|
|
||||||
var featureFound;
|
|
||||||
features.forEach(function (feature) {
|
|
||||||
if (feature.name === name) {
|
|
||||||
featureFound = feature;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return featureFound;
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
getFeatures: function() {
|
|
||||||
return new Promise(function (resolve) {
|
|
||||||
resolve(features);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getFeature: function(name) {
|
|
||||||
var feature = getFeature(name);
|
|
||||||
if(feature) {
|
|
||||||
return Promise.resolve(feature);
|
|
||||||
} else {
|
|
||||||
return Promise.reject(new NotFoundError("feature not found"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,10 +1,7 @@
|
|||||||
var specHelper = require('./specHelper');
|
var specHelper = require('./specHelper');
|
||||||
|
var request = specHelper.request;
|
||||||
|
|
||||||
describe('The routes', function () {
|
describe('The routes', function () {
|
||||||
var request;
|
|
||||||
|
|
||||||
before(function () { request = specHelper.setupMockServer(); });
|
|
||||||
after(specHelper.tearDownMockServer);
|
|
||||||
|
|
||||||
describe('healthcheck', function () {
|
describe('healthcheck', function () {
|
||||||
it('returns health good', function (done) {
|
it('returns health good', function (done) {
|
||||||
|
@ -1,37 +1,91 @@
|
|||||||
var request = require('supertest');
|
|
||||||
var mockery = require('mockery');
|
|
||||||
|
|
||||||
process.env.NODE_ENV = 'test';
|
process.env.NODE_ENV = 'test';
|
||||||
|
|
||||||
var server;
|
var Promise = require('bluebird');
|
||||||
|
var request = require('supertest');
|
||||||
|
var app = require('../app');
|
||||||
|
var knex = require('../lib/dbPool');
|
||||||
|
|
||||||
function setupMockServer() {
|
Promise.promisifyAll(request);
|
||||||
mockery.enable({
|
request = request(app);
|
||||||
warnOnReplace: false,
|
|
||||||
warnOnUnregistered: false,
|
function createStrategies() {
|
||||||
useCleanCache: true
|
return Promise.map([
|
||||||
|
{
|
||||||
|
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 (strategy) {
|
||||||
|
return request
|
||||||
|
.post('/strategies').send(strategy)
|
||||||
|
.set('Content-Type', 'application/json')
|
||||||
|
.expect(201)
|
||||||
|
.endAsync();
|
||||||
});
|
});
|
||||||
|
|
||||||
mockery.registerSubstitute('./eventDb', '../test/eventDbMock');
|
|
||||||
mockery.registerSubstitute('./featureDb', '../test/featureDbMock');
|
|
||||||
mockery.registerSubstitute('./strategyDb', '../test/strategyDbMock');
|
|
||||||
|
|
||||||
var app = require('../app');
|
|
||||||
|
|
||||||
return request(app);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function tearDownMockServer() {
|
function createFeatures() {
|
||||||
mockery.disable();
|
return Promise.map([
|
||||||
mockery.deregisterAll();
|
{
|
||||||
|
"name": "featureX",
|
||||||
|
"description": "the #1 feature",
|
||||||
|
"enabled": true,
|
||||||
|
"strategy": "default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "featureY",
|
||||||
|
"description": "soon to be the #1 feature",
|
||||||
|
"enabled": false,
|
||||||
|
"strategy": "baz",
|
||||||
|
"parameters": {
|
||||||
|
"foo": "bar"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "featureZ",
|
||||||
|
"description": "terrible feature",
|
||||||
|
"enabled": true,
|
||||||
|
"strategy": "baz",
|
||||||
|
"parameters": {
|
||||||
|
"foo": "rab"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
], function (feature) {
|
||||||
|
return request
|
||||||
|
.post('/features').send(feature)
|
||||||
|
.set('Content-Type', 'application/json')
|
||||||
|
.expect(201)
|
||||||
|
.endAsync();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (server) {
|
function destroyStrategies() {
|
||||||
server.server.close();
|
return knex('strategies').del();
|
||||||
server = null;
|
}
|
||||||
}
|
|
||||||
|
function destroyFeatures() {
|
||||||
|
return knex('features').del();
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetDatabase() {
|
||||||
|
return Promise.all([destroyStrategies(), destroyFeatures()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupDatabase() {
|
||||||
|
return Promise.all([createStrategies(), createFeatures()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
setupMockServer: setupMockServer,
|
request: request,
|
||||||
tearDownMockServer: tearDownMockServer
|
db: {
|
||||||
|
reset: resetDatabase,
|
||||||
|
setup: setupDatabase,
|
||||||
|
resetAndSetup: function () { return resetDatabase().then(setupDatabase); }
|
||||||
|
}
|
||||||
};
|
};
|
@ -1,10 +1,12 @@
|
|||||||
var specHelper = require('./specHelper');
|
var specHelper = require('./specHelper');
|
||||||
|
var request = specHelper.request;
|
||||||
|
|
||||||
describe('The strategy api', function () {
|
describe('The strategy api', function () {
|
||||||
var request;
|
beforeEach(function (done) {
|
||||||
|
specHelper.db.resetAndSetup()
|
||||||
before(function () { request = specHelper.setupMockServer(); });
|
.then(done.bind(null, null))
|
||||||
after(specHelper.tearDownMockServer);
|
.catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
it('gets all strategies', function (done) {
|
it('gets all strategies', function (done) {
|
||||||
request
|
request
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
var Promise = require("bluebird");
|
|
||||||
|
|
||||||
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"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "deletable",
|
|
||||||
description: "deletable"
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
function byName(name) {
|
|
||||||
return strategies.filter(function(s) {
|
|
||||||
return s.name === name;
|
|
||||||
})[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
getStrategies: function() {
|
|
||||||
return new Promise(function (resolve) {
|
|
||||||
resolve(strategies);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getStrategy: function(name) {
|
|
||||||
var strategy = byName(name);
|
|
||||||
if(strategy) {
|
|
||||||
return Promise.resolve(strategy);
|
|
||||||
} else {
|
|
||||||
return Promise.reject("strategy not found");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
Loading…
Reference in New Issue
Block a user