Now that we have the user creation flow tested, let's test if that user can log in.
Following the test file pattern we have been using, you need to create a file under test/session.js
with the following content:
var assert = require('assert'), Browser = require('zombie'), app = require('../app'), couchdb = require('../lib/couchdb'), dbName = 'users', db = couchdb.use(dbName), fixtures = require('./fixtures'); describe('Session', function() { before(function(done) { app.start(3000, done); }); after(function(done) { app.server.close(done); });
That concludes the opening ceremonies!
describe('Log in form', function() { before(function(done) { db.get(fixtures.user.email, function(err, doc) { if (err && err.status_code === 404) { return db.insert(fixtures.user, fixtures.user.email, done); } if (err) throw err; done(); }); });
This before
hook creates the test user document if one doesn't exist (instead of removing if it existed).
it('should load', function(done) { Browser.visit("http://localhost:3000/session/new", function(err, browser) { if (err) throw err; assert.ok(browser.success, 'page loaded'); assert.equal(browser.text('h1'), 'Log in'); var form = browser.query('form'); assert(form, 'form exists'); assert.equal(form.method, 'POST', 'uses POST method'); assert.equal(form.action, '/session', 'posts to /session'); assert(browser.query('input[type=email]#email', form), 'has email input'); assert(browser.query('input[type=password]#password', form), 'has password input'); assert(browser.query('input[type=submit]', form), 'has submit button'); done(); }); });
The only difference here from the user code is that the heading string should be Log in
instead of New User
. This happens because we have such a minimal user creation form, which suits us for the time being.
it("should allow you to log in", function(done) { Browser.visit("http://localhost:3000/session/new", function(err, browser) { if (err) throw err; browser .fill('E-mail', fixtures.user.email) .fill('Password', fixtures.user.password) .pressButton('Log In', function(err) { if (err) throw err; assert.equal(browser.location.pathname, '/todos', 'should be redirected to /todos'); done(); }); }); }); }); });
Here we're loading and filling in the e-mail and password fields and clicking on the Log In button. When clicking on the button, the login form is posted, the session is initiated, and the user is redirected to the to-do items page.
$ ./node_modules/.bin/mocha test/session.js ․․ ✔ 2 tests complete (750ms)
it("should not allow you to log in with wrong password", function(done) {
Browser.visit("http://localhost:3000/session/new",
function(err, browser) {
if (err) throw err;
browser
.fill('E-mail', fixtures.user.email)
.fill('Password', fixtures.user.password +
'thisisnotmypassword')
.pressButton('Log In', function(err) {
assert(err, 'expected an error');
assert.equal(browser.statusCode, 403,
'replied with 403 status code');
assert.equal(browser.location.pathname, '/session');
assert.equal(browser.text('#messages .alert .message'),
'Invalid password');
done();
});
}
);
});
Here we're loading and filling the login form, but this time we're providing a wrong password. After clicking on the Log In button, the server should return 403 status code
, which will trigger an error passed in to our callback. Then we need to check the return status code by inspecting the browser.statusCode
attribute, making sure it's the expected 403 forbidden code. Then we also verify that the user did not get redirected to the /todo
URL and that the response document contains an alert message saying Invalid password
.