test the session lib

pull/365/head
Matthijs van Henten 2016-09-22 18:01:49 +00:00
rodzic 726ac88a50
commit 94afcc2e14
1 zmienionych plików z 186 dodań i 0 usunięć

Wyświetl plik

@ -0,0 +1,186 @@
#!/usr/bin/env node
/*global describe it before after beforeEach afterEach */
"use strict";
"use server";
require("c9/inline-mocha")(module);
require("c9/setup_paths");
var assert = require("assert");
var ConnectCookie = require("./session/cookie");
var Cookie = require("cookie");
var session = require("./session");
var EventEmitter = require("events").EventEmitter;
var sinon = require("sinon");
var Store = require("connect").session.MemoryStore;
var encrypt = require("./encrypt");
var decrypt = require("./decrypt");
var hash = require("./session/hash");
describe("lib/session", function() {
function mockReq() {
var req = new EventEmitter();
req.originalUrl = "/";
req.cookies = {};
req.signedCookies = {};
req.headers = {};
req.connection = {};
return req;
}
function mockRes() {
var res = new EventEmitter();
res.setHeader = function(key, value) {};
sinon.spy(res, "setHeader");
return res;
}
it("Returns a middleware", function() {
var middleware = session({
store: new Store()
});
assert.equal(middleware.length, 3, "Has an arity of 3");
});
it("Encrypts a cookie", function(done) {
var middleware = session({
store: new Store(),
secret: "limecat"
});
var res = mockRes();
middleware(mockReq(), res, function() {
res.emit("header");
assert.ok(res.setHeader.calledOnce);
var args = res.setHeader.args[0];
assert.equal(args[0], "Set-Cookie");
assert.ok(/connect.sid=.+?; Path=\/; HttpOnly/.test(args[1]));
done();
});
});
it("Does not create a new cookie if the secret remains the same", function(done) {
var sessionID = "123";
var secret = "limecat";
var cookieVal = encrypt(sessionID, "connect.sid", new ConnectCookie({}), secret);
var req = mockReq();
var res = mockRes();
var store = new Store();
var mw = session({
secret: ["newsecret", secret],
store: store
});
sinon.stub(hash, "hash", function() {
return;
});
req.cookies = Cookie.parse(cookieVal);
mw(req, res, function() {
var sessionCalled = 0;
var sessionCookie = new ConnectCookie({});
// force the code down a certain path
sessionCookie.expires = new Date(Date.now() + 1000);
Object.defineProperty(req, "session", {
get: function() {
sessionCalled++;
return {
cookie: sessionCookie
};
}
});
res.emit("header");
assert.ok(hash.hash.calledOnce, "we know the hash got called (asserts the code path)");
assert.equal(sessionCalled, 4, "session was accessed, this asserts the code-path");
hash.hash.restore();
assert.ok(res.setHeader.notCalled);
done();
});
});
it("Rotates the secret: it encrypts using the new secret", function(done) {
var sessionID = Math.random().toString(36);
var secret = [Math.random().toString(36), Math.random().toString(36), Math.random().toString(36)];
// use the encryption funciton used in session to create a fake cookie
var cookie = encrypt(sessionID, "connect.sid", new ConnectCookie({}), secret[2]);
var req = mockReq();
var res = mockRes();
var mw = session({
secret: secret,
store: new Store()
});
req.sessionID = sessionID;
req.cookies = Cookie.parse(cookie);
var decryptSpy = sinon.spy(decrypt, "decrypt");
// forces code down the path in L262
sinon.stub(hash, "hash", function() {
return;
});
mw(req, res, function() {
// The cookie must have been decrypted by know, using one of the
// available secrets.
assert.deepEqual(decryptSpy.returnValues[0], {
unsignedCookie: sessionID,
usedSecret: secret[2]
}, "our cookie was decrypted");
// in the "header" listener we check for the cookie.
var sessionCookie = new ConnectCookie({});
// forces the if on L259
sessionCookie.expires = new Date(Date.now() + 1000);
// we need to mock req.session. The listener assumes this to be
// set in a later code path.
req.session = {
cookie: sessionCookie
};
// kick of the listener
res.emit("header");
// check that L262 was NOT executed
assert.ok(hash.hash.notCalled, "hash should be called on L262");
// we expect we got a fresh cookie
assert.ok(res.setHeader.calledOnce, "we expect a new cookie");
var cookie = res.setHeader.args[0][1];
var parsed = Cookie.parse(cookie);
var val = decrypt.decrypt(secret[1], parsed["connect.sid"]);
assert.deepEqual(val, {
unsignedCookie: req.sessionID,
usedSecret: secret[1]
});
hash.hash.restore();
done();
});
});
});