wip: fix unit tests for AuthenticationController

This commit is contained in:
Shane Kilkelly 2016-09-07 14:05:51 +01:00
parent cc5ddc92bb
commit 8e0103a1bc
2 changed files with 68 additions and 81 deletions

View file

@ -62,24 +62,21 @@ module.exports = AuthenticationController =
isUserLoggedIn: (req) -> isUserLoggedIn: (req) ->
user_id = AuthenticationController.getLoggedInUserId(req) user_id = AuthenticationController.getLoggedInUserId(req)
return user_id? return user_id != null
# TODO: perhaps should produce an error if the current user is not present # TODO: perhaps should produce an error if the current user is not present
getLoggedInUserId: (req) -> getLoggedInUserId: (req) ->
user = AuthenticationController.getSessionUser(req) user = AuthenticationController.getSessionUser(req)
if user? if user
return user._id return user._id
else else
return null return null
getSessionUser: (req) -> getSessionUser: (req) ->
# old sessions if req?.session?.user?
if req?.session?.user?._id?
return req.session.user return req.session.user
# new passport sessions else if req?.session?.passport?.user
else if req?.session?.passport?.user?._id?
return req.session.passport.user return req.session.passport.user
# neither
else else
return null return null
@ -110,7 +107,7 @@ module.exports = AuthenticationController =
if req.headers['authorization']? if req.headers['authorization']?
return AuthenticationController.httpAuth(req, res, next) return AuthenticationController.httpAuth(req, res, next)
else if AuthenticationController.isUserLoggedIn()? else if AuthenticationController.isUserLoggedIn(req)
return next() return next()
else else
logger.log url:req.url, "user trying to access endpoint not in global whitelist" logger.log url:req.url, "user trying to access endpoint not in global whitelist"

View file

