1
0
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:
Jari Bakken 2014-12-05 17:20:17 +01:00 committed by Ivar Conradi Østhus
parent 6bfde35de0
commit 642c06f6ba
12 changed files with 113 additions and 279 deletions

View File

@ -1,8 +1,11 @@
language: node_js
node_js:
- "0.10"
env: DATABASE_URL=postgres://postgres@localhost:5432/unleash_test
before_script:
- echo '--timeout 10000' > test/mocha.opts
- psql -c 'create database unleash_test;' -U postgres
- ./node_modules/.bin/db-migrate up
script:
- npm install
- npm test
@ -11,3 +14,5 @@ notifications:
hipchat:
rooms:
secure: GiIDk52xccnUKnevjLE+w6eUXg0jfV7oOmagw5VnOV5jXGUxdzMk/Q9um+oSClEPE51IvF76zoFEKPIX/CNdjgalEr+CZADy1gene/YRGrNgrXmYYmiU1/dNzelpla1WpKPrY2pkbOgKxrCR9ScID+pMs6vzvJnPwK9vu66W61U=
addons:
postgresql: "9.3"

View File

@ -18,7 +18,7 @@ module.exports = function (app) {
app.get('/strategies/:name', function (req, res) {
strategyDb.getStrategy(req.params.name)
.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) {

View File

@ -55,7 +55,6 @@
"jshint": "2.5.2",
"mocha": "1.20.1",
"mocha-lcov-reporter": "0.0.1",
"mockery": "1.4.0",
"pre-commit": "0.0.9",
"react-tools": "^0.12.0",
"supertest": "0.13.0",

View File

@ -1,11 +1,6 @@
var specHelper = require('./specHelper');
var request = require('./specHelper').request;
describe('The event api', function () {
var request;
before(function () { request = specHelper.setupMockServer(); });
after(specHelper.tearDownMockServer);
it('returns events', function (done) {
request
.get('/events')

View File

@ -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");
}
}
};

View File

@ -1,28 +1,8 @@
var assert = require('assert'),
mockery = require('mockery'),
eventType = require('../lib/eventType'),
eventStore;
var assert = require('assert'),
eventType = require('../lib/eventType'),
eventStore = require('../lib/eventStore');
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 () {
it('should emit event', function (done) {
eventStore.once(eventType.featureCreated, function (x) {

View File

@ -1,16 +1,26 @@
var assert = require('assert');
var specHelper = require('./specHelper');
var request = specHelper.request;
var stringify = function (o) { return JSON.stringify(o, null, ' '); };
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(); });
after(specHelper.tearDownMockServer);
specHelper.db.resetAndSetup()
.then(d.bind(null, null))
.catch(d);
});
it('returns three mocked feature toggles', function (done) {
it('returns three feature toggles', function (done) {
request
.get('/features')
.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) {
@ -23,7 +33,7 @@ describe('The features api', function () {
it('creates new feature toggle', function (done) {
request
.post('/features')
.send({name: 'com.test.feature', 'enabled': false})
.send({name: 'com.test.feature', enabled: false})
.set('Content-Type', 'application/json')
.expect(201, done);
});

View File

@ -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"));
}
}
};

View File

@ -1,10 +1,7 @@
var specHelper = require('./specHelper');
var request = specHelper.request;
describe('The routes', function () {
var request;
before(function () { request = specHelper.setupMockServer(); });
after(specHelper.tearDownMockServer);
describe('healthcheck', function () {
it('returns health good', function (done) {

View File

@ -1,37 +1,91 @@
var request = require('supertest');
var mockery = require('mockery');
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() {
mockery.enable({
warnOnReplace: false,
warnOnUnregistered: false,
useCleanCache: true
Promise.promisifyAll(request);
request = request(app);
function createStrategies() {
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() {
mockery.disable();
mockery.deregisterAll();
function createFeatures() {
return Promise.map([
{
"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) {
server.server.close();
server = null;
}
function destroyStrategies() {
return knex('strategies').del();
}
function destroyFeatures() {
return knex('features').del();
}
function resetDatabase() {
return Promise.all([destroyStrategies(), destroyFeatures()]);
}
function setupDatabase() {
return Promise.all([createStrategies(), createFeatures()]);
}
module.exports = {
setupMockServer: setupMockServer,
tearDownMockServer: tearDownMockServer
request: request,
db: {
reset: resetDatabase,
setup: setupDatabase,
resetAndSetup: function () { return resetDatabase().then(setupDatabase); }
}
};

View File

@ -1,10 +1,12 @@
var specHelper = require('./specHelper');
var request = specHelper.request;
describe('The strategy api', function () {
var request;
before(function () { request = specHelper.setupMockServer(); });
after(specHelper.tearDownMockServer);
beforeEach(function (done) {
specHelper.db.resetAndSetup()
.then(done.bind(null, null))
.catch(done);
});
it('gets all strategies', function (done) {
request

View File

@ -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");
}
}
};