Merge remote-tracking branch 'origin/master' into afc-update-user-references

This commit is contained in:
Alberto Fernández Capel
2018-06-08 11:28:58 +01:00
130 changed files with 4315 additions and 1011 deletions
@@ -12,6 +12,7 @@ ObjectId = require("mongojs").ObjectId
describe "AuthenticationController", ->
beforeEach ->
tk.freeze(Date.now())
@AuthenticationController = SandboxedModule.require modulePath, requires:
"./AuthenticationManager": @AuthenticationManager = {}
"../User/UserGetter" : @UserGetter = {}
@@ -39,7 +40,6 @@ describe "AuthenticationController", ->
@req = new MockRequest()
@res = new MockResponse()
@callback = @next = sinon.stub()
tk.freeze(Date.now())
afterEach ->
tk.reset()
@@ -23,8 +23,8 @@ describe "BetaProgramController", ->
optIn: sinon.stub()
optOut: sinon.stub()
},
"../User/UserLocator": @UserLocator = {
findById: sinon.stub()
"../User/UserGetter": @UserGetter = {
getUser: sinon.stub()
},
"settings-sharelatex": @settings = {
languages: {}
@@ -119,7 +119,7 @@ describe "BetaProgramController", ->
describe "optInPage", ->
beforeEach ->
@UserLocator.findById.callsArgWith(1, null, @user)
@UserGetter.getUser.callsArgWith(1, null, @user)
it "should render the opt-in page", () ->
@BetaProgramController.optInPage @req, @res, @next
@@ -128,10 +128,10 @@ describe "BetaProgramController", ->
args[0].should.equal 'beta_program/opt_in'
describe "when UserLocator.findById produces an error", ->
describe "when UserGetter.getUser produces an error", ->
beforeEach ->
@UserLocator.findById.callsArgWith(1, new Error('woops'))
@UserGetter.getUser.callsArgWith(1, new Error('woops'))
it "should not render the opt-in page", () ->
@BetaProgramController.optInPage @req, @res, @next
@@ -24,11 +24,14 @@ describe "CollaboratorsInviteController", ->
addCount: sinon.stub
@LimitationsManager = {}
@UserGetter =
getUserByMainEmail: sinon.stub()
getUser: sinon.stub()
@CollaboratorsInviteController = SandboxedModule.require modulePath, requires:
"../Project/ProjectGetter": @ProjectGetter = {}
'../Subscription/LimitationsManager' : @LimitationsManager
'../User/UserGetter': @UserGetter = {getUser: sinon.stub()}
'../User/UserGetter': @UserGetter
"./CollaboratorsHandler": @CollaboratorsHandler = {}
"./CollaboratorsInviteHandler": @CollaboratorsInviteHandler = {}
'logger-sharelatex': @logger = {err: sinon.stub(), error: sinon.stub(), log: sinon.stub()}
@@ -713,7 +716,7 @@ describe "CollaboratorsInviteController", ->
beforeEach ->
@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) ->
@call (err, shouldAllow) =>
@@ -725,7 +728,7 @@ describe "CollaboratorsInviteController", ->
beforeEach ->
@user = null
@UserGetter.getUser = sinon.stub().callsArgWith(2, null, @user)
@UserGetter.getUserByMainEmail = sinon.stub().callsArgWith(2, null, @user)
it 'should callback with `false`', (done) ->
@call (err, shouldAllow) =>
@@ -735,15 +738,15 @@ describe "CollaboratorsInviteController", ->
it 'should have called getUser', (done) ->
@call (err, shouldAllow) =>
@UserGetter.getUser.callCount.should.equal 1
@UserGetter.getUser.calledWith({email: @email}, {_id: 1}).should.equal true
@UserGetter.getUserByMainEmail.callCount.should.equal 1
@UserGetter.getUserByMainEmail.calledWith(@email, {_id: 1}).should.equal true
done()
describe 'when getUser produces an error', ->
beforeEach ->
@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) ->
@call (err, shouldAllow) =>
@@ -605,7 +605,7 @@ describe "CollaboratorsInviteHandler", ->
_id: ObjectId()
first_name: "jim"
@existingUser = {_id: ObjectId()}
@UserGetter.getUser = sinon.stub().callsArgWith(2, null, @existingUser)
@UserGetter.getUserByMainEmail = sinon.stub().callsArgWith(2, null, @existingUser)
@fakeProject =
_id: @project_id
name: "some project"
@@ -626,8 +626,8 @@ describe "CollaboratorsInviteHandler", ->
it 'should call getUser', (done) ->
@call (err) =>
@UserGetter.getUser.callCount.should.equal 1
@UserGetter.getUser.calledWith({email: @invite.email}).should.equal true
@UserGetter.getUserByMainEmail.callCount.should.equal 1
@UserGetter.getUserByMainEmail.calledWith(@invite.email).should.equal true
done()
it 'should call getProject', (done) ->
@@ -671,7 +671,7 @@ describe "CollaboratorsInviteHandler", ->
describe 'when the user does not exist', ->
beforeEach ->
@UserGetter.getUser = sinon.stub().callsArgWith(2, null, null)
@UserGetter.getUserByMainEmail = sinon.stub().callsArgWith(2, null, null)
it 'should not produce an error', (done) ->
@call (err) =>
@@ -680,8 +680,8 @@ describe "CollaboratorsInviteHandler", ->
it 'should call getUser', (done) ->
@call (err) =>
@UserGetter.getUser.callCount.should.equal 1
@UserGetter.getUser.calledWith({email: @invite.email}).should.equal true
@UserGetter.getUserByMainEmail.callCount.should.equal 1
@UserGetter.getUserByMainEmail.calledWith(@invite.email).should.equal true
done()
it 'should not call getProject', (done) ->
@@ -698,7 +698,7 @@ describe "CollaboratorsInviteHandler", ->
describe 'when the getUser produces an error', ->
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) ->
@call (err) =>
@@ -707,8 +707,8 @@ describe "CollaboratorsInviteHandler", ->
it 'should call getUser', (done) ->
@call (err) =>
@UserGetter.getUser.callCount.should.equal 1
@UserGetter.getUser.calledWith({email: @invite.email}).should.equal true
@UserGetter.getUserByMainEmail.callCount.should.equal 1
@UserGetter.getUserByMainEmail.calledWith(@invite.email).should.equal true
done()
it 'should not call getProject', (done) ->
@@ -27,6 +27,11 @@ describe 'ExportsHandler', ->
@project_history_id = 987
@user_id = "user-id-456"
@brand_variation_id = 789
@export_params = {
project_id: @project_id,
brand_variation_id: @brand_variation_id,
user_id: @user_id
}
@callback = sinon.stub()
describe 'exportProject', ->
@@ -35,13 +40,13 @@ describe 'ExportsHandler', ->
@response_body = {iAmAResponseBody: true}
@ExportsHandler._buildExport = sinon.stub().yields(null, @export_data)
@ExportsHandler._requestExport = sinon.stub().yields(null, @response_body)
@ExportsHandler.exportProject @project_id, @user_id, @brand_variation_id, (error, export_data) =>
@ExportsHandler.exportProject @export_params, (error, export_data) =>
@callback(error, export_data)
done()
it "should build the export", ->
@ExportsHandler._buildExport
.calledWith(@project_id, @user_id, @brand_variation_id)
.calledWith(@export_params)
.should.equal true
it "should request the export", ->
@@ -76,7 +81,7 @@ describe 'ExportsHandler', ->
describe "when all goes well", ->
beforeEach (done) ->
@ExportsHandler._buildExport @project_id, @user_id, @brand_variation_id, (error, export_data) =>
@ExportsHandler._buildExport @export_params, (error, export_data) =>
@callback(error, export_data)
done()
@@ -104,10 +109,40 @@ describe 'ExportsHandler', ->
@callback.calledWith(null, expected_export_data)
.should.equal true
describe "when we send replacement user first and last name", ->
beforeEach (done) ->
@custom_first_name = "FIRST"
@custom_last_name = "LAST"
@export_params.first_name = @custom_first_name
@export_params.last_name = @custom_last_name
@ExportsHandler._buildExport @export_params, (error, export_data) =>
@callback(error, export_data)
done()
it "should send the data from the user input", ->
expected_export_data =
project:
id: @project_id
rootDocPath: @rootDocPath
historyId: @project_history_id
historyVersion: @historyVersion
user:
id: @user_id
firstName: @custom_first_name
lastName: @custom_last_name
email: @user.email
orcidId: null
destination:
brandVariationId: @brand_variation_id
options:
callbackUrl: null
@callback.calledWith(null, expected_export_data)
.should.equal true
describe "when project is not found", ->
beforeEach (done) ->
@ProjectGetter.getProject = sinon.stub().yields(new Error("project not found"))
@ExportsHandler._buildExport @project_id, @user_id, @brand_variation_id, (error, export_data) =>
@ExportsHandler._buildExport @export_params, (error, export_data) =>
@callback(error, export_data)
done()
@@ -118,7 +153,7 @@ describe 'ExportsHandler', ->
describe "when project has no root doc", ->
beforeEach (done) ->
@ProjectLocator.findRootDoc = sinon.stub().yields(null, [null, null])
@ExportsHandler._buildExport @project_id, @user_id, @brand_variation_id, (error, export_data) =>
@ExportsHandler._buildExport @export_params, (error, export_data) =>
@callback(error, export_data)
done()
@@ -129,7 +164,7 @@ describe 'ExportsHandler', ->
describe "when user is not found", ->
beforeEach (done) ->
@UserGetter.getUser = sinon.stub().yields(new Error("user not found"))
@ExportsHandler._buildExport @project_id, @user_id, @brand_variation_id, (error, export_data) =>
@ExportsHandler._buildExport @export_params, (error, export_data) =>
@callback(error, export_data)
done()
@@ -140,7 +175,7 @@ describe 'ExportsHandler', ->
describe "when project history request fails", ->
beforeEach (done) ->
@ExportsHandler._requestVersion = sinon.stub().yields(new Error("project history call failed"))
@ExportsHandler._buildExport @project_id, @user_id, @brand_variation_id, (error, export_data) =>
@ExportsHandler._buildExport @export_params, (error, export_data) =>
@callback(error, export_data)
done()
@@ -10,6 +10,7 @@ moment = require('moment')
describe 'RestoreManager', ->
beforeEach ->
tk.freeze Date.now() # freeze the time for these tests
@RestoreManager = SandboxedModule.require modulePath, requires:
'../../infrastructure/FileWriter': @FileWriter = {}
'../Uploads/FileSystemImportManager': @FileSystemImportManager = {}
@@ -22,7 +23,6 @@ describe 'RestoreManager', ->
@project_id = 'mock-project-id'
@version = 42
@callback = sinon.stub()
tk.freeze Date.now() # freeze the time for these tests
afterEach ->
tk.reset()
@@ -16,7 +16,7 @@ describe "PasswordResetHandler", ->
getNewToken:sinon.stub()
getValueFromTokenAndExpire:sinon.stub()
@UserGetter =
getUser:sinon.stub()
getUserByMainEmail:sinon.stub()
@EmailHandler =
sendEmail:sinon.stub()
@AuthenticationManager =
@@ -40,7 +40,7 @@ describe "PasswordResetHandler", ->
describe "generateAndEmailResetToken", ->
it "should check the user exists", (done)->
@UserGetter.getUser.callsArgWith(1)
@UserGetter.getUserByMainEmail.callsArgWith(1)
@OneTimeTokenHandler.getNewToken.callsArgWith(1)
@PasswordResetHandler.generateAndEmailResetToken @user.email, (err, exists)=>
exists.should.equal false
@@ -49,7 +49,7 @@ describe "PasswordResetHandler", ->
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)
@EmailHandler.sendEmail.callsArgWith(2)
@PasswordResetHandler.generateAndEmailResetToken @user.email, (err, exists)=>
@@ -62,7 +62,7 @@ describe "PasswordResetHandler", ->
it "should return exists = false for a holdingAccount", (done) ->
@user.holdingAccount = true
@UserGetter.getUser.callsArgWith(1, null, @user)
@UserGetter.getUserByMainEmail.callsArgWith(1, null, @user)
@OneTimeTokenHandler.getNewToken.callsArgWith(1)
@PasswordResetHandler.generateAndEmailResetToken @user.email, (err, exists)=>
exists.should.equal false
@@ -67,6 +67,7 @@ describe "ProjectController", ->
protectTokens: sinon.stub()
@CollaboratorsHandler =
userIsTokenMember: sinon.stub().callsArgWith(2, null, false)
@ProjectEntityHandler = {}
@Modules =
hooks:
fire: sinon.stub()
@@ -98,6 +99,7 @@ describe "ProjectController", ->
"../TokenAccess/TokenAccessHandler": @TokenAccessHandler
"../Collaborators/CollaboratorsHandler": @CollaboratorsHandler
"../../infrastructure/Modules": @Modules
"./ProjectEntityHandler": @ProjectEntityHandler
@projectName = "£12321jkj9ujkljds"
@req =
@@ -520,7 +522,62 @@ describe "ProjectController", ->
@ProjectUpdateHandler.markAsOpened.calledWith(@project_id).should.equal true
done()
@ProjectController.loadEditor @req, @res
describe 'userProjectsJson', ->
beforeEach (done) ->
projects = [
{archived: true, id: 'a', name: 'A', accessLevel: 'a', somethingElse: 1}
{archived: false, id: 'b', name: 'B', accessLevel: 'b', somethingElse: 1}
{archived: false, id: 'c', name: 'C', accessLevel: 'c', somethingElse: 1}
{archived: false, id: 'd', name: 'D', accessLevel: 'd', somethingElse: 1}
]
@ProjectGetter.findAllUsersProjects = sinon.stub().callsArgWith(2, null, [])
@ProjectController._buildProjectList = sinon.stub().returns(projects)
@AuthenticationController.getLoggedInUserId = sinon.stub().returns 'abc'
done()
it 'should produce a list of projects', (done) ->
@res.json = (data) =>
expect(data).to.deep.equal {
projects: [
{_id: 'b', name: 'B', accessLevel: 'b'},
{_id: 'c', name: 'C', accessLevel: 'c'},
{_id: 'd', name: 'D', accessLevel: 'd'}
]
}
done()
@ProjectController.userProjectsJson @req, @res, @next
describe 'projectEntitiesJson', ->
beforeEach () ->
@AuthenticationController.getLoggedInUserId = sinon.stub().returns 'abc'
@req.params = {Project_id: 'abcd'}
@project = { _id: 'abcd' }
@docs = [
{path: '/things/b.txt', doc: true},
{path: '/main.tex', doc: true}
]
@files = [
{path: '/things/a.txt'}
]
@ProjectGetter.getProject = sinon.stub().callsArgWith(1, null, @project)
@ProjectEntityHandler.getAllEntitiesFromProject = sinon.stub().callsArgWith(1, null, @docs, @files)
it 'should produce a list of entities', (done) ->
@res.json = (data) =>
expect(data).to.deep.equal {
project_id: 'abcd',
entities: [
{path: '/main.tex', type: 'doc'},
{path: '/things/a.txt', type: 'file'},
{path: '/things/b.txt', type: 'doc'}
]
}
expect(@ProjectGetter.getProject.callCount).to.equal 1
expect(@ProjectEntityHandler.getAllEntitiesFromProject.callCount).to.equal 1
done()
@ProjectController.projectEntitiesJson @req, @res, @next
describe '_isInPercentageRollout', ->
before ->
@ids = [
@@ -22,6 +22,7 @@ describe "FeaturesUpdater", ->
describe "refreshFeatures", ->
beforeEach ->
@V1SubscriptionManager.notifyV1OfFeaturesChange = sinon.stub().yields()
@UserFeaturesUpdater.updateFeatures = sinon.stub().yields()
@FeaturesUpdater._getIndividualFeatures = sinon.stub().yields(null, { 'individual': 'features' })
@FeaturesUpdater._getGroupFeatureSets = sinon.stub().yields(null, [{ 'group': 'features' }, { 'group': 'features2' }])
@@ -29,48 +30,63 @@ describe "FeaturesUpdater", ->
@ReferalFeatures.getBonusFeatures = sinon.stub().yields(null, { 'bonus': 'features' })
@FeaturesUpdater._mergeFeatures = sinon.stub().returns({'merged': 'features'})
@callback = sinon.stub()
@FeaturesUpdater.refreshFeatures @user_id, @callback
it "should get the individual features", ->
@FeaturesUpdater._getIndividualFeatures
.calledWith(@user_id)
.should.equal true
describe "normally", ->
beforeEach ->
@FeaturesUpdater.refreshFeatures @user_id, @callback
it "should get the group features", ->
@FeaturesUpdater._getGroupFeatureSets
.calledWith(@user_id)
.should.equal true
it "should get the individual features", ->
@FeaturesUpdater._getIndividualFeatures
.calledWith(@user_id)
.should.equal true
it "should get the v1 features", ->
@FeaturesUpdater._getV1Features
.calledWith(@user_id)
.should.equal true
it "should get the group features", ->
@FeaturesUpdater._getGroupFeatureSets
.calledWith(@user_id)
.should.equal true
it "should get the bonus features", ->
@ReferalFeatures.getBonusFeatures
.calledWith(@user_id)
.should.equal true
it "should get the v1 features", ->
@FeaturesUpdater._getV1Features
.calledWith(@user_id)
.should.equal true
it "should merge from the default features", ->
@FeaturesUpdater._mergeFeatures.calledWith(@Settings.defaultFeatures).should.equal true
it "should get the bonus features", ->
@ReferalFeatures.getBonusFeatures
.calledWith(@user_id)
.should.equal true
it "should merge the individual features", ->
@FeaturesUpdater._mergeFeatures.calledWith(sinon.match.any, { 'individual': 'features' }).should.equal true
it "should merge from the default features", ->
@FeaturesUpdater._mergeFeatures.calledWith(@Settings.defaultFeatures).should.equal true
it "should merge the group features", ->
@FeaturesUpdater._mergeFeatures.calledWith(sinon.match.any, { 'group': 'features' }).should.equal true
@FeaturesUpdater._mergeFeatures.calledWith(sinon.match.any, { 'group': 'features2' }).should.equal true
it "should merge the individual features", ->
@FeaturesUpdater._mergeFeatures.calledWith(sinon.match.any, { 'individual': 'features' }).should.equal true
it "should merge the v1 features", ->
@FeaturesUpdater._mergeFeatures.calledWith(sinon.match.any, { 'v1': 'features' }).should.equal true
it "should merge the group features", ->
@FeaturesUpdater._mergeFeatures.calledWith(sinon.match.any, { 'group': 'features' }).should.equal true
@FeaturesUpdater._mergeFeatures.calledWith(sinon.match.any, { 'group': 'features2' }).should.equal true
it "should merge the bonus features", ->
@FeaturesUpdater._mergeFeatures.calledWith(sinon.match.any, { 'bonus': 'features' }).should.equal true
it "should merge the v1 features", ->
@FeaturesUpdater._mergeFeatures.calledWith(sinon.match.any, { 'v1': 'features' }).should.equal true
it "should update the user with the merged features", ->
@UserFeaturesUpdater.updateFeatures
.calledWith(@user_id, {'merged': 'features'})
.should.equal true
it "should merge the bonus features", ->
@FeaturesUpdater._mergeFeatures.calledWith(sinon.match.any, { 'bonus': 'features' }).should.equal true
it "should update the user with the merged features", ->
@UserFeaturesUpdater.updateFeatures
.calledWith(@user_id, {'merged': 'features'})
.should.equal true
it "should notify v1", ->
@V1SubscriptionManager.notifyV1OfFeaturesChange
.called.should.equal true
describe "with notifyV1 == false", ->
beforeEach ->
@FeaturesUpdater.refreshFeatures @user_id, false, @callback
it "should not notify v1", ->
@V1SubscriptionManager.notifyV1OfFeaturesChange
.called.should.equal false
describe "_mergeFeatures", ->
it "should prefer priority over standard for compileGroup", ->
@@ -116,6 +116,7 @@ describe "RecurlyWrapper", ->
apiKey: 'nonsense'
privateKey: 'private_nonsense'
tk.freeze Date.now() # freeze the time for these tests
@RecurlyWrapper = RecurlyWrapper = SandboxedModule.require modulePath, requires:
"settings-sharelatex": @settings
"logger-sharelatex":
@@ -124,10 +125,11 @@ describe "RecurlyWrapper", ->
log: sinon.stub()
"request": sinon.stub()
describe "sign", ->
after ->
tk.reset()
describe "sign", ->
before (done) ->
tk.freeze Date.now() # freeze the time for these tests
@RecurlyWrapper.sign({
subscription :
plan_code : "gold"
@@ -137,9 +139,6 @@ describe "RecurlyWrapper", ->
done()
)
after ->
tk.reset()
it "should be signed correctly", ->
signed = @signature.split("|")[0]
query = @signature.split("|")[1]
@@ -1061,4 +1060,4 @@ describe "RecurlyWrapper", ->
@RecurlyWrapper.listAccountActiveSubscriptions @user_id, @callback
it "should return an empty array of subscriptions", ->
@callback.calledWith(null, []).should.equal true
@callback.calledWith(null, []).should.equal true
@@ -87,35 +87,69 @@ describe "SubscriptionController", ->
@stubbedCurrencyCode = "GBP"
describe "plansPage", ->
beforeEach (done) ->
beforeEach ->
@req.ip = "1234.3123.3131.333 313.133.445.666 653.5345.5345.534"
@GeoIpLookup.getCurrencyCode.callsArgWith(1, null, @stubbedCurrencyCode)
@res.callback = done
@SubscriptionController.plansPage(@req, @res)
@UserGetter.getUser = sinon.stub().callsArgWith(2, null, @user)
it "should set the recommended currency from the geoiplookup", (done)->
@res.renderedVariables.recomendedCurrency.should.equal(@stubbedCurrencyCode)
@GeoIpLookup.getCurrencyCode.calledWith(@req.ip).should.equal true
done()
describe 'when user is logged in', (done) ->
beforeEach (done) ->
@res.callback = done
@SubscriptionController.plansPage(@req, @res)
it 'should fetch the current user', (done) ->
@UserGetter.getUser.callCount.should.equal 1
done()
it 'should fetch the current user', (done) ->
@UserGetter.getUser.callCount.should.equal 1
done()
it 'should decide not to AB test the plans when signed up before 2016-10-27', (done) ->
@res.renderedVariables.shouldABTestPlans.should.equal false
done()
it 'should decide not to AB test the plans', (done) ->
@res.renderedVariables.shouldABTestPlans.should.equal false
done()
describe 'not dependant on logged in state', (done) ->
# these could have been put in 'when user is not logged in' too
it "should set the recommended currency from the geoiplookup", (done)->
@res.renderedVariables.recomendedCurrency.should.equal(@stubbedCurrencyCode)
@GeoIpLookup.getCurrencyCode.calledWith(@req.ip).should.equal true
done()
it 'should include data for features table', (done) ->
# this is part of AB test. If default wins test, then remove this test
@res.renderedVariables.planFeatures.length.should.not.equal 0
done()
describe 'when user is not logged in', (done) ->
beforeEach (done) ->
@UserGetter =
getUser: sinon.stub().callsArgWith(2, null, null)
@res.callback = done
@SubscriptionController.plansPage(@req, @res)
@AuthenticationController =
getLoggedInUser: sinon.stub().callsArgWith(1, null, null)
getLoggedInUserId: sinon.stub().returns(null)
getSessionUser: sinon.stub().returns(null)
isUserLoggedIn: sinon.stub().returns(false)
beforeEach ->
@AuthenticationController.getLoggedInUserId.returns(null)
@SubscriptionController = SandboxedModule.require modulePath, requires:
'../Authentication/AuthenticationController': @AuthenticationController
'./SubscriptionHandler': @SubscriptionHandler
"./PlansLocator": @PlansLocator
'./SubscriptionViewModelBuilder': @SubscriptionViewModelBuilder
"./LimitationsManager": @LimitationsManager
"../../infrastructure/GeoIpLookup":@GeoIpLookup
"logger-sharelatex":
log:->
warn:->
"settings-sharelatex": @settings
"./SubscriptionDomainHandler":@SubscriptionDomainHandler
"../User/UserGetter": @UserGetter
"./RecurlyWrapper": @RecurlyWrapper = {}
"./FeaturesUpdater": @FeaturesUpdater = {}
it 'should not fetch the current user', (done) ->
@UserGetter.getUser.callCount.should.equal 0
done()
it 'should decide to AB test', (done) ->
@res.renderedVariables.shouldABTestPlans.should.equal true
done()
describe "paymentPage", ->
beforeEach ->
@req.headers = {}
@@ -460,4 +494,4 @@ describe "SubscriptionController", ->
@SubscriptionHandler.updateSubscription.calledWith(@user, "collaborator-annual", "COLLABORATORCODEHERE").should.equal true
done()
@SubscriptionController.processUpgradeToAnnualPlan @req, @res
@SubscriptionController.processUpgradeToAnnualPlan @req, @res
@@ -33,9 +33,9 @@ describe "SubscriptionGroupHandler", ->
addEmailInviteToGroup: sinon.stub().callsArgWith(2)
removeEmailInviteFromGroup: sinon.stub().callsArgWith(2)
@UserLocator =
findById: sinon.stub()
findByEmail: sinon.stub()
@UserGetter =
getUser: sinon.stub()
getUserByMainEmail: sinon.stub()
@LimitationsManager =
hasGroupMembersLimitReached: sinon.stub()
@@ -63,7 +63,7 @@ describe "SubscriptionGroupHandler", ->
"./SubscriptionUpdater": @SubscriptionUpdater
"./SubscriptionLocator": @SubscriptionLocator
"../../models/Subscription": Subscription: @Subscription
"../User/UserLocator": @UserLocator
"../User/UserGetter": @UserGetter
"./LimitationsManager": @LimitationsManager
"../Security/OneTimeTokenHandler":@OneTimeTokenHandler
"../Email/EmailHandler":@EmailHandler
@@ -78,11 +78,11 @@ describe "SubscriptionGroupHandler", ->
describe "addUserToGroup", ->
beforeEach ->
@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)->
@Handler.addUserToGroup @adminUser_id, @newEmail, (err)=>
@UserLocator.findByEmail.calledWith(@newEmail).should.equal true
@UserGetter.getUserByMainEmail.calledWith(@newEmail).should.equal true
done()
it "should add the user to the group", (done)->
@@ -109,7 +109,7 @@ describe "SubscriptionGroupHandler", ->
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)=>
@SubscriptionUpdater.addEmailInviteToGroup.calledWith(@adminUser_id, @newEmail).should.equal true
done()
@@ -155,26 +155,26 @@ describe "SubscriptionGroupHandler", ->
beforeEach ->
@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)->
@UserLocator.findById.callsArgWith(1, null, {_id:"31232"})
@UserGetter.getUser.callsArgWith(1, null, {_id:"31232"})
@Handler.getPopulatedListOfMembers @adminUser_id, (err, users)=>
@SubscriptionLocator.getUsersSubscription.calledWith(@adminUser_id).should.equal true
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"]
@Handler.getPopulatedListOfMembers @adminUser_id, (err, users)=>
@UserLocator.findById.calledWith(@subscription.member_ids[0]).should.equal true
@UserLocator.findById.calledWith(@subscription.member_ids[1]).should.equal true
@UserLocator.findById.calledWith(@subscription.member_ids[2]).should.equal true
@UserGetter.getUser.calledWith(@subscription.member_ids[0]).should.equal true
@UserGetter.getUser.calledWith(@subscription.member_ids[1]).should.equal true
@UserGetter.getUser.calledWith(@subscription.member_ids[2]).should.equal true
users.length.should.equal @subscription.member_ids.length
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"]
@Handler.getPopulatedListOfMembers @adminUser_id, (err, users)=>
assert.deepEqual users[0], {_id:@subscription.member_ids[0]}
@@ -16,10 +16,10 @@ describe 'V1SubscriptionManager', ->
err: sinon.stub()
warn: sinon.stub()
"settings-sharelatex":
overleaf:
host: @host = "http://overleaf.example.com"
apis:
v1:
host: @host = "http://overleaf.example.com"
"request": @request = sinon.stub()
@V1SubscriptionManager._v1PlanRequest = sinon.stub()
@userId = 'abcd'
@v1UserId = 42
@user =
@@ -33,33 +33,20 @@ describe 'V1SubscriptionManager', ->
@responseBody =
id: 32,
plan_name: 'pro'
@UserGetter.getUser = sinon.stub()
.yields(null, @user)
@V1SubscriptionManager._v1PlanRequest = sinon.stub()
@V1SubscriptionManager._v1Request = sinon.stub()
.yields(null, @responseBody)
@call = (cb) =>
@V1SubscriptionManager.getPlanCodeFromV1 @userId, cb
describe 'when all goes well', ->
it 'should call getUser', (done) ->
it 'should call _v1Request', (done) ->
@call (err, planCode) =>
expect(
@UserGetter.getUser.callCount
@V1SubscriptionManager._v1Request.callCount
).to.equal 1
expect(
@UserGetter.getUser.calledWith(@userId)
).to.equal true
done()
it 'should call _v1PlanRequest', (done) ->
@call (err, planCode) =>
expect(
@V1SubscriptionManager._v1PlanRequest.callCount
).to.equal 1
expect(
@V1SubscriptionManager._v1PlanRequest.calledWith(
@v1UserId
@V1SubscriptionManager._v1Request.calledWith(
@userId
)
).to.equal true
done()
@@ -80,49 +67,56 @@ describe 'V1SubscriptionManager', ->
expect(planCode).to.equal null
done()
describe '_v1Request', ->
beforeEach ->
@UserGetter.getUser = sinon.stub()
.yields(null, @user)
describe 'when getUser produces an error', ->
beforeEach ->
@UserGetter.getUser = sinon.stub()
.yields(new Error('woops'))
@call = (cb) =>
@V1SubscriptionManager._v1Request @user_id, { url: () -> '/foo' }, cb
it 'should not call _v1PlanRequest', (done) ->
it 'should not call request', (done) ->
@call (err, planCode) =>
expect(
@V1SubscriptionManager._v1PlanRequest.callCount
@request.callCount
).to.equal 0
done()
it 'should produce an error', (done) ->
@call (err, planCode) =>
expect(err).to.exist
expect(planCode).to.not.exist
done()
describe 'when getUser does not find a user', ->
beforeEach ->
@UserGetter.getUser = sinon.stub()
.yields(null, null)
@call = (cb) =>
@V1SubscriptionManager._v1Request @user_id, { url: () -> '/foo' }, cb
it 'should not call _v1PlanRequest', (done) ->
it 'should not call request', (done) ->
@call (err, planCode) =>
expect(
@V1SubscriptionManager._v1PlanRequest.callCount
@request.callCount
).to.equal 0
done()
it 'should produce a null plan-code, without error', (done) ->
@call (err, planCode) =>
it 'should not error', (done) ->
@call (err) =>
expect(err).to.not.exist
expect(planCode).to.not.exist
done()
describe 'when the request to v1 fails', ->
beforeEach ->
@V1SubscriptionManager._v1PlanRequest = sinon.stub()
.yields(new Error('woops'))
@request.yields(new Error('woops'))
@call = (cb) =>
@V1SubscriptionManager._v1Request @user_id, { url: () -> '/foo' }, cb
it 'should produce an error', (done) ->
@call (err, planCode) =>
@call (err) =>
expect(err).to.exist
expect(planCode).to.not.exist
done()
@@ -0,0 +1,76 @@
should = require('chai').should()
SandboxedModule = require('sandboxed-module')
assert = require('assert')
path = require('path')
sinon = require('sinon')
modulePath = '../../../../app/js/Features/Templates/TemplatesController'
describe 'TemplatesController', ->
project_id = "213432"
beforeEach ->
@request = sinon.stub()
@request.returns {
pipe:->
on:->
}
@fs = {
unlink : sinon.stub()
createWriteStream : sinon.stub().returns(on:(_, cb)->cb())
}
@ProjectUploadManager = {createProjectFromZipArchive : sinon.stub().callsArgWith(3, null, {_id:project_id})}
@dumpFolder = "dump/path"
@ProjectOptionsHandler = {setCompiler:sinon.stub().callsArgWith(2)}
@uuid = "1234"
@ProjectDetailsHandler =
getProjectDescription:sinon.stub()
@Project =
update: sinon.stub().callsArgWith(3, null)
@controller = SandboxedModule.require modulePath, requires:
'../../../js/Features/Uploads/ProjectUploadManager':@ProjectUploadManager
'../../../js/Features/Project/ProjectOptionsHandler':@ProjectOptionsHandler
'../../../js/Features/Authentication/AuthenticationController': @AuthenticationController = {getLoggedInUserId: sinon.stub()}
'./TemplatesPublisher':@TemplatesPublisher
"logger-sharelatex":
log:->
err:->
"settings-sharelatex":
path:
dumpFolder:@dumpFolder
siteUrl: @siteUrl = "http://localhost:3000"
apis:
v1:
url: @v1Url="http://overleaf.com"
user: "sharelatex"
pass: "password"
overleaf:
host: @v1Url
"uuid":v4:=>@uuid
"request": @request
"fs":@fs
"../../../../app/js/models/Project": {Project: @Project}
@zipUrl = "%2Ftemplates%2F52fb86a81ae1e566597a25f6%2Fv%2F4%2Fzip&templateName=Moderncv%20Banking&compiler=pdflatex"
@templateName = "project name here"
@user_id = "1234"
@req =
session:
user: _id:@user_id
templateData:
zipUrl: @zipUrl
templateName: @templateName
@redirect = {}
@AuthenticationController.getLoggedInUserId.returns(@user_id)
describe 'v1Templates', ->
it "should fetch zip from v1 based on template id", (done)->
@templateVersionId = 15
@req.body = {templateVersionId: @templateVersionId}
redirect = =>
@request.calledWith("#{@v1Url}/api/v1/sharelatex/templates/#{@templateVersionId}").should.equal true
done()
res = redirect:redirect
@controller.createProjectFromV1Template @req, res
@@ -30,8 +30,8 @@ describe "UserController", ->
@UserDeleter =
deleteUser: sinon.stub().callsArgWith(1)
@UserLocator =
findById: sinon.stub().callsArgWith(1, null, @user)
@UserGetter =
getUser: sinon.stub().callsArgWith(1, null, @user)
@User =
findById: sinon.stub().callsArgWith(1, null, @user)
@NewsLetterManager =
@@ -63,7 +63,7 @@ describe "UserController", ->
@SudoModeHandler =
clearSudoMode: sinon.stub()
@UserController = SandboxedModule.require modulePath, requires:
"./UserLocator": @UserLocator
"./UserGetter": @UserGetter
"./UserDeleter": @UserDeleter
"./UserUpdater":@UserUpdater
"../../models/User": User:@User
@@ -15,34 +15,16 @@ describe "UserCreator", ->
constructor: ->
return self.user
@UserLocator =
findByEmail: sinon.stub()
@UserGetter =
getUserByMainEmail: sinon.stub()
@UserCreator = SandboxedModule.require modulePath, requires:
"../../models/User": User:@UserModel
"./UserLocator":@UserLocator
"./UserGetter":@UserGetter
"logger-sharelatex":{log:->}
'metrics-sharelatex': {timeAsyncMethod: ()->}
@email = "bob.oswald@gmail.com"
describe "getUserOrCreateHoldingAccount", ->
it "should immediately return the user if found", (done)->
@UserLocator.findByEmail.callsArgWith(1, null, @user)
@UserCreator.getUserOrCreateHoldingAccount @email, (err, returnedUser)=>
assert.deepEqual returnedUser, @user
done()
it "should create new holding account if the user is not found", (done)->
@UserLocator.findByEmail.callsArgWith(1)
@UserCreator.createNewUser = sinon.stub().callsArgWith(1, null, @user)
@UserCreator.getUserOrCreateHoldingAccount @email, (err, returnedUser)=>
@UserCreator.createNewUser.calledWith(email:@email, holdingAccount:true).should.equal true
assert.deepEqual returnedUser, @user
done()
describe "createNewUser", ->
it "should take the opts and put them in the model", (done)->
@@ -0,0 +1,87 @@
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()
describe "getUserByAnyEmail", ->
it "query user for any email", (done)->
email = 'hello@world.com'
expectedQuery =
emails: { $exists: true }
'emails.email': email
projection = emails: 1
@UserGetter.getUserByAnyEmail " #{email} ", projection, (error, user) =>
@findOne.calledWith(expectedQuery, projection).should.equal true
user.should.deep.equal @fakeUser
done()
it "query contains $exists:true so partial index is used", (done)->
expectedQuery =
emails: { $exists: true }
'emails.email': ''
@UserGetter.getUserByAnyEmail '', {}, (error, user) =>
@findOne.calledWith(expectedQuery, {}).should.equal true
done()
it "checks main email as well", (done)->
@findOne.callsArgWith(2, null, null)
email = 'hello@world.com'
projection = emails: 1
@UserGetter.getUserByAnyEmail " #{email} ", projection, (error, user) =>
@findOne.calledTwice.should.equal true
@findOne.calledWith(email: email, projection).should.equal true
done()
@@ -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()
@@ -16,10 +16,7 @@ describe "UserPagesController", ->
features:{}
email: "joe@example.com"
@UserLocator =
findById: sinon.stub().callsArgWith(1, null, @user)
@UserGetter =
getUser: sinon.stub().callsArgWith(2, null, @user)
@UserGetter = getUser: sinon.stub()
@UserSessionsManager =
getAllUserSessions: sinon.stub()
@dropboxStatus = {}
@@ -37,7 +34,6 @@ describe "UserPagesController", ->
"logger-sharelatex":
log:->
err:->
"./UserLocator": @UserLocator
"./UserGetter": @UserGetter
"./UserSessionsManager": @UserSessionsManager
"../Errors/ErrorController": @ErrorController
@@ -136,6 +132,8 @@ describe "UserPagesController", ->
@UserPagesController.sessionsPage @req, @res, @next
describe "settingsPage", ->
beforeEach ->
@UserGetter.getUser = sinon.stub().callsArgWith(1, null, @user)
it "should render user/settings", (done)->
@res.render = (page)->
@@ -185,6 +183,7 @@ describe "UserPagesController", ->
describe "activateAccountPage", ->
beforeEach ->
@UserGetter.getUser = sinon.stub().callsArgWith(2, null, @user)
@req.query.user_id = @user_id
@req.query.token = @token = "mock-token-123"
@@ -12,8 +12,9 @@ describe "UserRegistrationHandler", ->
@user =
_id: @user_id = "31j2lk21kjl"
@User =
findOne:sinon.stub()
update: sinon.stub().callsArgWith(2)
@UserGetter =
getUserByMainEmail: sinon.stub()
@UserCreator =
createNewUser:sinon.stub().callsArgWith(1, null, @user)
@AuthenticationManager =
@@ -26,6 +27,7 @@ describe "UserRegistrationHandler", ->
getNewToken: sinon.stub()
@handler = SandboxedModule.require modulePath, requires:
"../../models/User": {User:@User}
"./UserGetter": @UserGetter
"./UserCreator": @UserCreator
"../Authentication/AuthenticationManager":@AuthenticationManager
"../Newsletter/NewsletterManager":@NewsLetterManager
@@ -70,7 +72,7 @@ describe "UserRegistrationHandler", ->
beforeEach ->
@user.holdingAccount = 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)->
@handler.registerNewUser @passingRequest, (err)=>
@@ -94,7 +96,7 @@ describe "UserRegistrationHandler", ->
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)=>
err.should.deep.equal new Error("EmailAlreadyRegistered")
user.should.deep.equal @user
@@ -103,7 +105,7 @@ describe "UserRegistrationHandler", ->
describe "validRequest", ->
beforeEach ->
@handler._registrationRequestIsValid = sinon.stub().returns true
@User.findOne.callsArgWith 1
@UserGetter.getUserByMainEmail.callsArgWith 1
it "should create a new user", (done)->
@handler.registerNewUser @passingRequest, (err)=>
@@ -14,36 +14,136 @@ describe "UserUpdater", ->
@mongojs =
db:{}
ObjectId:(id)-> return id
@UserLocator =
findByEmail:sinon.stub()
@UserGetter =
getUserEmail: sinon.stub()
getUserByAnyEmail: sinon.stub()
@logger = err: sinon.stub(), log: ->
@UserUpdater = SandboxedModule.require modulePath, requires:
"settings-sharelatex":@settings
"logger-sharelatex": log:->
"./UserLocator":@UserLocator
"logger-sharelatex": @logger
"./UserGetter": @UserGetter
"../../infrastructure/mongojs":@mongojs
"metrics-sharelatex": timeAsyncMethod: sinon.stub()
@stubbedUser =
_id: "3131231"
name:"bob"
email:"hello@world.com"
@user_id = "3131231"
@newEmail = "bob@bob.com"
describe "changeEmailAddress", ->
describe 'changeEmailAddress', ->
beforeEach ->
@UserUpdater.updateUser = sinon.stub().callsArgWith(2)
@UserGetter.getUserEmail.callsArgWith(1, null, @stubbedUser.email)
@UserUpdater.addEmailAddress = sinon.stub().callsArgWith(2)
@UserUpdater.setDefaultEmailAddress = sinon.stub().callsArgWith(2)
@UserUpdater.removeEmailAddress = sinon.stub().callsArgWith(2)
it "should check if the new email already has an account", (done)->
@UserLocator.findByEmail.callsArgWith(1, null, @stubbedUser)
@UserUpdater.changeEmailAddress @user_id, @stubbedUser.email, (err)=>
@UserUpdater.updateUser.called.should.equal false
it 'change email', (done)->
@UserUpdater.changeEmailAddress @stubbedUser._id, @newEmail, (err)=>
should.not.exist(err)
@UserUpdater.addEmailAddress.calledWith(
@stubbedUser._id, @newEmail
).should.equal true
@UserUpdater.setDefaultEmailAddress.calledWith(
@stubbedUser._id, @newEmail
).should.equal true
@UserUpdater.removeEmailAddress.calledWith(
@stubbedUser._id, @stubbedUser.email
).should.equal true
done()
it 'handle error', (done)->
@UserUpdater.removeEmailAddress.callsArgWith(2, new Error('nope'))
@UserUpdater.changeEmailAddress @stubbedUser._id, @newEmail, (err)=>
should.exist(err)
done()
describe 'addEmailAddress', ->
beforeEach ->
@UserUpdater._ensureUniqueEmailAddress = sinon.stub().callsArgWith(1)
it 'add email', (done)->
@UserUpdater.updateUser = sinon.stub().callsArgWith(2, null)
@UserUpdater.addEmailAddress @stubbedUser._id, @newEmail, (err)=>
@UserUpdater._ensureUniqueEmailAddress.called.should.equal true
should.not.exist(err)
@UserUpdater.updateUser.calledWith(
@stubbedUser._id,
$push: { emails: { email: @newEmail, createdAt: sinon.match.date } }
).should.equal true
done()
it 'handle error', (done)->
@UserUpdater.updateUser = sinon.stub().callsArgWith(2, new Error('nope'))
@UserUpdater.addEmailAddress @stubbedUser._id, @newEmail, (err)=>
@logger.err.called.should.equal true
should.exist(err)
done()
describe 'removeEmailAddress', ->
it 'remove email', (done)->
@UserUpdater.updateUser = sinon.stub().callsArgWith(2, null, nMatched: 1)
@UserUpdater.removeEmailAddress @stubbedUser._id, @newEmail, (err)=>
should.not.exist(err)
@UserUpdater.updateUser.calledWith(
{ _id: @stubbedUser._id, email: { $ne: @newEmail } },
$pull: { emails: { email: @newEmail } }
).should.equal true
done()
it 'handle error', (done)->
@UserUpdater.updateUser = sinon.stub().callsArgWith(2, new Error('nope'))
@UserUpdater.removeEmailAddress @stubbedUser._id, @newEmail, (err)=>
should.exist(err)
done()
it 'handle missed update', (done)->
@UserUpdater.updateUser = sinon.stub().callsArgWith(2, null, nMatched: 0)
@UserUpdater.removeEmailAddress @stubbedUser._id, @newEmail, (err)=>
should.exist(err)
done()
describe 'setDefaultEmailAddress', ->
it 'set default', (done)->
@UserUpdater.updateUser = sinon.stub().callsArgWith(2, null, nMatched: 1)
@UserUpdater.setDefaultEmailAddress @stubbedUser._id, @newEmail, (err)=>
should.not.exist(err)
@UserUpdater.updateUser.calledWith(
{ _id: @stubbedUser._id, 'emails.email': @newEmail },
$set: { email: @newEmail }
).should.equal true
done()
it 'handle error', (done)->
@UserUpdater.updateUser = sinon.stub().callsArgWith(2, new Error('nope'))
@UserUpdater.setDefaultEmailAddress @stubbedUser._id, @newEmail, (err)=>
should.exist(err)
done()
it 'handle missed update', (done)->
@UserUpdater.updateUser = sinon.stub().callsArgWith(2, null, nMatched: 0)
@UserUpdater.setDefaultEmailAddress @stubbedUser._id, @newEmail, (err)=>
should.exist(err)
done()
it "should set the users password", (done)->
@UserLocator.findByEmail.callsArgWith(1, null)
@UserUpdater.changeEmailAddress @user_id, @newEmail, (err)=>
@UserUpdater.updateUser.calledWith(@user_id, $set: { "email": @newEmail}).should.equal true
describe '_ensureUniqueEmailAddress', ->
it 'should return error if existing user is found', (done)->
@UserGetter.getUserByAnyEmail.callsArgWith(1, null, @stubbedUser)
@UserUpdater._ensureUniqueEmailAddress @newEmail, (err)=>
should.exist(err)
done()
it 'should return null if no user is found', (done)->
@UserGetter.getUserByAnyEmail.callsArgWith(1)
@UserUpdater._ensureUniqueEmailAddress @newEmail, (err)=>
should.not.exist(err)
done()