overleaf/services/web/test/unit/src/User/UserUpdaterTests.js

511 lines
14 KiB
JavaScript
Raw Normal View History

/* eslint-disable
max-len,
no-return-assign,
no-unused-vars,
*/
// TODO: This file was created by bulk-decaffeinate.
// Fix any style issues and re-enable lint.
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
const should = require('chai').should()
const SandboxedModule = require('sandboxed-module')
const assert = require('assert')
const path = require('path')
const sinon = require('sinon')
const modulePath = path.join(
__dirname,
'../../../../app/src/Features/User/UserUpdater'
)
const { expect } = require('chai')
const tk = require('timekeeper')
describe('UserUpdater', function() {
beforeEach(function() {
tk.freeze(Date.now())
this.mongojs = {
db: {},
ObjectId(id) {
return id
}
}
this.UserGetter = {
getUserEmail: sinon.stub(),
getUserByAnyEmail: sinon.stub(),
ensureUniqueEmailAddress: sinon.stub()
}
this.logger = {
err: sinon.stub(),
log() {},
warn() {}
}
this.addAffiliation = sinon.stub().yields()
this.removeAffiliation = sinon.stub().callsArgWith(2, null)
this.refreshFeatures = sinon.stub().yields()
this.NewsletterManager = { changeEmail: sinon.stub() }
this.UserUpdater = SandboxedModule.require(modulePath, {
requires: {
'logger-sharelatex': this.logger,
'../../infrastructure/mongojs': this.mongojs,
'metrics-sharelatex': {
timeAsyncMethod: sinon.stub()
},
'./UserGetter': this.UserGetter,
'../Institutions/InstitutionsAPI': {
addAffiliation: this.addAffiliation,
removeAffiliation: this.removeAffiliation
},
'../Subscription/FeaturesUpdater': {
refreshFeatures: this.refreshFeatures
},
'settings-sharelatex': (this.settings = {}),
request: (this.request = {}),
'../Newsletter/NewsletterManager': this.NewsletterManager
}
})
this.stubbedUser = {
_id: '3131231',
name: 'bob',
email: 'hello@world.com'
}
return (this.newEmail = 'bob@bob.com')
})
afterEach(() => tk.reset())
describe('changeEmailAddress', function() {
beforeEach(function() {
this.UserGetter.getUserEmail.callsArgWith(1, null, this.stubbedUser.email)
this.UserUpdater.addEmailAddress = sinon.stub().callsArgWith(2)
this.UserUpdater.setDefaultEmailAddress = sinon.stub().callsArgWith(2)
return (this.UserUpdater.removeEmailAddress = sinon
.stub()
.callsArgWith(2))
})
it('change email', function(done) {
return this.UserUpdater.changeEmailAddress(
this.stubbedUser._id,
this.newEmail,
err => {
should.not.exist(err)
this.UserUpdater.addEmailAddress
.calledWith(this.stubbedUser._id, this.newEmail)
.should.equal(true)
this.UserUpdater.setDefaultEmailAddress
.calledWith(this.stubbedUser._id, this.newEmail)
.should.equal(true)
this.UserUpdater.removeEmailAddress
.calledWith(this.stubbedUser._id, this.stubbedUser.email)
.should.equal(true)
return done()
}
)
})
it('validates email', function(done) {
return this.UserUpdater.changeEmailAddress(
this.stubbedUser._id,
'foo',
err => {
should.exist(err)
return done()
}
)
})
return it('handle error', function(done) {
this.UserUpdater.removeEmailAddress.callsArgWith(2, new Error('nope'))
return this.UserUpdater.changeEmailAddress(
this.stubbedUser._id,
this.newEmail,
err => {
should.exist(err)
return done()
}
)
})
})
describe('addEmailAddress', function() {
beforeEach(function() {
this.UserGetter.ensureUniqueEmailAddress = sinon.stub().callsArgWith(1)
return (this.UserUpdater.updateUser = sinon.stub().callsArgWith(2, null))
})
it('add email', function(done) {
return this.UserUpdater.addEmailAddress(
this.stubbedUser._id,
this.newEmail,
err => {
this.UserGetter.ensureUniqueEmailAddress.called.should.equal(true)
should.not.exist(err)
const reversedHostname = this.newEmail
.split('@')[1]
.split('')
.reverse()
.join('')
this.UserUpdater.updateUser
.calledWith(this.stubbedUser._id, {
$push: {
emails: {
email: this.newEmail,
createdAt: sinon.match.date,
reversedHostname
}
}
})
.should.equal(true)
return done()
}
)
})
it('add affiliation', function(done) {
const affiliationOptions = {
university: { id: 1 },
role: 'Prof',
department: 'Math'
}
return this.UserUpdater.addEmailAddress(
this.stubbedUser._id,
this.newEmail,
affiliationOptions,
err => {
should.not.exist(err)
this.addAffiliation.calledOnce.should.equal(true)
const { args } = this.addAffiliation.lastCall
args[0].should.equal(this.stubbedUser._id)
args[1].should.equal(this.newEmail)
args[2].should.equal(affiliationOptions)
return done()
}
)
})
it('handle error', function(done) {
this.UserUpdater.updateUser = sinon
.stub()
.callsArgWith(2, new Error('nope'))
return this.UserUpdater.addEmailAddress(
this.stubbedUser._id,
this.newEmail,
err => {
this.logger.err.called.should.equal(true)
should.exist(err)
return done()
}
)
})
it('handle affiliation error', function(done) {
const body = { errors: 'affiliation error message' }
this.addAffiliation.callsArgWith(3, new Error('nope'))
return this.UserUpdater.addEmailAddress(
this.stubbedUser._id,
this.newEmail,
err => {
should.exist(err)
this.UserUpdater.updateUser.called.should.equal(false)
return done()
}
)
})
return it('validates email', function(done) {
return this.UserUpdater.addEmailAddress(
this.stubbedUser._id,
'bar',
err => {
should.exist(err)
return done()
}
)
})
})
describe('removeEmailAddress', function() {
beforeEach(function() {
return (this.UserUpdater.updateUser = sinon
.stub()
.callsArgWith(2, null, { nMatched: 1 }))
})
it('remove email', function(done) {
return this.UserUpdater.removeEmailAddress(
this.stubbedUser._id,
this.newEmail,
err => {
should.not.exist(err)
this.UserUpdater.updateUser
.calledWith(
{ _id: this.stubbedUser._id, email: { $ne: this.newEmail } },
{ $pull: { emails: { email: this.newEmail } } }
)
.should.equal(true)
return done()
}
)
})
it('remove affiliation', function(done) {
return this.UserUpdater.removeEmailAddress(
this.stubbedUser._id,
this.newEmail,
err => {
should.not.exist(err)
this.removeAffiliation.calledOnce.should.equal(true)
const { args } = this.removeAffiliation.lastCall
args[0].should.equal(this.stubbedUser._id)
args[1].should.equal(this.newEmail)
return done()
}
)
})
it('handle error', function(done) {
this.UserUpdater.updateUser = sinon
.stub()
.callsArgWith(2, new Error('nope'))
return this.UserUpdater.removeEmailAddress(
this.stubbedUser._id,
this.newEmail,
err => {
should.exist(err)
return done()
}
)
})
it('handle missed update', function(done) {
this.UserUpdater.updateUser = sinon.stub().callsArgWith(2, null, { n: 0 })
return this.UserUpdater.removeEmailAddress(
this.stubbedUser._id,
this.newEmail,
err => {
should.exist(err)
return done()
}
)
})
it('handle affiliation error', function(done) {
this.removeAffiliation.callsArgWith(2, new Error('nope'))
return this.UserUpdater.removeEmailAddress(
this.stubbedUser._id,
this.newEmail,
err => {
should.exist(err)
this.UserUpdater.updateUser.called.should.equal(false)
return done()
}
)
})
return it('validates email', function(done) {
return this.UserUpdater.removeEmailAddress(
this.stubbedUser._id,
'baz',
err => {
should.exist(err)
return done()
}
)
})
})
describe('setDefaultEmailAddress', function() {
beforeEach(function() {
this.UserGetter.getUserEmail.callsArgWith(1, null, this.stubbedUser.email)
return this.NewsletterManager.changeEmail.callsArgWith(2, null)
})
it('set default', function(done) {
this.UserUpdater.updateUser = sinon.stub().callsArgWith(2, null, { n: 1 })
return this.UserUpdater.setDefaultEmailAddress(
this.stubbedUser._id,
this.newEmail,
err => {
should.not.exist(err)
this.UserUpdater.updateUser
.calledWith(
{ _id: this.stubbedUser._id, 'emails.email': this.newEmail },
{ $set: { email: this.newEmail } }
)
.should.equal(true)
return done()
}
)
})
it('set changed the email in newsletter', function(done) {
this.UserUpdater.updateUser = sinon.stub().callsArgWith(2, null, { n: 1 })
return this.UserUpdater.setDefaultEmailAddress(
this.stubbedUser._id,
this.newEmail,
err => {
should.not.exist(err)
this.NewsletterManager.changeEmail
.calledWith(this.stubbedUser.email, this.newEmail)
.should.equal(true)
return done()
}
)
})
it('handle error', function(done) {
this.UserUpdater.updateUser = sinon
.stub()
.callsArgWith(2, new Error('nope'))
return this.UserUpdater.setDefaultEmailAddress(
this.stubbedUser._id,
this.newEmail,
err => {
should.exist(err)
return done()
}
)
})
it('handle missed update', function(done) {
this.UserUpdater.updateUser = sinon.stub().callsArgWith(2, null, { n: 0 })
return this.UserUpdater.setDefaultEmailAddress(
this.stubbedUser._id,
this.newEmail,
err => {
should.exist(err)
return done()
}
)
})
return it('validates email', function(done) {
return this.UserUpdater.setDefaultEmailAddress(
this.stubbedUser._id,
'.edu',
err => {
should.exist(err)
return done()
}
)
})
})
return describe('confirmEmail', function() {
beforeEach(function() {
return (this.UserUpdater.updateUser = sinon
.stub()
.callsArgWith(2, null, { n: 1 }))
})
it('should update the email record', function(done) {
return this.UserUpdater.confirmEmail(
this.stubbedUser._id,
this.newEmail,
err => {
should.not.exist(err)
this.UserUpdater.updateUser
.calledWith(
{ _id: this.stubbedUser._id, 'emails.email': this.newEmail },
{ $set: { 'emails.$.confirmedAt': new Date() } }
)
.should.equal(true)
return done()
}
)
})
it('add affiliation', function(done) {
return this.UserUpdater.confirmEmail(
this.stubbedUser._id,
this.newEmail,
err => {
should.not.exist(err)
this.addAffiliation.calledOnce.should.equal(true)
sinon.assert.calledWith(
this.addAffiliation,
this.stubbedUser._id,
this.newEmail,
{ confirmedAt: new Date() }
)
return done()
}
)
})
it('handle error', function(done) {
this.UserUpdater.updateUser = sinon
.stub()
.callsArgWith(2, new Error('nope'))
return this.UserUpdater.confirmEmail(
this.stubbedUser._id,
this.newEmail,
err => {
should.exist(err)
return done()
}
)
})
it('handle missed update', function(done) {
this.UserUpdater.updateUser = sinon.stub().callsArgWith(2, null, { n: 0 })
return this.UserUpdater.confirmEmail(
this.stubbedUser._id,
this.newEmail,
err => {
should.exist(err)
return done()
}
)
})
it('validates email', function(done) {
return this.UserUpdater.confirmEmail(this.stubbedUser._id, '@', err => {
should.exist(err)
return done()
})
})
it('handle affiliation error', function(done) {
this.addAffiliation.callsArgWith(3, new Error('nope'))
return this.UserUpdater.confirmEmail(
this.stubbedUser._id,
this.newEmail,
err => {
should.exist(err)
this.UserUpdater.updateUser.called.should.equal(false)
return done()
}
)
})
return it('refresh features', function(done) {
return this.UserUpdater.confirmEmail(
this.stubbedUser._id,
this.newEmail,
err => {
should.not.exist(err)
sinon.assert.calledWith(
this.refreshFeatures,
this.stubbedUser._id,
true
)
return done()
}
)
})
})
})