Merge pull request #586 from sharelatex/ta-refactor-user-getter

Canonical Way to Get Users by Email
This commit is contained in:
Timothée Alby 2018-05-29 17:56:59 +02:00 committed by GitHub
commit 6db3bf59a6
23 changed files with 145 additions and 133 deletions

View file

@ -1,5 +1,5 @@
BetaProgramHandler = require './BetaProgramHandler' BetaProgramHandler = require './BetaProgramHandler'
UserLocator = require "../User/UserLocator" UserGetter = require "../User/UserGetter"
Settings = require "settings-sharelatex" Settings = require "settings-sharelatex"
logger = require 'logger-sharelatex' logger = require 'logger-sharelatex'
AuthenticationController = require '../Authentication/AuthenticationController' AuthenticationController = require '../Authentication/AuthenticationController'
@ -30,7 +30,7 @@ module.exports = BetaProgramController =
optInPage: (req, res, next)-> optInPage: (req, res, next)->
user_id = AuthenticationController.getLoggedInUserId(req) user_id = AuthenticationController.getLoggedInUserId(req)
logger.log {user_id}, "showing beta participation page for user" logger.log {user_id}, "showing beta participation page for user"
UserLocator.findById user_id, (err, user)-> UserGetter.getUser user_id, (err, user)->
if err if err
logger.err {err, user_id}, "error fetching user" logger.err {err, user_id}, "error fetching user"
return next(err) return next(err)

View file

@ -27,7 +27,7 @@ module.exports = CollaboratorsInviteController =
_checkShouldInviteEmail: (email, callback=(err, shouldAllowInvite)->) -> _checkShouldInviteEmail: (email, callback=(err, shouldAllowInvite)->) ->
if Settings.restrictInvitesToExistingAccounts == true if Settings.restrictInvitesToExistingAccounts == true
logger.log {email}, "checking if user exists with this email" logger.log {email}, "checking if user exists with this email"
UserGetter.getUser {email: email}, {_id: 1}, (err, user) -> UserGetter.getUserByMainEmail email, {_id: 1}, (err, user) ->
return callback(err) if err? return callback(err) if err?
userExists = user? and user?._id? userExists = user? and user?._id?
callback(null, userExists) callback(null, userExists)

View file

@ -32,7 +32,7 @@ module.exports = CollaboratorsInviteHandler =
_trySendInviteNotification: (projectId, sendingUser, invite, callback=(err)->) -> _trySendInviteNotification: (projectId, sendingUser, invite, callback=(err)->) ->
email = invite.email email = invite.email
UserGetter.getUser {email: email}, {_id: 1}, (err, existingUser) -> UserGetter.getUserByMainEmail email, {_id: 1}, (err, existingUser) ->
if err? if err?
logger.err {projectId, email}, "error checking if user exists" logger.err {projectId, email}, "error checking if user exists"
return callback(err) return callback(err)

View file

@ -9,7 +9,7 @@ logger = require("logger-sharelatex")
module.exports = module.exports =
generateAndEmailResetToken:(email, callback = (error, exists) ->)-> generateAndEmailResetToken:(email, callback = (error, exists) ->)->
UserGetter.getUser email:email, (err, user)-> UserGetter.getUserByMainEmail email, (err, user)->
if err then return callback(err) if err then return callback(err)
if !user? or user.holdingAccount if !user? or user.holdingAccount
logger.err email:email, "user could not be found for password reset" logger.err email:email, "user could not be found for password reset"

View file

@ -2,7 +2,7 @@ async = require("async")
_ = require("underscore") _ = require("underscore")
SubscriptionUpdater = require("./SubscriptionUpdater") SubscriptionUpdater = require("./SubscriptionUpdater")
SubscriptionLocator = require("./SubscriptionLocator") SubscriptionLocator = require("./SubscriptionLocator")
UserLocator = require("../User/UserLocator") UserGetter = require("../User/UserGetter")
LimitationsManager = require("./LimitationsManager") LimitationsManager = require("./LimitationsManager")
logger = require("logger-sharelatex") logger = require("logger-sharelatex")
OneTimeTokenHandler = require("../Security/OneTimeTokenHandler") OneTimeTokenHandler = require("../Security/OneTimeTokenHandler")
@ -21,7 +21,7 @@ module.exports = SubscriptionGroupHandler =
if limitReached if limitReached
logger.err adminUserId:adminUserId, newEmail:newEmail, "group subscription limit reached not adding user to group" logger.err adminUserId:adminUserId, newEmail:newEmail, "group subscription limit reached not adding user to group"
return callback(limitReached:limitReached) return callback(limitReached:limitReached)
UserLocator.findByEmail newEmail, (err, user)-> UserGetter.getUserByMainEmail newEmail, (err, user)->
return callback(err) if err? return callback(err) if err?
if user? if user?
SubscriptionUpdater.addUserToGroup adminUserId, user._id, (err)-> SubscriptionUpdater.addUserToGroup adminUserId, user._id, (err)->
@ -50,7 +50,7 @@ module.exports = SubscriptionGroupHandler =
users.push buildEmailInviteViewModel(email) users.push buildEmailInviteViewModel(email)
jobs = _.map subscription.member_ids, (user_id)-> jobs = _.map subscription.member_ids, (user_id)->
return (cb)-> return (cb)->
UserLocator.findById user_id, (err, user)-> UserGetter.getUser user_id, (err, user)->
if err? or !user? if err? or !user?
users.push _id:user_id users.push _id:user_id
return cb() return cb()