@ -39,35 +39,52 @@ describe "AuthenticationController", ->
@callback = @next = sinon.stub() @callback = @next = sinon.stub()
tk.freeze(Date.now()) tk.freeze(Date.now())
afterEach -> afterEach ->
tk.reset() tk.reset()
describe "login", -> describe 'getSessionUser', ->
it 'should get the user object from session', ->
@req.session =
passport:
user: {_id: 'one'}
user = @AuthenticationController.getSessionUser(@req)
expect(user).to.deep.equal {_id: 'one'}
it 'should work with legacy sessions', ->
@req.session =
user: {_id: 'one'}
user = @AuthenticationController.getSessionUser(@req)
expect(user).to.deep.equal {_id: 'one'}
describe "doPassportLogin", ->
beforeEach -> beforeEach ->
@AuthenticationController._recordFailedLogin = sinon.stub() @AuthenticationController._recordFailedLogin = sinon.stub()
@AuthenticationController._recordSuccessfulLogin = sinon.stub() @AuthenticationController._recordSuccessfulLogin = sinon.stub()
@AuthenticationController.establishUserSession = sinon.stub().callsArg(2) # @AuthenticationController.establishUserSession = sinon.stub().callsArg(2)
@req.body = @req.body =
email: @email email: @email
password: @password password: @password
redir: @redir = "/path/to/redir/to" redir: @redir = "/path/to/redir/to"
@cb = sinon.stub()
describe "when the users rate limit", -> describe "when the users rate limit", ->
it "should block the request if the limit has been exceeded", (done)-> beforeEach ->
@LoginRateLimiter.processLoginRequest.callsArgWith(1, null, false) @LoginRateLimiter.processLoginRequest.callsArgWith(1, null, false)
@res =
send: (code)=> it "should block the request if the limit has been exceeded", (done)->
@res.statusCode.should.equal 429 @AuthenticationController.doPassportLogin(@req, @req.body.email, @req.body.password, @cb)
done() @cb.callCount.should.equal 1
@AuthenticationController.login(@req, @res) @cb.calledWith(null, null).should.equal true
done()
describe 'when the user is authenticated', -> describe 'when the user is authenticated', ->
beforeEach -> beforeEach ->
@cb = sinon.stub()
@LoginRateLimiter.processLoginRequest.callsArgWith(1, null, true) @LoginRateLimiter.processLoginRequest.callsArgWith(1, null, true)
@AuthenticationManager.authenticate = sinon.stub().callsArgWith(2, null, @user) @AuthenticationManager.authenticate = sinon.stub().callsArgWith(2, null, @user)
@AuthenticationController.login(@req, @res) @AuthenticationController.doPassportLogin(@req, @req.body.email, @req.body.password, @cb)
it "should attempt to authorise the user", -> it "should attempt to authorise the user", ->
@AuthenticationManager.authenticate @AuthenticationManager.authenticate
@ -78,15 +95,13 @@ describe "AuthenticationController", ->
@UserHandler.setupLoginData.calledWith(@user).should.equal true @UserHandler.setupLoginData.calledWith(@user).should.equal true
it "should establish the user's session", -> it "should establish the user's session", ->
@AuthenticationController.establishUserSession @cb.calledWith(null, @user).should.equal true
.calledWith(@req, @user)
.should.equal true
it "should set res.session.justLoggedIn", -> it "should set res.session.justLoggedIn", ->
@req.session.justLoggedIn.should.equal true @req.session.justLoggedIn.should.equal true
it "should redirect the user to the specified location", -> it "should redirect the user to the specified location", ->
expect(@res.body).to.deep.equal redir: @redir expect(@req._redir).to.deep.equal @redir
it "should record the successful login", -> it "should record the successful login", ->
@AuthenticationController._recordSuccessfulLogin @AuthenticationController._recordSuccessfulLogin
@ -106,23 +121,22 @@ describe "AuthenticationController", ->
.calledWith(@user._id, "user-logged-in") .calledWith(@user._id, "user-logged-in")
.should.equal true .should.equal true
describe 'when the user is not authenticated', -> describe 'when the user is not authenticated', ->
beforeEach -> beforeEach ->
@LoginRateLimiter.processLoginRequest.callsArgWith(1, null, true) @LoginRateLimiter.processLoginRequest.callsArgWith(1, null, true)
@AuthenticationManager.authenticate = sinon.stub().callsArgWith(2, null, null) @AuthenticationManager.authenticate = sinon.stub().callsArgWith(2, null, null)
@AuthenticationController.login(@req, @res) @cb = sinon.stub()
@AuthenticationController.doPassportLogin(@req, @req.body.email, @req.body.password, @cb)
it "should return an error", -> it "should not establish the login", ->
@cb.callCount.should.equal 1
@cb.calledWith(null, false)
# @res.body.should.exist # @res.body.should.exist
expect(@res.body.message).to.exist expect(@cb.lastCall.args[2]).to.contain.all.keys ['message']
# message: # message:
# text: 'Your email or password were incorrect. Please try again', # text: 'Your email or password were incorrect. Please try again',
# type: 'error' # type: 'error'
it "should not establish a session", ->
@AuthenticationController.establishUserSession.called.should.equal false
it "should not setup the user data in the background", -> it "should not setup the user data in the background", ->
@UserHandler.setupLoginData.called.should.equal false @UserHandler.setupLoginData.called.should.equal false
@ -139,10 +153,11 @@ describe "AuthenticationController", ->
@LoginRateLimiter.processLoginRequest.callsArgWith(1, null, true) @LoginRateLimiter.processLoginRequest.callsArgWith(1, null, true)
@req.body.redir = "http://www.facebook.com/test" @req.body.redir = "http://www.facebook.com/test"
@AuthenticationManager.authenticate = sinon.stub().callsArgWith(2, null, @user) @AuthenticationManager.authenticate = sinon.stub().callsArgWith(2, null, @user)
@AuthenticationController.login(@req, @res) @cb = sinon.stub()
@AuthenticationController.doPassportLogin(@req, @req.body.email, @req.body.password, @cb)
it "should only redirect to the local path", -> it "should only redirect to the local path", ->
expect(@res.body).to.deep.equal redir: "/test" expect(@req._redir).to.equal "/test"
describe "getLoggedInUserId", -> describe "getLoggedInUserId", ->
@ -150,34 +165,42 @@ describe "AuthenticationController", ->
@req = @req =
session :{} session :{}
it "should return the user id from the session", (done)-> it "should return the user id from the session", ()->
@user_id = "2134" @user_id = "2134"
@req.session.user = @req.session.user =
_id:@user_id _id:@user_id
@AuthenticationController.getLoggedInUserId @req, (err, user_id)=> result = @AuthenticationController.getLoggedInUserId @req
expect(user_id).to.equal @user_id expect(result).to.equal @user_id
done()
it "should return null if there is no user on the session", (done)-> it 'should return user for passport session', () ->
@AuthenticationController.getLoggedInUserId @req, (err, user_id)=> @user_id = "2134"
expect(user_id).to.be.null @req.session = {
done() passport: {
user: {
_id:@user_id
}
}
}
result = @AuthenticationController.getLoggedInUserId @req
expect(result).to.equal @user_id
it "should return null if there is no session", (done)-> it "should return null if there is no user on the session", ()->
result = @AuthenticationController.getLoggedInUserId @req
expect(result).to.equal null
it "should return null if there is no session", ()->
@req = {} @req = {}
@AuthenticationController.getLoggedInUserId @req, (err, user_id)=> result = @AuthenticationController.getLoggedInUserId @req
expect(user_id).to.be.null expect(result).to.equal null
done()
it "should return null if there is no req", (done)-> it "should return null if there is no req", ()->
@req = {} @req = {}
@AuthenticationController.getLoggedInUserId @req, (err, user_id)=> result = @AuthenticationController.getLoggedInUserId @req
expect(user_id).to.be.null expect(result).to.equal null
done()
describe "getLoggedInUser", -> describe "getLoggedInUser", ->
beforeEach -> beforeEach ->
@UserGetter.getUser = sinon.stub().callsArgWith(1, null, @user) @UserGetter.getUser = sinon.stub().callsArgWith(2, null, @user)
describe "with an established session", -> describe "with an established session", ->
beforeEach -> beforeEach ->
@ -209,9 +232,6 @@ describe "AuthenticationController", ->
} }
@middleware(@req, @res, @next) @middleware(@req, @res, @next)
it "should set the user property on the request", ->
@req.user.should.deep.equal @user
it "should call the next method in the chain", -> it "should call the next method in the chain", ->
@next.called.should.equal true @next.called.should.equal true
@ -367,33 +387,3 @@ describe "AuthenticationController", ->
it "should call the callback", -> it "should call the callback", ->
@callback.called.should.equal true @callback.called.should.equal true
describe "establishUserSession", ->
beforeEach ->
@req.session =
save: sinon.stub().callsArg(0)
destroy : sinon.stub()
@req.sessionStore =
generate: sinon.stub()
@req.ip = "1.2.3.4"
@AuthenticationController.establishUserSession @req, @user, @callback
it "should set the session user to a basic version of the user", ->
@req.session.user._id.should.equal @user._id
@req.session.user.email.should.equal @user.email
@req.session.user.first_name.should.equal @user.first_name
@req.session.user.last_name.should.equal @user.last_name
@req.session.user.referal_id.should.equal @user.referal_id
@req.session.user.isAdmin.should.equal @user.isAdmin
@req.session.user.ip_address.should.equal @req.ip
expect(typeof @req.session.user.ip_address).to.equal 'string'
expect(typeof @req.session.user.session_created).to.equal 'string'
it "should destroy the session", ->
@req.session.destroy.called.should.equal true
it "should regenerate the session to protect against session fixation", ->
@req.sessionStore.generate.calledWith(@req).should.equal true
it "should return the callback", ->
@callback.called.should.equal true