Disable bootstrap.js when run unit tests - sails.js

I have sails.on('lifted',...) in config\bootstrap.js.
How to not run this when running mocha unit tests?

While running tests, you can load sails instead of lifting it.
var Sails = require('sails').Sails;
before(function (done) {
new Sails().load(
{}, // your configuration
done
);
});
after(function (done) {
if (sails) { return sails.lower(done); }
return done();
});

Related

mocha test for sails hook that depends on a sails app

I'm trying to write a mocha test for a sails installable hook (myhook) that is dependent on a particular sails app (myapp). I'd like the bootstrap.test.js to lift myapp with myhook. Thus, I have myapp a devDependency in myhook project.
My bootstrap.test.js has something like this:
var myapp = require('myapp');
// put it in global (special case) for npm test only
global.thehook = require('../api/hooks/myhook/index');
before(function(done) {
this.timeout(10000);
console.log("Bootstrap lifting sails...");
myapp.lift({
hooks: {
"myhook": global.thehook,
"grunt": false
},
log: {level: "error"},
}, function(err) {
if (err) return done(err);
// here you can load fixtures, etc.
done(err, sails);
});
});
after(function(done) {
myapp.lower(done);
});
Thinking .lift() and .lower would apply to the sails app. But, that doesn't seem to be the case.
How do I make this work?
You will need to use the sails dependency in place of myapp.
var sails = require('sails');
before(function(done) {
sails.lift({
// test configuration
}, function (error) {
// ...
done();
});
});
after(function(done) {
sails.lower(function (error) {
//...
done();
});
})
The sails dependency starts in the root of the project directory and will lift the application, so there's no need to require app.js for lifting the app.

how to deal with mongodb race condition in integration test

I have a mongoose schema with a unique field and I am trying to write a backend (express) integration test which checks that POSTing the same entity twice results in HTTP 400. When testing manually behaviour is as excpected. Automatic testing however requires a wait:
it('should not accept two projects with the same name', function(done) {
var project = // ...
postProjectExpect201(project,
() => {
setTimeout( () => {
postProjectExpect400(project, done);
},100);
}
);
});
The two post... methods do as named and the code above works fine, but if the timeout is removed, BOTH requests receive HTTP 200 (though only one entity created in the database).
I'm new to those technologies and I'm not sure what's going on. Could this be a mongodb related concurrency issue and if so how should I deal with it?
The database call looks like this:
Project.create(req.body)
.then(respondWithResult(res, 201))
.catch(next);
I already tried connecting to mongodb with ?w=1 option btw.
Update:
To be more verbose: Project is a mongoose model and next is my express error handler which catches the duplicate error.
The test functions:
var postProjectExpect201=function(project, done, validateProject) {
request(app)
.post('/api/projects')
.send(project)
.expect(201)
.expect('Content-Type', /json/)
.end((err, res) => {
if (err) {
return done(err);
}
validateProject && validateProject(res.body);
done();
});
};
var postProjectExpect400=function(project, done) {
request(app)
.post('/api/projects')
.send(project)
.expect(400)
.end((err, res) => {
if (err) {
return done(err);
}
done();
});
};

404 on Karma when trying to use web worker

I'm getting the error WARN [web-server]: 404: /app/workers/total.js when trying to run a unit test on a web worker.
Karma.conf.js includes the following:
...
files: [
...
'app/workers/*.js',
'unit-tests/mocks/**/*.js',
'unit-tests/src/**/*.js'
],
....
the test goes as follows:
describe('totals', function () {
var worker;
beforeEach(function() {
worker = new Worker('/app/workers/total.js');
});
it('should do something', function () {
...
});
});
I have tried many urls, but none seem to work
Finally I found the solution on https://github.com/karma-runner/karma/issues/1302, the trick is to include /base as part of the worker URL, being the solution:
describe('totals', function () {
var worker;
beforeEach(function() {
worker = new Worker('/base/app/workers/total.js');
});
it('should do something', function () {
...
});
});
Note /base as part of the worker URL.
Thanks to maksimr

How to seed dev database in Sails.js in a reproducible way

I'm looking for a best way to seed my development database in sails js.
In rails I would just use the seeds.rb file but even without that I could use a rake task.
With sails I am unsure of how I could do this outside of manually doing it with sails console.
Please note that solutions which add logic to config/models and the models themselves for production seeding are not what I am looking for. I don't want these records to exist in production.
You can seed your database in the config/bootstrap.js file.
To seed it for a particular environment, what I usually do is:
// config/bootstrap.js
module.exports.bootstrap = function (cb) {
if(process.env.NODE_ENV !== 'development')
return cb();
// Do whatever you want
// And don't forget to...
return cb();
};
And to drop the database each time during the Sails lifting:
// config/env/development.js
module.exports = {
models: {
migrate: 'drop'
}
};
You can use test framework, like Mocha. At your development mode, switch your table name to development table. Here is step by step:
Install mocha with npm install mocha --save-dev
Create test/boostrap.test.js and fill with (configure as your needs), look at my configured connections, it'll override default connections at config.
var Sails = require('sails'),
sails;
before(function (done) {
Sails.lift({
log : {
level: 'error'
},
connections: {
mongodbServer: {
database: 'table_test'
}
},
models : {
migrate: 'drop'
}
}, function (err, server) {
sails = server;
done(err, sails);
});
});
after(function (done) {
// here you can clear fixtures, etc.
sails.lower(done);
});
Create another file for seeding your data, for example create test/inject/seed.js and fill with something like.
describe('data seeding', function(){
it('should seed data', function(done){
sails.models.someModel
.create({
name: 'Some Name'
})
.then(function(result){
done();
})
.catch(done);
});
});
Add this at your package.json under "scripts" key.
"test": "_mocha test/bootstrap.test.js test/inject/**/*.inject.js --no-timeouts"
Run it with npm test to seed your data.
If you need to use it at development mode, when you run sails lift, edit your config/env/development.js and add something like this.
module.exports = {
connections: {
mongodbServer: {
database: 'table_test'
}
}
};
Now your sails lift will use table_test instead of production table, so your production table will be clean.

How to set up unit tests in sailsjs

I cannot run sailsjs unit tests. It seems sails cannot be lifted,
my test (/test/unit/test.js):
var Sails = require('sails');
var app;
before(function() {
console.log('before');
Sails.lift({
log: {
level: 'error'
}
}, function(err, server) {
console.log('lifted');
app = server;
done(err, app);
});
});
// Global after hook
after(function(done) {
app.lower(done);
});
describe('mailer service', function() {
it('should connect to gmail', function() {
console.log(app);
});
});
In my app folder I run: mocha test/unit/test.js
The "app" variable is undefined, console.log('lifted') is not being triggered. What am I doing wrong?
First of all.
You need to call before with a done parameter :
before(function(done){...})
Does your app lift succesfully when you run it with ?
sails lift