View file

@ -1,6 +1,6 @@
UserHandler = require("./UserHandler") UserHandler = require("./UserHandler")
UserDeleter = require("./UserDeleter") UserDeleter = require("./UserDeleter")
UserLocator = require("./UserLocator") UserGetter = require("./UserGetter")
User = require("../../models/User").User User = require("../../models/User").User
newsLetterManager = require('../Newsletter/NewsletterManager') newsLetterManager = require('../Newsletter/NewsletterManager')
UserRegistrationHandler = require("./UserRegistrationHandler") UserRegistrationHandler = require("./UserRegistrationHandler")
@ -45,7 +45,7 @@ module.exports = UserController =
unsubscribe: (req, res)-> unsubscribe: (req, res)->
user_id = AuthenticationController.getLoggedInUserId(req) user_id = AuthenticationController.getLoggedInUserId(req)
UserLocator.findById user_id, (err, user)-> UserGetter.getUser user_id, (err, user)->
newsLetterManager.unsubscribe user, -> newsLetterManager.unsubscribe user, ->
res.send() res.send()

View file

@ -6,6 +6,8 @@ ObjectId = mongojs.ObjectId
module.exports = UserGetter = module.exports = UserGetter =
getUser: (query, projection, callback = (error, user) ->) -> getUser: (query, projection, callback = (error, user) ->) ->
if query?.email?
return callback(new Error("Don't use getUser to find user by email"), null)
if arguments.length == 2 if arguments.length == 2
callback = projection callback = projection
projection = {} projection = {}
@ -19,6 +21,13 @@ module.exports = UserGetter =
db.users.findOne query, projection, callback db.users.findOne query, projection, callback
getUserByMainEmail: (email, projection, callback = (error, user) ->) ->
email = email.trim()
if arguments.length == 2
callback = projection
projection = {}
db.users.findOne email: email, projection, callback
getUsers: (user_ids, projection, callback = (error, users) ->) -> getUsers: (user_ids, projection, callback = (error, users) ->) ->
try try
user_ids = user_ids.map (u) -> ObjectId(u.toString()) user_ids = user_ids.map (u) -> ObjectId(u.toString())
@ -39,6 +48,7 @@ module.exports = UserGetter =
[ [
'getUser', 'getUser',
'getUserByMainEmail',
'getUsers', 'getUsers',
'getUserOrUserStubById' 'getUserOrUserStubById'
].map (method) -> ].map (method) ->

View file

@ -1,21 +0,0 @@
mongojs = require("../../infrastructure/mongojs")
metrics = require("metrics-sharelatex")
db = mongojs.db
ObjectId = mongojs.ObjectId
logger = require('logger-sharelatex')
module.exports = UserLocator =
findByEmail: (email, callback)->
email = email.trim()
db.users.findOne email:email, (err, user)->
callback(err, user)
findById: (_id, callback)->
db.users.findOne _id:ObjectId(_id+""), callback
[
'findById',
'findByEmail'
].map (method) ->
metrics.timeAsyncMethod UserLocator, method, 'mongo.UserLocator', logger

View file

@ -1,4 +1,3 @@
UserLocator = require("./UserLocator")
UserGetter = require("./UserGetter") UserGetter = require("./UserGetter")
UserSessionsManager = require("./UserSessionsManager") UserSessionsManager = require("./UserSessionsManager")
ErrorController = require("../Errors/ErrorController") ErrorController = require("../Errors/ErrorController")
@ -61,7 +60,7 @@ module.exports =
user_id = AuthenticationController.getLoggedInUserId(req) user_id = AuthenticationController.getLoggedInUserId(req)
logger.log user: user_id, "loading settings page" logger.log user: user_id, "loading settings page"
shouldAllowEditingDetails = !(Settings?.ldap?.updateUserDetailsOnLogin) and !(Settings?.saml?.updateUserDetailsOnLogin) shouldAllowEditingDetails = !(Settings?.ldap?.updateUserDetailsOnLogin) and !(Settings?.saml?.updateUserDetailsOnLogin)
UserLocator.findById user_id, (err, user)-> UserGetter.getUser user_id, (err, user)->
return next(err) if err? return next(err) if err?
res.render 'user/settings', res.render 'user/settings',
title:'account_settings' title:'account_settings'

View file

@ -1,6 +1,7 @@
sanitize = require('sanitizer') sanitize = require('sanitizer')
User = require("../../models/User").User User = require("../../models/User").User
UserCreator = require("./UserCreator") UserCreator = require("./UserCreator")
UserGetter = require("./UserGetter")
AuthenticationManager = require("../Authentication/AuthenticationManager") AuthenticationManager = require("../Authentication/AuthenticationManager")
NewsLetterManager = require("../Newsletter/NewsletterManager") NewsLetterManager = require("../Newsletter/NewsletterManager")
async = require("async") async = require("async")
@ -47,7 +48,7 @@ module.exports = UserRegistrationHandler =
if !requestIsValid if !requestIsValid
return callback(new Error("request is not valid")) return callback(new Error("request is not valid"))
userDetails.email = userDetails.email?.trim()?.toLowerCase() userDetails.email = userDetails.email?.trim()?.toLowerCase()
User.findOne email:userDetails.email, (err, user)-> UserGetter.getUserByMainEmail userDetails.email, (err, user) =>
if err? if err?
return callback err return callback err
if user?.holdingAccount == false if user?.holdingAccount == false

