I'm currently writing an app using SailsJS. What has been done so far works as expected when tested 'manually', but doesn't when tested with Mocha.
I tried to follow SailsJS testing guide, calling the test with npm:
[...]
"scripts": {
"start": "node app.js",
"debug": "node debug app.js",
"test": "mocha test/bootstrap.test.js test/unit/**/*.test.js"
},
[...]
My test directory structure is as follows:
test
├── bootstrap.test.js
├── mocha.opts
└── unit
└── controllers
└── UserController.test.js
boostrap.test.js:
var Sails = require('sails');
var sails;
before(function(done) {
Sails.lift(function(err, server) {
sails = server;
if (err) return done(err);
done(err, sails);
});
});
after(function(done) {
Sails.lower(done);
});
UserController.test.js:
var request = require('supertest');
describe('UsersController', function() {
describe('#logout()', function() {
it('should respond with a 401 status because nobody is logged in', function (done) {
request(sails.hooks.http.app)
.put('/user/logout')
.expect(401, done)
});
});
describe('#signup()', function() {
it('should create and log in an user', function (done) {
request(sails.hooks.http.app)
.post('/user')
.send({
firstname: 'foo',
name: 'bar',
email: '[email protected]',
sex: true,
password: 'foobar',
birthdate: '01/01/1991',
phoneNumber: '+33 3 10 10 10'
})
.expect(200, done)
});
});
describe('#logout()', function() {
it('should log out an user', function (done) {
request(sails.hooks.http.app)
.put('/user/logout')
.expect(200, done)
});
});
describe('#login()', function() {
it('should respond with a 404 status because credentials are invalid', function (done) {
request(sails.hooks.http.app)
.put('/user/login')
.send({
email: '[email protected]',
password: 'barfoo'
})
.expect(404, done)
});
});
describe('#login()', function() {
it('should log in an user', function (done) {
request(sails.hooks.http.app)
.put('/user/login')
.send({
email: '[email protected]',
password: 'foobar'
})
.expect(200, done);
});
});
describe('#login()', function() {
it('should respond with a 401 status because user is already logged in', function (done) {
request(sails.hooks.http.app)
.put('/user/login')
.send({
email: '[email protected]',
password: 'foobar'
})
.expect(401, done);
});
});
});
Finally, here is my output when I call npm test:
> [email protected] test /Users/fwoelffel/Dev/STOFMA
> mocha test/bootstrap.test.js test/unit/**/*.test.js
UsersController
#logout()
debug: false
debug: req.session -> {"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"}}
info: Policy 'authenticated' disallowed to proceed to the next policy
✓ should respond with a 401 status because nobody is logged in (86ms)
#signup()
debug: null === req.session.authenticated || undefined === req.session.authenticated -> true
debug: req.session -> {"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"}}
info: Policy 'unauthenticated' allowed to proceed to the next policy
info: User [email protected] signed up and logged in.
✓ should create and log in an user (146ms)
#logout()
debug: false
debug: req.session -> {"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"}}
info: Policy 'authenticated' disallowed to proceed to the next policy
1) should log out an user
#login()
debug: null === req.session.authenticated || undefined === req.session.authenticated -> true
debug: req.session -> {"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"}}
info: Policy 'unauthenticated' allowed to proceed to the next policy
info: No user matching [email protected].
✓ should respond with a 404 status because credentials are invalid (66ms)
#login()
debug: null === req.session.authenticated || undefined === req.session.authenticated -> true
debug: req.session -> {"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"}}
info: Policy 'unauthenticated' allowed to proceed to the next policy
info: Found user [email protected].
info: [email protected] credentials are valid.
✓ should log in an user (128ms)
#login()
debug: null === req.session.authenticated || undefined === req.session.authenticated -> true
debug: req.session -> {"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"}}
info: Policy 'unauthenticated' allowed to proceed to the next policy
info: Found user [email protected].
info: [email protected] credentials are valid.
2) should respond with a 401 status because user is already logged in
4 passing (1s)
2 failing
1) UsersController #logout() should log out an user:
Error: expected 200 "OK", got 401 "Unauthorized"
at net.js:1419:10
2) UsersController #login() should respond with a 401 status because user is already logged in:
Error: expected 401 "Unauthorized", got 200 "OK"
at net.js:1419:10
npm ERR! Test failed. See above for more details.
To sum things up, I am testing an auth/unauth API. An below are the policies:
- When a logged in user tries to log in, the 'unauthenticated' policy should throw an error (401)
- When a logged in user tries to sign up, the 'unauthenticated' policy should throw an error (401)
- When an logged out user tries to log out, the 'authenticated' policy should throw an error (401)
I might be doing something wrong but I really can't figure what it is. Could you help to solve this issue?
If you need more information, please ask. You might find the code (without the tests, since they're failing) on Github.
Thanks for reading, have a nice day!
UPDATE
Thanks to elsaar, I changed my code to:
var request = require('supertest');
var agent;
describe('UsersController', function() {
before(function(done) {
agent = request.agent(sails.hooks.http.app);
done();
})
describe('#logout()', function() {
it('should respond with a 401 status because nobody is logged in', function (done) {
agent
.put('/user/logout')
.expect(401, done)
});
});
describe('#signup()', function() {
it('should create and log in an user', function (done) {
agent
.post('/user')
.send({
firstname: 'foo',
name: 'bar',
email: '[email protected]',
sex: true,
password: 'foobar',
birthdate: '01/01/1991',
phoneNumber: '+33 3 10 10 10'
})
.expect(200, done)
});
});
describe('#logout()', function() {
it('should log out an user', function (done) {
agent
.put('/user/logout')
.expect(200, done)
});
});
describe('#login()', function() {
it('should respond with a 404 status because credentials are invalid', function (done) {
agent
.put('/user/login')
.send({
email: '[email protected]',
password: 'barfoo'
})
.expect(404, done)
});
});
describe('#login()', function() {
it('should log in an user', function (done) {
agent
.put('/user/login')
.send({
email: '[email protected]',
password: 'foobar'
})
.expect(200, done);
});
});
describe('#login()', function() {
it('should respond with a 401 status because user is already logged in', function (done) {
agent
.put('/user/login')
.send({
email: '[email protected]',
password: 'foobar'
})
.expect(401, done);
});
});
});