|
@@ -13,9 +13,15 @@ describe('UserEmailsController', function() {
|
|
|
beforeEach(function() {
|
|
beforeEach(function() {
|
|
|
this.req = new MockRequest()
|
|
this.req = new MockRequest()
|
|
|
this.res = new MockResponse()
|
|
this.res = new MockResponse()
|
|
|
- this.user = { _id: 'mock-user-id' }
|
|
|
|
|
|
|
+ this.next = sinon.stub()
|
|
|
|
|
+ this.user = { _id: 'mock-user-id', email: 'example@overleaf.com' }
|
|
|
|
|
|
|
|
- this.UserGetter = { getUserFullEmails: sinon.stub() }
|
|
|
|
|
|
|
+ this.UserGetter = {
|
|
|
|
|
+ getUserFullEmails: sinon.stub(),
|
|
|
|
|
+ promises: {
|
|
|
|
|
+ getUser: sinon.stub().resolves(this.user)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
this.AuthenticationController = {
|
|
this.AuthenticationController = {
|
|
|
getLoggedInUserId: sinon.stub().returns(this.user._id),
|
|
getLoggedInUserId: sinon.stub().returns(this.user._id),
|
|
|
setInSessionUser: sinon.stub()
|
|
setInSessionUser: sinon.stub()
|
|
@@ -27,7 +33,10 @@ describe('UserEmailsController', function() {
|
|
|
addEmailAddress: sinon.stub(),
|
|
addEmailAddress: sinon.stub(),
|
|
|
removeEmailAddress: sinon.stub(),
|
|
removeEmailAddress: sinon.stub(),
|
|
|
setDefaultEmailAddress: sinon.stub(),
|
|
setDefaultEmailAddress: sinon.stub(),
|
|
|
- updateV1AndSetDefaultEmailAddress: sinon.stub()
|
|
|
|
|
|
|
+ updateV1AndSetDefaultEmailAddress: sinon.stub(),
|
|
|
|
|
+ promises: {
|
|
|
|
|
+ addEmailAddress: sinon.stub().resolves()
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
this.EmailHelper = { parseEmail: sinon.stub() }
|
|
this.EmailHelper = { parseEmail: sinon.stub() }
|
|
|
this.endorseAffiliation = sinon.stub().yields()
|
|
this.endorseAffiliation = sinon.stub().yields()
|
|
@@ -51,8 +60,17 @@ describe('UserEmailsController', function() {
|
|
|
'../../infrastructure/Features': this.Features,
|
|
'../../infrastructure/Features': this.Features,
|
|
|
'./UserGetter': this.UserGetter,
|
|
'./UserGetter': this.UserGetter,
|
|
|
'./UserUpdater': this.UserUpdater,
|
|
'./UserUpdater': this.UserUpdater,
|
|
|
|
|
+ '../Email/EmailHandler': (this.EmailHandler = {
|
|
|
|
|
+ promises: {
|
|
|
|
|
+ sendEmail: sinon.stub().resolves()
|
|
|
|
|
+ }
|
|
|
|
|
+ }),
|
|
|
'../Helpers/EmailHelper': this.EmailHelper,
|
|
'../Helpers/EmailHelper': this.EmailHelper,
|
|
|
- './UserEmailsConfirmationHandler': (this.UserEmailsConfirmationHandler = {}),
|
|
|
|
|
|
|
+ './UserEmailsConfirmationHandler': (this.UserEmailsConfirmationHandler = {
|
|
|
|
|
+ promises: {
|
|
|
|
|
+ sendConfirmationEmail: sinon.stub().resolves()
|
|
|
|
|
+ }
|
|
|
|
|
+ }),
|
|
|
'../Institutions/InstitutionsAPI': this.InstitutionsAPI,
|
|
'../Institutions/InstitutionsAPI': this.InstitutionsAPI,
|
|
|
'../Errors/HttpErrorHandler': this.HttpErrorHandler,
|
|
'../Errors/HttpErrorHandler': this.HttpErrorHandler,
|
|
|
'../Errors/Errors': Errors,
|
|
'../Errors/Errors': Errors,
|
|
@@ -96,69 +114,94 @@ describe('UserEmailsController', function() {
|
|
|
this.UserEmailsConfirmationHandler.sendConfirmationEmail = sinon
|
|
this.UserEmailsConfirmationHandler.sendConfirmationEmail = sinon
|
|
|
.stub()
|
|
.stub()
|
|
|
.yields()
|
|
.yields()
|
|
|
- this.UserUpdater.addEmailAddress.callsArgWith(3, null)
|
|
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('adds new email', function(done) {
|
|
it('adds new email', function(done) {
|
|
|
- this.UserEmailsController.add(this.req, {
|
|
|
|
|
- sendStatus: code => {
|
|
|
|
|
- code.should.equal(204)
|
|
|
|
|
- assertCalledWith(this.EmailHelper.parseEmail, this.newEmail)
|
|
|
|
|
- assertCalledWith(
|
|
|
|
|
- this.UserUpdater.addEmailAddress,
|
|
|
|
|
- this.user._id,
|
|
|
|
|
- this.newEmail
|
|
|
|
|
- )
|
|
|
|
|
-
|
|
|
|
|
- const affiliationOptions = this.UserUpdater.addEmailAddress.lastCall
|
|
|
|
|
- .args[2]
|
|
|
|
|
- Object.keys(affiliationOptions).length.should.equal(3)
|
|
|
|
|
- affiliationOptions.university.should.equal(this.req.body.university)
|
|
|
|
|
- affiliationOptions.department.should.equal(this.req.body.department)
|
|
|
|
|
- affiliationOptions.role.should.equal(this.req.body.role)
|
|
|
|
|
|
|
+ this.UserEmailsController.add(
|
|
|
|
|
+ this.req,
|
|
|
|
|
+ {
|
|
|
|
|
+ sendStatus: code => {
|
|
|
|
|
+ code.should.equal(204)
|
|
|
|
|
+ assertCalledWith(this.EmailHelper.parseEmail, this.newEmail)
|
|
|
|
|
+ assertCalledWith(
|
|
|
|
|
+ this.UserUpdater.promises.addEmailAddress,
|
|
|
|
|
+ this.user._id,
|
|
|
|
|
+ this.newEmail
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ const affiliationOptions = this.UserUpdater.promises.addEmailAddress
|
|
|
|
|
+ .lastCall.args[2]
|
|
|
|
|
+ Object.keys(affiliationOptions).length.should.equal(3)
|
|
|
|
|
+ affiliationOptions.university.should.equal(this.req.body.university)
|
|
|
|
|
+ affiliationOptions.department.should.equal(this.req.body.department)
|
|
|
|
|
+ affiliationOptions.role.should.equal(this.req.body.role)
|
|
|
|
|
+
|
|
|
|
|
+ done()
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ this.next
|
|
|
|
|
+ )
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
- done()
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ it('sends a security alert email', async function() {
|
|
|
|
|
+ await this.UserEmailsController.promises.add(
|
|
|
|
|
+ this.req,
|
|
|
|
|
+ this.res,
|
|
|
|
|
+ this.next
|
|
|
|
|
+ )
|
|
|
|
|
+ const emailCall = this.EmailHandler.promises.sendEmail.getCall(0)
|
|
|
|
|
+ emailCall.args[0].should.to.equal('securityAlert')
|
|
|
|
|
+ emailCall.args[1].to.should.equal(this.user.email)
|
|
|
|
|
+ emailCall.args[1].actionDescribed.should.contain(
|
|
|
|
|
+ 'a secondary email address'
|
|
|
|
|
+ )
|
|
|
|
|
+ emailCall.args[1].to.should.equal(this.user.email)
|
|
|
|
|
+ emailCall.args[1].message[0].should.contain(this.newEmail)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('sends an email confirmation', function(done) {
|
|
it('sends an email confirmation', function(done) {
|
|
|
- this.UserEmailsController.add(this.req, {
|
|
|
|
|
- sendStatus: code => {
|
|
|
|
|
- code.should.equal(204)
|
|
|
|
|
- assertCalledWith(
|
|
|
|
|
- this.UserEmailsConfirmationHandler.sendConfirmationEmail,
|
|
|
|
|
- this.user._id,
|
|
|
|
|
- this.newEmail
|
|
|
|
|
- )
|
|
|
|
|
- done()
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ this.UserEmailsController.add(
|
|
|
|
|
+ this.req,
|
|
|
|
|
+ {
|
|
|
|
|
+ sendStatus: code => {
|
|
|
|
|
+ code.should.equal(204)
|
|
|
|
|
+ assertCalledWith(
|
|
|
|
|
+ this.UserEmailsConfirmationHandler.promises.sendConfirmationEmail,
|
|
|
|
|
+ this.user._id,
|
|
|
|
|
+ this.newEmail
|
|
|
|
|
+ )
|
|
|
|
|
+ done()
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ this.next
|
|
|
|
|
+ )
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('handles email parse error', function(done) {
|
|
it('handles email parse error', function(done) {
|
|
|
this.EmailHelper.parseEmail.returns(null)
|
|
this.EmailHelper.parseEmail.returns(null)
|
|
|
- this.UserEmailsController.add(this.req, {
|
|
|
|
|
- sendStatus: code => {
|
|
|
|
|
- code.should.equal(422)
|
|
|
|
|
- assertNotCalled(this.UserUpdater.addEmailAddress)
|
|
|
|
|
- done()
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ this.UserEmailsController.add(
|
|
|
|
|
+ this.req,
|
|
|
|
|
+ {
|
|
|
|
|
+ sendStatus: code => {
|
|
|
|
|
+ code.should.equal(422)
|
|
|
|
|
+ assertNotCalled(this.UserUpdater.promises.addEmailAddress)
|
|
|
|
|
+ done()
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ this.next
|
|
|
|
|
+ )
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should pass the error to the next handler when adding the email fails', function(done) {
|
|
it('should pass the error to the next handler when adding the email fails', function(done) {
|
|
|
- this.UserUpdater.addEmailAddress.callsArgWith(3, new Error())
|
|
|
|
|
- this.next = sinon.spy(error => {
|
|
|
|
|
- expect(error).instanceOf(Error)
|
|
|
|
|
|
|
+ this.UserUpdater.promises.addEmailAddress.rejects(new Error())
|
|
|
|
|
+ this.UserEmailsController.add(this.req, this.res, error => {
|
|
|
|
|
+ expect(error).to.be.instanceof(Error)
|
|
|
done()
|
|
done()
|
|
|
})
|
|
})
|
|
|
- this.UserEmailsController.add(this.req, this.res, this.next)
|
|
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should call the HTTP conflict handler when the email already exists', function(done) {
|
|
it('should call the HTTP conflict handler when the email already exists', function(done) {
|
|
|
- this.UserUpdater.addEmailAddress.callsArgWith(
|
|
|
|
|
- 3,
|
|
|
|
|
|
|
+ this.UserUpdater.promises.addEmailAddress.rejects(
|
|
|
new Errors.EmailExistsError()
|
|
new Errors.EmailExistsError()
|
|
|
)
|
|
)
|
|
|
this.HttpErrorHandler.conflict = sinon.spy((req, res, message) => {
|
|
this.HttpErrorHandler.conflict = sinon.spy((req, res, message) => {
|
|
@@ -167,12 +210,11 @@ describe('UserEmailsController', function() {
|
|
|
message.should.equal('email_already_registered')
|
|
message.should.equal('email_already_registered')
|
|
|
done()
|
|
done()
|
|
|
})
|
|
})
|
|
|
- this.UserEmailsController.add(this.req, this.res)
|
|
|
|
|
|
|
+ this.UserEmailsController.add(this.req, this.res, this.next)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it("should call the HTTP conflict handler when there's a domain matching error", function(done) {
|
|
it("should call the HTTP conflict handler when there's a domain matching error", function(done) {
|
|
|
- this.UserUpdater.addEmailAddress.callsArgWith(
|
|
|
|
|
- 3,
|
|
|
|
|
|
|
+ this.UserUpdater.promises.addEmailAddress.rejects(
|
|
|
new Error('422: Email does not belong to university')
|
|
new Error('422: Email does not belong to university')
|
|
|
)
|
|
)
|
|
|
this.HttpErrorHandler.conflict = sinon.spy((req, res, message) => {
|
|
this.HttpErrorHandler.conflict = sinon.spy((req, res, message) => {
|
|
@@ -181,7 +223,7 @@ describe('UserEmailsController', function() {
|
|
|
message.should.equal('email_does_not_belong_to_university')
|
|
message.should.equal('email_does_not_belong_to_university')
|
|
|
done()
|
|
done()
|
|
|
})
|
|
})
|
|
|
- this.UserEmailsController.add(this.req, this.res)
|
|
|
|
|
|
|
+ this.UserEmailsController.add(this.req, this.res, this.next)
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
|