View file

@ -3,7 +3,7 @@ mongojs = require("../../infrastructure/mongojs")
metrics = require("metrics-sharelatex") metrics = require("metrics-sharelatex")
db = mongojs.db db = mongojs.db
ObjectId = mongojs.ObjectId ObjectId = mongojs.ObjectId
UserLocator = require("./UserLocator") UserGetter = require("./UserGetter")
module.exports = UserUpdater = module.exports = UserUpdater =
updateUser: (query, update, callback = (error) ->) -> updateUser: (query, update, callback = (error) ->) ->
@ -18,7 +18,7 @@ module.exports = UserUpdater =
changeEmailAddress: (user_id, newEmail, callback)-> changeEmailAddress: (user_id, newEmail, callback)->
self = @ self = @
logger.log user_id:user_id, newEmail:newEmail, "updaing email address of user" logger.log user_id:user_id, newEmail:newEmail, "updaing email address of user"
UserLocator.findByEmail newEmail, (error, user) -> UserGetter.getUserByMainEmail newEmail, (error, user) ->
if user? if user?
return callback({message:"alread_exists"}) return callback({message:"alread_exists"})
self.updateUser user_id.toString(), { self.updateUser user_id.toString(), {

View file

@ -23,8 +23,8 @@ describe "BetaProgramController", ->
optIn: sinon.stub() optIn: sinon.stub()
optOut: sinon.stub() optOut: sinon.stub()
}, },
"../User/UserLocator": @UserLocator = { "../User/UserGetter": @UserGetter = {
findById: sinon.stub() getUser: sinon.stub()
}, },
"settings-sharelatex": @settings = { "settings-sharelatex": @settings = {
languages: {} languages: {}
@ -119,7 +119,7 @@ describe "BetaProgramController", ->
describe "optInPage", -> describe "optInPage", ->
beforeEach -> beforeEach ->
@UserLocator.findById.callsArgWith(1, null, @user) @UserGetter.getUser.callsArgWith(1, null, @user)
it "should render the opt-in page", () -> it "should render the opt-in page", () ->
@BetaProgramController.optInPage @req, @res, @next @BetaProgramController.optInPage @req, @res, @next
@ -128,10 +128,10 @@ describe "BetaProgramController", ->
args[0].should.equal 'beta_program/opt_in' args[0].should.equal 'beta_program/opt_in'
describe "when UserLocator.findById produces an error", -> describe "when UserGetter.getUser produces an error", ->
beforeEach -> beforeEach ->
@UserLocator.findById.callsArgWith(1, new Error('woops')) @UserGetter.getUser.callsArgWith(1, new Error('woops'))
it "should not render the opt-in page", () -> it "should not render the opt-in page", () ->
@BetaProgramController.optInPage @req, @res, @next @BetaProgramController.optInPage @req, @res, @next

View file

@ -24,11 +24,14 @@ describe "CollaboratorsInviteController", ->
addCount: sinon.stub addCount: sinon.stub
@LimitationsManager = {} @LimitationsManager = {}
@UserGetter =
getUserByMainEmail: sinon.stub()
getUser: sinon.stub()
@CollaboratorsInviteController = SandboxedModule.require modulePath, requires: @CollaboratorsInviteController = SandboxedModule.require modulePath, requires:
"../Project/ProjectGetter": @ProjectGetter = {} "../Project/ProjectGetter": @ProjectGetter = {}
'../Subscription/LimitationsManager' : @LimitationsManager '../Subscription/LimitationsManager' : @LimitationsManager
'../User/UserGetter': @UserGetter = {getUser: sinon.stub()} '../User/UserGetter': @UserGetter
"./CollaboratorsHandler": @CollaboratorsHandler = {} "./CollaboratorsHandler": @CollaboratorsHandler = {}
"./CollaboratorsInviteHandler": @CollaboratorsInviteHandler = {} "./CollaboratorsInviteHandler": @CollaboratorsInviteHandler = {}
'logger-sharelatex': @logger = {err: sinon.stub(), error: sinon.stub(), log: sinon.stub()} 'logger-sharelatex': @logger = {err: sinon.stub(), error: sinon.stub(), log: sinon.stub()}
@ -713,7 +716,7 @@ describe "CollaboratorsInviteController", ->
beforeEach -> beforeEach ->
@user = {_id: ObjectId().toString()} @user = {_id: ObjectId().toString()}
@UserGetter.getUser = sinon.stub().callsArgWith(2, null, @user) @UserGetter.getUserByMainEmail = sinon.stub().callsArgWith(2, null, @user)
it 'should callback with `true`', (done) -> it 'should callback with `true`', (done) ->
@call (err, shouldAllow) => @call (err, shouldAllow) =>
@ -725,7 +728,7 @@ describe "CollaboratorsInviteController", ->
beforeEach -> beforeEach ->
@user = null @user = null
@UserGetter.getUser = sinon.stub().callsArgWith(2, null, @user) @UserGetter.getUserByMainEmail = sinon.stub().callsArgWith(2, null, @user)
it 'should callback with `false`', (done) -> it 'should callback with `false`', (done) ->
@call (err, shouldAllow) => @call (err, shouldAllow) =>
@ -735,15 +738,15 @@ describe "CollaboratorsInviteController", ->
it 'should have called getUser', (done) -> it 'should have called getUser', (done) ->
@call (err, shouldAllow) => @call (err, shouldAllow) =>
@UserGetter.getUser.callCount.should.equal 1 @UserGetter.getUserByMainEmail.callCount.should.equal 1
@UserGetter.getUser.calledWith({email: @email}, {_id: 1}).should.equal true @UserGetter.getUserByMainEmail.calledWith(@email, {_id: 1}).should.equal true
done() done()
describe 'when getUser produces an error', -> describe 'when getUser produces an error', ->
beforeEach -> beforeEach ->
@user = null @user = null
@UserGetter.getUser = sinon.stub().callsArgWith(2, new Error('woops')) @UserGetter.getUserByMainEmail = sinon.stub().callsArgWith(2, new Error('woops'))
it 'should callback with an error', (done) -> it 'should callback with an error', (done) ->
@call (err, shouldAllow) => @call (err, shouldAllow) =>

View file

@ -605,7 +605,7 @@ describe "CollaboratorsInviteHandler", ->
_id: ObjectId() _id: ObjectId()
first_name: "jim" first_name: "jim"
@existingUser = {_id: ObjectId()} @existingUser = {_id: ObjectId()}
@UserGetter.getUser = sinon.stub().callsArgWith(2, null, @existingUser) @UserGetter.getUserByMainEmail = sinon.stub().callsArgWith(2, null, @existingUser)
@fakeProject = @fakeProject =
_id: @project_id _id: @project_id
name: "some project" name: "some project"
@ -626,8 +626,8 @@ describe "CollaboratorsInviteHandler", ->
it 'should call getUser', (done) -> it 'should call getUser', (done) ->
@call (err) => @call (err) =>
@UserGetter.getUser.callCount.should.equal 1 @UserGetter.getUserByMainEmail.callCount.should.equal 1
@UserGetter.getUser.calledWith({email: @invite.email}).should.equal true @UserGetter.getUserByMainEmail.calledWith(@invite.email).should.equal true
done() done()
it 'should call getProject', (done) -> it 'should call getProject', (done) ->
@ -671,7 +671,7 @@ describe "CollaboratorsInviteHandler", ->
describe 'when the user does not exist', -> describe 'when the user does not exist', ->
beforeEach -> beforeEach ->
@UserGetter.getUser = sinon.stub().callsArgWith(2, null, null) @UserGetter.getUserByMainEmail = sinon.stub().callsArgWith(2, null, null)
it 'should not produce an error', (done) -> it 'should not produce an error', (done) ->
@call (err) => @call (err) =>
@ -680,8 +680,8 @@ describe "CollaboratorsInviteHandler", ->
it 'should call getUser', (done) -> it 'should call getUser', (done) ->
@call (err) => @call (err) =>
@UserGetter.getUser.callCount.should.equal 1 @UserGetter.getUserByMainEmail.callCount.should.equal 1
@UserGetter.getUser.calledWith({email: @invite.email}).should.equal true @UserGetter.getUserByMainEmail.calledWith(@invite.email).should.equal true
done() done()
it 'should not call getProject', (done) -> it 'should not call getProject', (done) ->
@ -698,7 +698,7 @@ describe "CollaboratorsInviteHandler", ->
describe 'when the getUser produces an error', -> describe 'when the getUser produces an error', ->
beforeEach -> beforeEach ->
@UserGetter.getUser = sinon.stub().callsArgWith(2, new Error('woops')) @UserGetter.getUserByMainEmail = sinon.stub().callsArgWith(2, new Error('woops'))
it 'should produce an error', (done) -> it 'should produce an error', (done) ->
@call (err) => @call (err) =>
@ -707,8 +707,8 @@ describe "CollaboratorsInviteHandler", ->
it 'should call getUser', (done) -> it 'should call getUser', (done) ->
@call (err) => @call (err) =>
@UserGetter.getUser.callCount.should.equal 1 @UserGetter.getUserByMainEmail.callCount.should.equal 1
@UserGetter.getUser.calledWith({email: @invite.email}).should.equal true @UserGetter.getUserByMainEmail.calledWith(@invite.email).should.equal true
done() done()
it 'should not call getProject', (done) -> it 'should not call getProject', (done) ->

View file

@ -16,7 +16,7 @@ describe "PasswordResetHandler", ->
getNewToken:sinon.stub() getNewToken:sinon.stub()
getValueFromTokenAndExpire:sinon.stub() getValueFromTokenAndExpire:sinon.stub()
@UserGetter = @UserGetter =
getUser:sinon.stub() getUserByMainEmail:sinon.stub()
@EmailHandler = @EmailHandler =
sendEmail:sinon.stub() sendEmail:sinon.stub()
@AuthenticationManager = @AuthenticationManager =
@ -40,7 +40,7 @@ describe "PasswordResetHandler", ->
describe "generateAndEmailResetToken", -> describe "generateAndEmailResetToken", ->
it "should check the user exists", (done)-> it "should check the user exists", (done)->
@UserGetter.getUser.callsArgWith(1) @UserGetter.getUserByMainEmail.callsArgWith(1)
@OneTimeTokenHandler.getNewToken.callsArgWith(1) @OneTimeTokenHandler.getNewToken.callsArgWith(1)
@PasswordResetHandler.generateAndEmailResetToken @user.email, (err, exists)=> @PasswordResetHandler.generateAndEmailResetToken @user.email, (err, exists)=>
exists.should.equal false exists.should.equal false
@ -49,7 +49,7 @@ describe "PasswordResetHandler", ->
it "should send the email with the token", (done)-> it "should send the email with the token", (done)->
@UserGetter.getUser.callsArgWith(1, null, @user) @UserGetter.getUserByMainEmail.callsArgWith(1, null, @user)
@OneTimeTokenHandler.getNewToken.callsArgWith(1, null, @token) @OneTimeTokenHandler.getNewToken.callsArgWith(1, null, @token)
@EmailHandler.sendEmail.callsArgWith(2) @EmailHandler.sendEmail.callsArgWith(2)
@PasswordResetHandler.generateAndEmailResetToken @user.email, (err, exists)=> @PasswordResetHandler.generateAndEmailResetToken @user.email, (err, exists)=>
@ -62,7 +62,7 @@ describe "PasswordResetHandler", ->
it "should return exists = false for a holdingAccount", (done) -> it "should return exists = false for a holdingAccount", (done) ->
@user.holdingAccount = true @user.holdingAccount = true
@UserGetter.getUser.callsArgWith(1, null, @user) @UserGetter.getUserByMainEmail.callsArgWith(1, null, @user)
@OneTimeTokenHandler.getNewToken.callsArgWith(1) @OneTimeTokenHandler.getNewToken.callsArgWith(1)
@PasswordResetHandler.generateAndEmailResetToken @user.email, (err, exists)=> @PasswordResetHandler.generateAndEmailResetToken @user.email, (err, exists)=>
exists.should.equal false exists.should.equal false

View file

@ -30,9 +30,9 @@ describe "SubscriptionGroupHandler", ->
addEmailInviteToGroup: sinon.stub().callsArgWith(2) addEmailInviteToGroup: sinon.stub().callsArgWith(2)
removeEmailInviteFromGroup: sinon.stub().callsArgWith(2) removeEmailInviteFromGroup: sinon.stub().callsArgWith(2)
@UserLocator = @UserGetter =
findById: sinon.stub() getUser: sinon.stub()
findByEmail: sinon.stub() getUserByMainEmail: sinon.stub()
@LimitationsManager = @LimitationsManager =
hasGroupMembersLimitReached: sinon.stub() hasGroupMembersLimitReached: sinon.stub()
@ -56,7 +56,7 @@ describe "SubscriptionGroupHandler", ->
"../User/UserCreator": @UserCreator "../User/UserCreator": @UserCreator
"./SubscriptionUpdater": @SubscriptionUpdater "./SubscriptionUpdater": @SubscriptionUpdater
"./SubscriptionLocator": @SubscriptionLocator "./SubscriptionLocator": @SubscriptionLocator
"../User/UserLocator": @UserLocator "../User/UserGetter": @UserGetter
"./LimitationsManager": @LimitationsManager "./LimitationsManager": @LimitationsManager
"../Security/OneTimeTokenHandler":@OneTimeTokenHandler "../Security/OneTimeTokenHandler":@OneTimeTokenHandler
"../Email/EmailHandler":@EmailHandler "../Email/EmailHandler":@EmailHandler
@ -71,11 +71,11 @@ describe "SubscriptionGroupHandler", ->
describe "addUserToGroup", -> describe "addUserToGroup", ->
beforeEach -> beforeEach ->
@LimitationsManager.hasGroupMembersLimitReached.callsArgWith(1, null, false, @subscription) @LimitationsManager.hasGroupMembersLimitReached.callsArgWith(1, null, false, @subscription)
@UserLocator.findByEmail.callsArgWith(1, null, @user) @UserGetter.getUserByMainEmail.callsArgWith(1, null, @user)
it "should find the user", (done)-> it "should find the user", (done)->
@Handler.addUserToGroup @adminUser_id, @newEmail, (err)=> @Handler.addUserToGroup @adminUser_id, @newEmail, (err)=>
@UserLocator.findByEmail.calledWith(@newEmail).should.equal true @UserGetter.getUserByMainEmail.calledWith(@newEmail).should.equal true
done() done()
it "should add the user to the group", (done)-> it "should add the user to the group", (done)->
@ -102,7 +102,7 @@ describe "SubscriptionGroupHandler", ->
done() done()
it "should add an email invite if no user is found", (done) -> it "should add an email invite if no user is found", (done) ->
@UserLocator.findByEmail.callsArgWith(1, null, null) @UserGetter.getUserByMainEmail.callsArgWith(1, null, null)
@Handler.addUserToGroup @adminUser_id, @newEmail, (err)=> @Handler.addUserToGroup @adminUser_id, @newEmail, (err)=>
@SubscriptionUpdater.addEmailInviteToGroup.calledWith(@adminUser_id, @newEmail).should.equal true @SubscriptionUpdater.addEmailInviteToGroup.calledWith(@adminUser_id, @newEmail).should.equal true
done() done()
@ -119,26 +119,26 @@ describe "SubscriptionGroupHandler", ->
beforeEach -> beforeEach ->
@subscription = {} @subscription = {}
@SubscriptionLocator.getUsersSubscription.callsArgWith(1, null, @subscription) @SubscriptionLocator.getUsersSubscription.callsArgWith(1, null, @subscription)
@UserLocator.findById.callsArgWith(1, null, {_id:"31232"}) @UserGetter.getUser.callsArgWith(1, null, {_id:"31232"})
it "should locate the subscription", (done)-> it "should locate the subscription", (done)->
@UserLocator.findById.callsArgWith(1, null, {_id:"31232"}) @UserGetter.getUser.callsArgWith(1, null, {_id:"31232"})
@Handler.getPopulatedListOfMembers @adminUser_id, (err, users)=> @Handler.getPopulatedListOfMembers @adminUser_id, (err, users)=>
@SubscriptionLocator.getUsersSubscription.calledWith(@adminUser_id).should.equal true @SubscriptionLocator.getUsersSubscription.calledWith(@adminUser_id).should.equal true
done() done()
it "should get the users by id", (done)-> it "should get the users by id", (done)->
@UserLocator.findById.callsArgWith(1, null, {_id:"31232"}) @UserGetter.getUser.callsArgWith(1, null, {_id:"31232"})
@subscription.member_ids = ["1234", "342432", "312312"] @subscription.member_ids = ["1234", "342432", "312312"]
@Handler.getPopulatedListOfMembers @adminUser_id, (err, users)=> @Handler.getPopulatedListOfMembers @adminUser_id, (err, users)=>
@UserLocator.findById.calledWith(@subscription.member_ids[0]).should.equal true @UserGetter.getUser.calledWith(@subscription.member_ids[0]).should.equal true
@UserLocator.findById.calledWith(@subscription.member_ids[1]).should.equal true @UserGetter.getUser.calledWith(@subscription.member_ids[1]).should.equal true
@UserLocator.findById.calledWith(@subscription.member_ids[2]).should.equal true @UserGetter.getUser.calledWith(@subscription.member_ids[2]).should.equal true
users.length.should.equal @subscription.member_ids.length users.length.should.equal @subscription.member_ids.length
done() done()
it "should just return the id if the user can not be found as they may have deleted their account", (done)-> it "should just return the id if the user can not be found as they may have deleted their account", (done)->
@UserLocator.findById.callsArgWith(1) @UserGetter.getUser.callsArgWith(1)
@subscription.member_ids = ["1234", "342432", "312312"] @subscription.member_ids = ["1234", "342432", "312312"]
@Handler.getPopulatedListOfMembers @adminUser_id, (err, users)=> @Handler.getPopulatedListOfMembers @adminUser_id, (err, users)=>
assert.deepEqual users[0], {_id:@subscription.member_ids[0]} assert.deepEqual users[0], {_id:@subscription.member_ids[0]}

View file

@ -30,8 +30,8 @@ describe "UserController", ->
@UserDeleter = @UserDeleter =
deleteUser: sinon.stub().callsArgWith(1) deleteUser: sinon.stub().callsArgWith(1)
@UserLocator = @UserGetter =
findById: sinon.stub().callsArgWith(1, null, @user) getUser: sinon.stub().callsArgWith(1, null, @user)
@User = @User =
findById: sinon.stub().callsArgWith(1, null, @user) findById: sinon.stub().callsArgWith(1, null, @user)
@NewsLetterManager = @NewsLetterManager =
@ -63,7 +63,7 @@ describe "UserController", ->
@SudoModeHandler = @SudoModeHandler =
clearSudoMode: sinon.stub() clearSudoMode: sinon.stub()
@UserController = SandboxedModule.require modulePath, requires: @UserController = SandboxedModule.require modulePath, requires:
"./UserLocator": @UserLocator "./UserGetter": @UserGetter
"./UserDeleter": @UserDeleter "./UserDeleter": @UserDeleter
"./UserUpdater":@UserUpdater "./UserUpdater":@UserUpdater
"../../models/User": User:@User "../../models/User": User:@User

View file

@ -15,11 +15,11 @@ describe "UserCreator", ->
constructor: -> constructor: ->
return self.user return self.user
@UserLocator = @UserGetter =
findByEmail: sinon.stub() getUserByMainEmail: sinon.stub()
@UserCreator = SandboxedModule.require modulePath, requires: @UserCreator = SandboxedModule.require modulePath, requires:
"../../models/User": User:@UserModel "../../models/User": User:@UserModel
"./UserLocator":@UserLocator "./UserGetter":@UserGetter
"logger-sharelatex":{log:->} "logger-sharelatex":{log:->}
'metrics-sharelatex': {timeAsyncMethod: ()->} 'metrics-sharelatex': {timeAsyncMethod: ()->}

View file

@ -0,0 +1,58 @@
should = require('chai').should()
SandboxedModule = require('sandboxed-module')
assert = require('assert')
path = require('path')
sinon = require('sinon')
modulePath = path.join __dirname, "../../../../app/js/Features/User/UserGetter"
expect = require("chai").expect
describe "UserGetter", ->
beforeEach ->
@fakeUser = {_id:"12390i"}
@findOne = sinon.stub().callsArgWith(2, null, @fakeUser)
@Mongo =
db: users: findOne: @findOne
ObjectId: (id) -> return id
@UserGetter = SandboxedModule.require modulePath, requires:
"logger-sharelatex": log:->
"../../infrastructure/mongojs": @Mongo
"metrics-sharelatex": timeAsyncMethod: sinon.stub()
describe "getUser", ->
it "should get user", (done)->
query = _id: 'foo'
projection = email: 1
@UserGetter.getUser query, projection, (error, user) =>
@findOne.called.should.equal true
@findOne.calledWith(query, projection).should.equal true
user.should.deep.equal @fakeUser
done()
it "should not allow email in query", (done)->
@UserGetter.getUser email: 'foo@bar.com', {}, (error, user) =>
error.should.exist
done()
describe "getUserbyMainEmail", ->
it "query user by main email", (done)->
email = 'hello@world.com'
projection = emails: 1
@UserGetter.getUserByMainEmail email, projection, (error, user) =>
@findOne.called.should.equal true
@findOne.calledWith(email: email, projection).should.equal true
done()
it "return user if found", (done)->
email = 'hello@world.com'
@UserGetter.getUserByMainEmail email, (error, user) =>
user.should.deep.equal @fakeUser
done()
it "trim email", (done)->
email = 'hello@world.com'
@UserGetter.getUserByMainEmail " #{email} ", (error, user) =>
@findOne.called.should.equal true
@findOne.calledWith(email: email).should.equal true
done()

View file

@ -1,39 +0,0 @@
sinon = require('sinon')
chai = require('chai')
should = chai.should()
modulePath = "../../../../app/js/Features/User/UserLocator.js"
SandboxedModule = require('sandboxed-module')
describe "UserLocator", ->
beforeEach ->
@user = {_id:"12390i"}
@UserLocator = SandboxedModule.require modulePath, requires:
"../../infrastructure/mongojs": db: @db = { users: {} }
"metrics-sharelatex": timeAsyncMethod: sinon.stub()
'logger-sharelatex' : { log: sinon.stub() }
@db.users =
findOne : sinon.stub().callsArgWith(1, null, @user)
@email = "bob.oswald@gmail.com"
describe "findByEmail", ->
it "should try and find a user with that email address", (done)->
@UserLocator.findByEmail @email, (err, user)=>
@db.users.findOne.calledWith(email:@email).should.equal true
done()
it "should trim white space", (done)->
@UserLocator.findByEmail "#{@email} ", (err, user)=>
@db.users.findOne.calledWith(email:@email).should.equal true
done()
it "should return the user if found", (done)->
@UserLocator.findByEmail @email, (err, user)=>
user.should.deep.equal @user
done()

View file

@ -16,10 +16,7 @@ describe "UserPagesController", ->
features:{} features:{}
email: "joe@example.com" email: "joe@example.com"
@UserLocator = @UserGetter = getUser: sinon.stub()
findById: sinon.stub().callsArgWith(1, null, @user)
@UserGetter =
getUser: sinon.stub().callsArgWith(2, null, @user)
@UserSessionsManager = @UserSessionsManager =
getAllUserSessions: sinon.stub() getAllUserSessions: sinon.stub()
@dropboxStatus = {} @dropboxStatus = {}
@ -37,7 +34,6 @@ describe "UserPagesController", ->
"logger-sharelatex": "logger-sharelatex":
log:-> log:->
err:-> err:->
"./UserLocator": @UserLocator
"./UserGetter": @UserGetter "./UserGetter": @UserGetter
"./UserSessionsManager": @UserSessionsManager "./UserSessionsManager": @UserSessionsManager
"../Errors/ErrorController": @ErrorController "../Errors/ErrorController": @ErrorController
@ -136,6 +132,8 @@ describe "UserPagesController", ->
@UserPagesController.sessionsPage @req, @res, @next @UserPagesController.sessionsPage @req, @res, @next
describe "settingsPage", -> describe "settingsPage", ->
beforeEach ->
@UserGetter.getUser = sinon.stub().callsArgWith(1, null, @user)
it "should render user/settings", (done)-> it "should render user/settings", (done)->
@res.render = (page)-> @res.render = (page)->
@ -185,6 +183,7 @@ describe "UserPagesController", ->
describe "activateAccountPage", -> describe "activateAccountPage", ->
beforeEach -> beforeEach ->
@UserGetter.getUser = sinon.stub().callsArgWith(2, null, @user)
@req.query.user_id = @user_id @req.query.user_id = @user_id
@req.query.token = @token = "mock-token-123" @req.query.token = @token = "mock-token-123"

View file

@ -12,8 +12,9 @@ describe "UserRegistrationHandler", ->
@user = @user =
_id: @user_id = "31j2lk21kjl" _id: @user_id = "31j2lk21kjl"
@User = @User =
findOne:sinon.stub()
update: sinon.stub().callsArgWith(2) update: sinon.stub().callsArgWith(2)
@UserGetter =
getUserByMainEmail: sinon.stub()
@UserCreator = @UserCreator =
createNewUser:sinon.stub().callsArgWith(1, null, @user) createNewUser:sinon.stub().callsArgWith(1, null, @user)
@AuthenticationManager = @AuthenticationManager =
@ -26,6 +27,7 @@ describe "UserRegistrationHandler", ->
getNewToken: sinon.stub() getNewToken: sinon.stub()
@handler = SandboxedModule.require modulePath, requires: @handler = SandboxedModule.require modulePath, requires:
"../../models/User": {User:@User} "../../models/User": {User:@User}
"./UserGetter": @UserGetter
"./UserCreator": @UserCreator "./UserCreator": @UserCreator
"../Authentication/AuthenticationManager":@AuthenticationManager "../Authentication/AuthenticationManager":@AuthenticationManager
"../Newsletter/NewsletterManager":@NewsLetterManager "../Newsletter/NewsletterManager":@NewsLetterManager
@ -70,7 +72,7 @@ describe "UserRegistrationHandler", ->
beforeEach -> beforeEach ->
@user.holdingAccount = true @user.holdingAccount = true
@handler._registrationRequestIsValid = sinon.stub().returns true @handler._registrationRequestIsValid = sinon.stub().returns true
@User.findOne.callsArgWith(1, null, @user) @UserGetter.getUserByMainEmail.callsArgWith(1, null, @user)
it "should not create a new user if there is a holding account there", (done)-> it "should not create a new user if there is a holding account there", (done)->
@handler.registerNewUser @passingRequest, (err)=> @handler.registerNewUser @passingRequest, (err)=>
@ -94,7 +96,7 @@ describe "UserRegistrationHandler", ->
done() done()
it "should return email registered in the error if there is a non holdingAccount there", (done)-> it "should return email registered in the error if there is a non holdingAccount there", (done)->
@User.findOne.callsArgWith(1, null, @user = {holdingAccount:false}) @UserGetter.getUserByMainEmail.callsArgWith(1, null, @user = {holdingAccount:false})
@handler.registerNewUser @passingRequest, (err, user)=> @handler.registerNewUser @passingRequest, (err, user)=>
err.should.deep.equal new Error("EmailAlreadyRegistered") err.should.deep.equal new Error("EmailAlreadyRegistered")
user.should.deep.equal @user user.should.deep.equal @user
@ -103,7 +105,7 @@ describe "UserRegistrationHandler", ->
describe "validRequest", -> describe "validRequest", ->
beforeEach -> beforeEach ->
@handler._registrationRequestIsValid = sinon.stub().returns true @handler._registrationRequestIsValid = sinon.stub().returns true
@User.findOne.callsArgWith 1 @UserGetter.getUserByMainEmail.callsArgWith 1
it "should create a new user", (done)-> it "should create a new user", (done)->
@handler.registerNewUser @passingRequest, (err)=> @handler.registerNewUser @passingRequest, (err)=>

View file

@ -14,12 +14,12 @@ describe "UserUpdater", ->
@mongojs = @mongojs =
db:{} db:{}
ObjectId:(id)-> return id ObjectId:(id)-> return id
@UserLocator = @UserGetter =
findByEmail:sinon.stub() getUserByMainEmail: sinon.stub()
@UserUpdater = SandboxedModule.require modulePath, requires: @UserUpdater = SandboxedModule.require modulePath, requires:
"settings-sharelatex":@settings "settings-sharelatex":@settings
"logger-sharelatex": log:-> "logger-sharelatex": log:->
"./UserLocator":@UserLocator "./UserGetter": @UserGetter
"../../infrastructure/mongojs":@mongojs "../../infrastructure/mongojs":@mongojs
"metrics-sharelatex": timeAsyncMethod: sinon.stub() "metrics-sharelatex": timeAsyncMethod: sinon.stub()
@ -34,7 +34,7 @@ describe "UserUpdater", ->
@UserUpdater.updateUser = sinon.stub().callsArgWith(2) @UserUpdater.updateUser = sinon.stub().callsArgWith(2)
it "should check if the new email already has an account", (done)-> it "should check if the new email already has an account", (done)->
@UserLocator.findByEmail.callsArgWith(1, null, @stubbedUser) @UserGetter.getUserByMainEmail.callsArgWith(1, null, @stubbedUser)
@UserUpdater.changeEmailAddress @user_id, @stubbedUser.email, (err)=> @UserUpdater.changeEmailAddress @user_id, @stubbedUser.email, (err)=>
@UserUpdater.updateUser.called.should.equal false @UserUpdater.updateUser.called.should.equal false
should.exist(err) should.exist(err)
@ -42,7 +42,7 @@ describe "UserUpdater", ->
it "should set the users password", (done)-> it "should set the users password", (done)->
@UserLocator.findByEmail.callsArgWith(1, null) @UserGetter.getUserByMainEmail.callsArgWith(1, null)
@UserUpdater.changeEmailAddress @user_id, @newEmail, (err)=> @UserUpdater.changeEmailAddress @user_id, @newEmail, (err)=>
@UserUpdater.updateUser.calledWith(@user_id, $set: { "email": @newEmail}).should.equal true @UserUpdater.updateUser.calledWith(@user_id, $set: { "email": @newEmail}).should.equal true
done() done()