2019-09-18 11:22:27 -04:00
|
|
|
const SandboxedModule = require('sandboxed-module')
|
|
|
|
const sinon = require('sinon')
|
2021-03-31 08:20:55 -04:00
|
|
|
const { assert } = require('chai')
|
2019-09-18 11:22:27 -04:00
|
|
|
|
2019-05-29 05:21:06 -04:00
|
|
|
const modulePath = '../../../../app/src/Features/User/UserCreator.js'
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('UserCreator', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
const self = this
|
|
|
|
this.user = { _id: '12390i', ace: {} }
|
2019-09-18 11:22:27 -04:00
|
|
|
this.user.save = sinon.stub().resolves(self.user)
|
|
|
|
this.UserModel = class Project {
|
2019-05-29 05:21:06 -04:00
|
|
|
constructor() {
|
|
|
|
return self.user
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.UserCreator = SandboxedModule.require(modulePath, {
|
|
|
|
requires: {
|
|
|
|
'../../models/User': {
|
2021-04-27 03:52:58 -04:00
|
|
|
User: this.UserModel,
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
2020-10-30 04:10:50 -04:00
|
|
|
'@overleaf/metrics': { timeAsyncMethod() {} },
|
2020-02-20 11:08:40 -05:00
|
|
|
'../../infrastructure/Features': (this.Features = {
|
2021-04-27 03:52:58 -04:00
|
|
|
hasFeature: sinon.stub().returns(false),
|
2020-02-20 11:08:40 -05:00
|
|
|
}),
|
2020-09-01 08:37:09 -04:00
|
|
|
'./UserDeleter': (this.UserDeleter = {
|
|
|
|
promises: {
|
2021-04-27 03:52:58 -04:00
|
|
|
deleteNewUser: sinon.stub().resolves(),
|
|
|
|
},
|
2020-09-01 08:37:09 -04:00
|
|
|
}),
|
2020-02-20 11:08:40 -05:00
|
|
|
'./UserGetter': (this.UserGetter = {
|
|
|
|
promises: {
|
2021-04-27 03:52:58 -04:00
|
|
|
getUser: sinon.stub().resolves(this.user),
|
|
|
|
},
|
2020-02-20 11:08:40 -05:00
|
|
|
}),
|
|
|
|
'./UserUpdater': (this.UserUpdater = {
|
|
|
|
promises: {
|
|
|
|
addAffiliationForNewUser: sinon
|
|
|
|
.stub()
|
|
|
|
.resolves({ n: 1, nModified: 1, ok: 1 }),
|
2021-04-27 03:52:58 -04:00
|
|
|
updateUser: sinon.stub().resolves(),
|
|
|
|
},
|
2021-03-10 04:20:55 -05:00
|
|
|
}),
|
|
|
|
'../Analytics/AnalyticsManager': (this.Analytics = {
|
2021-04-27 03:52:58 -04:00
|
|
|
recordEvent: sinon.stub(),
|
2021-03-31 05:24:39 -04:00
|
|
|
}),
|
|
|
|
'./UserOnboardingEmailManager': (this.UserOnboardingEmailManager = {
|
2021-04-27 03:52:58 -04:00
|
|
|
scheduleOnboardingEmail: sinon.stub(),
|
|
|
|
}),
|
|
|
|
},
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2019-09-18 11:22:27 -04:00
|
|
|
this.email = 'bob.oswald@gmail.com'
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('createNewUser', function () {
|
|
|
|
describe('with callbacks', function () {
|
|
|
|
it('should take the opts and put them in the model', async function () {
|
2020-09-01 08:37:09 -04:00
|
|
|
const user = await this.UserCreator.promises.createNewUser({
|
2019-09-18 11:22:27 -04:00
|
|
|
email: this.email,
|
2021-04-27 03:52:58 -04:00
|
|
|
holdingAccount: true,
|
2019-09-18 11:22:27 -04:00
|
|
|
})
|
2020-09-01 08:37:09 -04:00
|
|
|
assert.equal(user.email, this.email)
|
|
|
|
assert.equal(user.holdingAccount, true)
|
|
|
|
assert.equal(user.first_name, 'bob.oswald')
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should use the start of the email if the first name is empty string', async function () {
|
2020-09-01 08:37:09 -04:00
|
|
|
const user = await this.UserCreator.promises.createNewUser({
|
2019-09-18 11:22:27 -04:00
|
|
|
email: this.email,
|
|
|
|
holdingAccount: true,
|
2021-04-27 03:52:58 -04:00
|
|
|
first_name: '',
|
2019-09-18 11:22:27 -04:00
|
|
|
})
|
2020-09-01 08:37:09 -04:00
|
|
|
assert.equal(user.email, this.email)
|
|
|
|
assert.equal(user.holdingAccount, true)
|
|
|
|
assert.equal(user.first_name, 'bob.oswald')
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should use the first name if passed', async function () {
|
2020-09-01 08:37:09 -04:00
|
|
|
const user = await this.UserCreator.promises.createNewUser({
|
2019-09-18 11:22:27 -04:00
|
|
|
email: this.email,
|
|
|
|
holdingAccount: true,
|
2021-04-27 03:52:58 -04:00
|
|
|
first_name: 'fiiirstname',
|
2019-09-18 11:22:27 -04:00
|
|
|
})
|
2020-09-01 08:37:09 -04:00
|
|
|
assert.equal(user.email, this.email)
|
|
|
|
assert.equal(user.holdingAccount, true)
|
|
|
|
assert.equal(user.first_name, 'fiiirstname')
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should use the last name if passed', async function () {
|
2020-09-01 08:37:09 -04:00
|
|
|
const user = await this.UserCreator.promises.createNewUser({
|
2019-09-18 11:22:27 -04:00
|
|
|
email: this.email,
|
|
|
|
holdingAccount: true,
|
2021-04-27 03:52:58 -04:00
|
|
|
last_name: 'lastNammmmeee',
|
2019-09-18 11:22:27 -04:00
|
|
|
})
|
2020-09-01 08:37:09 -04:00
|
|
|
assert.equal(user.email, this.email)
|
|
|
|
assert.equal(user.holdingAccount, true)
|
|
|
|
assert.equal(user.last_name, 'lastNammmmeee')
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should set emails attribute', async function () {
|
2020-09-01 08:37:09 -04:00
|
|
|
const user = await this.UserCreator.promises.createNewUser({
|
2021-04-27 03:52:58 -04:00
|
|
|
email: this.email,
|
2019-09-18 11:22:27 -04:00
|
|
|
})
|
2020-09-01 08:37:09 -04:00
|
|
|
user.email.should.equal(this.email)
|
|
|
|
user.emails.length.should.equal(1)
|
|
|
|
user.emails[0].email.should.equal(this.email)
|
|
|
|
user.emails[0].createdAt.should.be.a('date')
|
|
|
|
user.emails[0].reversedHostname.should.equal('moc.liamg')
|
2019-09-18 11:22:27 -04:00
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('with affiliations feature', function () {
|
2020-02-20 11:08:40 -05:00
|
|
|
let attributes, user
|
2021-04-14 09:17:21 -04:00
|
|
|
beforeEach(function () {
|
2020-02-20 11:08:40 -05:00
|
|
|
attributes = { email: this.email }
|
|
|
|
this.Features.hasFeature = sinon
|
|
|
|
.stub()
|
|
|
|
.withArgs('affiliations')
|
|
|
|
.returns(true)
|
|
|
|
})
|
2020-09-01 08:37:09 -04:00
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('when v1 affiliations API does not return an error', function () {
|
|
|
|
beforeEach(async function () {
|
2020-09-01 08:37:09 -04:00
|
|
|
user = await this.UserCreator.promises.createNewUser(attributes)
|
2020-02-20 11:08:40 -05:00
|
|
|
})
|
2020-09-01 08:37:09 -04:00
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should flag that affiliation is unchecked', function () {
|
2020-02-20 11:08:40 -05:00
|
|
|
user.emails[0].affiliationUnchecked.should.equal(true)
|
|
|
|
})
|
2020-09-01 08:37:09 -04:00
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should try to add affiliation to v1', function () {
|
2020-02-20 11:08:40 -05:00
|
|
|
sinon.assert.calledOnce(
|
|
|
|
this.UserUpdater.promises.addAffiliationForNewUser
|
|
|
|
)
|
|
|
|
sinon.assert.calledWithMatch(
|
|
|
|
this.UserUpdater.promises.addAffiliationForNewUser,
|
|
|
|
user._id,
|
|
|
|
this.email
|
|
|
|
)
|
|
|
|
})
|
2020-09-01 08:37:09 -04:00
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should query for updated user data', function () {
|
2020-02-20 11:08:40 -05:00
|
|
|
sinon.assert.calledOnce(this.UserGetter.promises.getUser)
|
|
|
|
})
|
|
|
|
})
|
2020-09-01 08:37:09 -04:00
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('when v1 affiliations API does return an error', function () {
|
|
|
|
beforeEach(async function () {
|
2020-02-20 11:08:40 -05:00
|
|
|
this.UserUpdater.promises.addAffiliationForNewUser.rejects()
|
2020-09-01 08:37:09 -04:00
|
|
|
user = await this.UserCreator.promises.createNewUser(attributes)
|
2020-02-20 11:08:40 -05:00
|
|
|
})
|
2020-09-01 08:37:09 -04:00
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should flag that affiliation is unchecked', function () {
|
2020-02-20 11:08:40 -05:00
|
|
|
user.emails[0].affiliationUnchecked.should.equal(true)
|
|
|
|
})
|
2020-09-01 08:37:09 -04:00
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should try to add affiliation to v1', function () {
|
2020-02-20 11:08:40 -05:00
|
|
|
sinon.assert.calledOnce(
|
|
|
|
this.UserUpdater.promises.addAffiliationForNewUser
|
|
|
|
)
|
|
|
|
sinon.assert.calledWithMatch(
|
|
|
|
this.UserUpdater.promises.addAffiliationForNewUser,
|
|
|
|
user._id,
|
|
|
|
this.email
|
|
|
|
)
|
|
|
|
})
|
2020-09-01 08:37:09 -04:00
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should not query for updated user data', function () {
|
2020-09-01 08:37:09 -04:00
|
|
|
sinon.assert.notCalled(this.UserGetter.promises.getUser)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should log error', function () {
|
2021-03-31 08:20:55 -04:00
|
|
|
sinon.assert.calledOnce(this.logger.error)
|
2020-09-01 08:37:09 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('when v1 affiliations API returns an error and requireAffiliation=true', function () {
|
|
|
|
beforeEach(async function () {
|
2020-09-01 08:37:09 -04:00
|
|
|
this.UserUpdater.promises.addAffiliationForNewUser.rejects()
|
|
|
|
user = await this.UserCreator.promises.createNewUser(attributes)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should flag that affiliation is unchecked', function () {
|
2020-09-01 08:37:09 -04:00
|
|
|
user.emails[0].affiliationUnchecked.should.equal(true)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should try to add affiliation to v1', function () {
|
2020-09-01 08:37:09 -04:00
|
|
|
sinon.assert.calledOnce(
|
|
|
|
this.UserUpdater.promises.addAffiliationForNewUser
|
|
|
|
)
|
|
|
|
sinon.assert.calledWithMatch(
|
|
|
|
this.UserUpdater.promises.addAffiliationForNewUser,
|
|
|
|
user._id,
|
|
|
|
this.email
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should not query for updated user data', function () {
|
2020-09-01 08:37:09 -04:00
|
|
|
sinon.assert.notCalled(this.UserGetter.promises.getUser)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should log error', function () {
|
2021-03-31 08:20:55 -04:00
|
|
|
sinon.assert.calledOnce(this.logger.error)
|
2020-02-20 11:08:40 -05:00
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should not add affiliation when without affiliation feature', async function () {
|
2019-09-18 11:22:27 -04:00
|
|
|
const attributes = { email: this.email }
|
2020-09-01 08:37:09 -04:00
|
|
|
await this.UserCreator.promises.createNewUser(attributes)
|
|
|
|
sinon.assert.notCalled(
|
|
|
|
this.UserUpdater.promises.addAffiliationForNewUser
|
|
|
|
)
|
2019-09-18 11:22:27 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('with promises', function () {
|
|
|
|
it('should take the opts and put them in the model', async function () {
|
2019-09-18 11:22:27 -04:00
|
|
|
const opts = {
|
|
|
|
email: this.email,
|
2021-04-27 03:52:58 -04:00
|
|
|
holdingAccount: true,
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
2019-09-18 11:22:27 -04:00
|
|
|
const user = await this.UserCreator.promises.createNewUser(opts)
|
|
|
|
assert.equal(user.email, this.email)
|
|
|
|
assert.equal(user.holdingAccount, true)
|
|
|
|
assert.equal(user.first_name, 'bob.oswald')
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should add affiliation when with affiliation feature', async function () {
|
2020-02-20 11:08:40 -05:00
|
|
|
this.Features.hasFeature = sinon
|
|
|
|
.stub()
|
|
|
|
.withArgs('affiliations')
|
|
|
|
.returns(true)
|
2019-09-18 11:22:27 -04:00
|
|
|
const attributes = { email: this.email }
|
|
|
|
const user = await this.UserCreator.promises.createNewUser(attributes)
|
2020-02-20 11:08:40 -05:00
|
|
|
sinon.assert.calledOnce(
|
|
|
|
this.UserUpdater.promises.addAffiliationForNewUser
|
|
|
|
)
|
|
|
|
sinon.assert.calledWithMatch(
|
|
|
|
this.UserUpdater.promises.addAffiliationForNewUser,
|
|
|
|
user._id,
|
|
|
|
this.email
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should not add affiliation when without affiliation feature', async function () {
|
2020-02-20 11:08:40 -05:00
|
|
|
this.Features.hasFeature = sinon.stub().returns(false)
|
|
|
|
const attributes = { email: this.email }
|
|
|
|
await this.UserCreator.promises.createNewUser(attributes)
|
|
|
|
sinon.assert.notCalled(
|
|
|
|
this.UserUpdater.promises.addAffiliationForNewUser
|
|
|
|
)
|
2019-09-18 11:22:27 -04:00
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should include SAML provider ID with email', async function () {
|
2019-10-07 11:23:45 -04:00
|
|
|
const attributes = {
|
|
|
|
email: this.email,
|
2021-04-27 03:52:58 -04:00
|
|
|
samlIdentifiers: [{ email: this.email, providerId: '1' }],
|
2019-10-07 11:23:45 -04:00
|
|
|
}
|
|
|
|
const user = await this.UserCreator.promises.createNewUser(attributes)
|
|
|
|
assert.equal(user.emails[0].samlProviderId, '1')
|
|
|
|
})
|
2021-03-10 04:20:55 -05:00
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should fire an analytics event on registration', async function () {
|
2021-03-10 04:20:55 -05:00
|
|
|
const user = await this.UserCreator.promises.createNewUser({
|
2021-04-27 03:52:58 -04:00
|
|
|
email: this.email,
|
2021-03-10 04:20:55 -05:00
|
|
|
})
|
|
|
|
assert.equal(user.email, this.email)
|
|
|
|
sinon.assert.calledWith(
|
|
|
|
this.Analytics.recordEvent,
|
|
|
|
user._id,
|
|
|
|
'user-registered'
|
|
|
|
)
|
|
|
|
})
|
2021-03-31 05:24:39 -04:00
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should schedule an onboarding email on registration', async function () {
|
2021-03-31 05:24:39 -04:00
|
|
|
const user = await this.UserCreator.promises.createNewUser({
|
2021-04-27 03:52:58 -04:00
|
|
|
email: this.email,
|
2021-03-31 05:24:39 -04:00
|
|
|
})
|
|
|
|
assert.equal(user.email, this.email)
|
|
|
|
sinon.assert.calledWith(
|
|
|
|
this.UserOnboardingEmailManager.scheduleOnboardingEmail,
|
|
|
|
user
|
|
|
|
)
|
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|