Merge pull request #3409 from overleaf/jel-inst-leavers-db

Add reconfirmedAt to UserSchema

GitOrigin-RevId: 543b57236bbf964c72c6587362a6b6d6b7b7caa6
This commit is contained in:
Jessica Lawshe
2020-12-01 03:04:39 +00:00
committed by Copybot
parent 76cbf9949f
commit 8b4659e700
4 changed files with 155 additions and 62 deletions
@@ -6,6 +6,34 @@ const { db, ObjectId } = require('../../../app/src/infrastructure/mongodb')
const MockV1Api = require('./helpers/MockV1Api')
const expectErrorResponse = require('./helpers/expectErrorResponse')
async function confirmEmail(userHelper, email) {
let response
// UserHelper.createUser does not create a confirmation token
response = await userHelper.request.post({
form: {
email
},
simple: false,
uri: '/user/emails/resend_confirmation'
})
expect(response.statusCode).to.equal(200)
const tokenData = await db.tokens
.find({
use: 'email_confirmation',
'data.user_id': userHelper.user._id.toString(),
usedAt: { $exists: false }
})
.next()
response = await userHelper.request.post({
form: {
token: tokenData.token
},
simple: false,
uri: '/user/emails/confirm'
})
expect(response.statusCode).to.equal(200)
}
describe('UserEmails', function() {
beforeEach(function(done) {
this.timeout(20000)
@@ -41,7 +69,9 @@ describe('UserEmails', function() {
expect(error).to.not.exist
expect(response.statusCode).to.equal(200)
expect(body[0].confirmedAt).to.not.exist
expect(body[0].reconfirmedAt).to.not.exist
expect(body[1].confirmedAt).to.not.exist
expect(body[1].reconfirmedAt).to.not.exist
cb()
}
)
@@ -88,7 +118,10 @@ describe('UserEmails', function() {
expect(error).to.not.exist
expect(response.statusCode).to.equal(200)
expect(body[0].confirmedAt).to.not.exist
expect(body[0].reconfirmedAt).to.not.exist
expect(body[1].confirmedAt).to.exist
expect(body[1].reconfirmedAt).to.exist
expect(body[1].reconfirmedAt).to.deep.equal(body[1].confirmedAt)
cb()
}
)
@@ -239,6 +272,37 @@ describe('UserEmails', function() {
})
})
describe('reconfirm an email', function() {
let email, userHelper, confirmedAtDate
beforeEach(async function() {
userHelper = new UserHelper()
email = userHelper.getDefaultEmail()
userHelper = await UserHelper.createUser({ email })
userHelper = await UserHelper.loginUser({
email,
password: userHelper.getDefaultPassword()
})
// original confirmation
await confirmEmail(userHelper, email)
const user = (await UserHelper.getUser({ email })).user
confirmedAtDate = user.emails[0].confirmedAt
expect(user.emails[0].confirmedAt).to.exist
expect(user.emails[0].reconfirmedAt).to.exist
})
it('should set reconfirmedAt and not reset confirmedAt', async function() {
await confirmEmail(userHelper, email)
const user = (await UserHelper.getUser({ email })).user
expect(user.emails[0].confirmedAt).to.exist
expect(user.emails[0].reconfirmedAt).to.exist
expect(user.emails[0].confirmedAt).to.deep.equal(confirmedAtDate)
expect(user.emails[0].reconfirmedAt).to.not.deep.equal(
user.emails[0].confirmedAt
)
expect(user.emails[0].reconfirmedAt > user.emails[0].confirmedAt).to.be
.true
})
})
describe('with an expired token', function() {
it('should not confirm the email', function(done) {
let token = null
@@ -72,9 +72,12 @@ describe('UserUpdater', function() {
'../../infrastructure/Features': (this.Features = {
hasFeature: sinon.stub().returns(false)
}),
'../Subscription/FeaturesUpdater': {
refreshFeatures: this.refreshFeatures
},
'../Subscription/FeaturesUpdater': (this.FeaturesUpdater = {
refreshFeatures: this.refreshFeatures,
promises: {
refreshFeatures: sinon.stub().resolves()
}
}),
'settings-sharelatex': (this.settings = {}),
request: (this.request = {}),
'../Newsletter/NewsletterManager': this.NewsletterManager,
@@ -87,10 +90,16 @@ describe('UserUpdater', function() {
}
})
this.stubbedUserEmail = 'hello@world.com'
this.stubbedUser = {
_id: '3131231',
name: 'bob',
email: 'hello@world.com'
email: this.stubbedUserEmail,
emails: [
{
email: this.stubbedUserEmail
}
]
}
this.newEmail = 'bob@bob.com'
this.callback = sinon.stub()
@@ -708,19 +717,28 @@ describe('UserUpdater', function() {
describe('confirmEmail', function() {
beforeEach(function() {
this.UserUpdater.updateUser = sinon.stub().callsArgWith(2, null, { n: 1 })
this.UserUpdater.promises.updateUser = sinon.stub().resolves({ n: 1 })
this.UserGetter.promises.getUser.resolves(this.stubbedUser)
})
it('should update the email record', function(done) {
this.UserUpdater.confirmEmail(
this.stubbedUser._id,
this.newEmail,
this.stubbedUserEmail,
err => {
should.not.exist(err)
this.UserUpdater.updateUser
this.UserUpdater.promises.updateUser
.calledWith(
{ _id: this.stubbedUser._id, 'emails.email': this.newEmail },
{ $set: { 'emails.$.confirmedAt': new Date() } }
{
_id: this.stubbedUser._id,
'emails.email': this.stubbedUserEmail
},
{
$set: {
'emails.$.confirmedAt': new Date(),
'emails.$.reconfirmedAt': new Date()
}
}
)
.should.equal(true)
done()
@@ -734,9 +752,11 @@ describe('UserUpdater', function() {
this.newEmail,
err => {
should.not.exist(err)
this.addAffiliation.calledOnce.should.equal(true)
this.InstitutionsAPI.promises.addAffiliation.calledOnce.should.equal(
true
)
sinon.assert.calledWith(
this.addAffiliation,
this.InstitutionsAPI.promises.addAffiliation,
this.stubbedUser._id,
this.newEmail,
{ confirmedAt: new Date() }
@@ -747,9 +767,9 @@ describe('UserUpdater', function() {
})
it('handle error', function(done) {
this.UserUpdater.updateUser = sinon
this.UserUpdater.promises.updateUser = sinon
.stub()
.callsArgWith(2, new Error('nope'))
.throws(new Error('nope'))
this.UserUpdater.confirmEmail(
this.stubbedUser._id,
@@ -762,7 +782,7 @@ describe('UserUpdater', function() {
})
it('handle missed update', function(done) {
this.UserUpdater.updateUser = sinon.stub().callsArgWith(2, null, { n: 0 })
this.UserUpdater.promises.updateUser = sinon.stub().resolves({ n: 0 })
this.UserUpdater.confirmEmail(
this.stubbedUser._id,
@@ -782,13 +802,13 @@ describe('UserUpdater', function() {
})
it('handle affiliation error', function(done) {
this.addAffiliation.callsArgWith(3, new Error('nope'))
this.InstitutionsAPI.promises.addAffiliation.throws(Error('nope'))
this.UserUpdater.confirmEmail(
this.stubbedUser._id,
this.newEmail,
err => {
should.exist(err)
this.UserUpdater.updateUser.called.should.equal(false)
this.UserUpdater.promises.updateUser.called.should.equal(false)
done()
}
)
@@ -800,7 +820,10 @@ describe('UserUpdater', function() {
this.newEmail,
err => {
should.not.exist(err)
sinon.assert.calledWith(this.refreshFeatures, this.stubbedUser._id)
sinon.assert.calledWith(
this.FeaturesUpdater.promises.refreshFeatures,
this.stubbedUser._id
)
done()
}
)