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

134 lines
3.7 KiB
JavaScript
Raw Normal View History

const SandboxedModule = require('sandboxed-module')
const path = require('path')
const sinon = require('sinon')
const { expect } = require('chai')
const MODULE_PATH = path.join(
__dirname,
'../../../../app/src/Features/User/UserOnboardingEmailManager'
)
describe('UserOnboardingEmailManager', function () {
beforeEach(function () {
this.fakeUserId = '123abc'
this.fakeUserEmail = 'frog@overleaf.com'
this.onboardingEmailsQueue = {
add: sinon.stub().resolves(),
process: callback => {
this.queueProcessFunction = callback
},
}
this.Queues = {
getOnboardingEmailsQueue: sinon
.stub()
.returns(this.onboardingEmailsQueue),
}
this.UserGetter = {
promises: {
getUser: sinon.stub().resolves({
_id: this.fakeUserId,
email: this.fakeUserEmail,
}),
},
}
this.EmailHandler = {
promises: {
sendEmail: sinon.stub().resolves(),
},
}
this.UserUpdater = {
promises: {
updateUser: sinon.stub().resolves(),
},
}
this.Features = {
hasFeature: sinon.stub(),
}
this.request = sinon.stub().yields()
this.init = isSAAS => {
this.Features.hasFeature.withArgs('saas').returns(isSAAS)
this.UserOnboardingEmailManager = SandboxedModule.require(MODULE_PATH, {
globals: {
console: console,
},
requires: {
'../../infrastructure/Features': this.Features,
'../../infrastructure/Queues': this.Queues,
'../Email/EmailHandler': this.EmailHandler,
'./UserGetter': this.UserGetter,
'./UserUpdater': this.UserUpdater,
},
})
}
})
describe('in Server CE/Pro', function () {
beforeEach(function () {
this.init(false)
})
it('should not create any queue', function () {
expect(this.Queues.getOnboardingEmailsQueue).to.not.have.been.called
})
it('should not schedule any email', function () {
this.UserOnboardingEmailManager.scheduleOnboardingEmail({
_id: this.fakeUserId,
})
expect(this.onboardingEmailsQueue.add).to.not.have.been.called
})
})
describe('schedule email in SAAS', function () {
beforeEach(function () {
this.init(true)
})
it('should schedule delayed job on queue', function () {
this.UserOnboardingEmailManager.scheduleOnboardingEmail({
_id: this.fakeUserId,
})
sinon.assert.calledWith(
this.onboardingEmailsQueue.add,
{ userId: this.fakeUserId },
{ delay: 24 * 60 * 60 * 1000 }
)
})
it('queue process callback should send onboarding email and update user', async function () {
await this.queueProcessFunction({ data: { userId: this.fakeUserId } })
sinon.assert.calledWith(
this.UserGetter.promises.getUser,
{ _id: this.fakeUserId },
{ email: 1 }
)
sinon.assert.calledWith(
this.EmailHandler.promises.sendEmail,
'userOnboardingEmail',
{
to: this.fakeUserEmail,
}
)
sinon.assert.calledWith(
this.UserUpdater.promises.updateUser,
this.fakeUserId,
{
$set: { onboardingEmailSentAt: sinon.match.date },
}
)
})
it('queue process callback should stop if user is not found', async function () {
this.UserGetter.promises.getUser = sinon.stub().resolves()
await this.queueProcessFunction({ data: { userId: 'deleted-user' } })
sinon.assert.calledWith(
this.UserGetter.promises.getUser,
{ _id: 'deleted-user' },
{ email: 1 }
)
sinon.assert.notCalled(this.EmailHandler.promises.sendEmail)
sinon.assert.notCalled(this.UserUpdater.promises.updateUser)
})
})
})