Merge pull request #17530 from overleaf/dp-teardown-onboarding-flow-split-test

Teardown onboarding flow split test

GitOrigin-RevId: 48e95e4e736772074cb68d195fc950a9da3aebcf
This commit is contained in:
David
2024-04-08 08:04:04 +00:00
committed by Copybot
parent 2f74b79d3a
commit b1928cecef
12 changed files with 168 additions and 26 deletions
@@ -8,6 +8,50 @@ const MockReCAPTCHAApi = require('../mocks/MockReCaptchaApi')
const {
gracefulShutdown,
} = require('../../../../app/src/infrastructure/GracefulShutdown')
const { app } = require('../../../../app/src/infrastructure/Server')
/**
* Inject an endpoint to get the current users session into our app. This
* endpoint should only be available when running in the test environment.
* It is used to retrieve an email confirmation code when registering a
* new user account in acceptance tests.
*/
const addSessionEndpoint = app => {
const stack = app._router.stack
stack.forEach(layer => {
if (layer.name !== 'router' || !layer.handle || !layer.handle.stack) {
return
}
// We want to position our /dev/session endpoint next to the /dev/csrf
// endpoint so we check each router for the presence of this path.
const newRouteIndex = layer.handle.stack.findIndex(
route =>
route &&
route.route &&
route.route.path &&
route.route.path === '/dev/csrf'
)
if (newRouteIndex !== -1) {
// We add our new endpoint to the end of the router stack.
layer.handle.get('/dev/session', (req, res) => {
return res.json(req.session)
})
const routeStack = layer.handle.stack
const sessionRoute = routeStack[routeStack.length - 1]
// Then we reposition it next to the /dev/csrf endpoint.
layer.handle.stack = [
...routeStack.slice(0, newRouteIndex),
sessionRoute,
...routeStack.slice(newRouteIndex, routeStack.length - 1),
]
}
})
}
logger.logger.level('error')
@@ -18,6 +62,7 @@ MockReCAPTCHAApi.initialize(2222)
let server
before('start main app', function (done) {
addSessionEndpoint(app)
server = App.listen(23000, 'localhost', done)
})
@@ -32,6 +32,46 @@ class User {
})
}
getSession(callback) {
this.request.get(
{
url: '/dev/session',
},
(err, response, body) => {
if (err != null) {
return callback(err)
}
if (response.statusCode !== 200) {
return callback(
new Error(
`get session failed: status=${
response.statusCode
} body=${JSON.stringify(body)}`
)
)
}
const session = JSON.parse(response.body)
callback(null, session)
}
)
}
getEmailConfirmationCode(callback) {
this.getSession((err, session) => {
if (err != null) {
return callback(err)
}
const code = session.pendingUserRegistration?.confirmCode
if (!code) {
return callback(new Error('No confirmation code found in session'))
}
callback(null, code)
})
}
resetCookies() {
this.jar = request.jar()
this.request = request.defaults({
@@ -114,12 +154,40 @@ class User {
)
)
}
db.users.findOne({ email: this.email }, (error, user) => {
this.getEmailConfirmationCode((error, code) => {
if (error != null) {
return callback(error)
}
this.setExtraAttributes(user)
callback(null, user)
this.request.post(
{
url: '/registration/confirm-email',
json: { code },
},
(error, response, body) => {
if (error != null) {
return callback(error)
}
if (response.statusCode !== 200) {
return callback(
new Error(
`email confirmation failed: status=${
response.statusCode
} body=${JSON.stringify(body)}`
)
)
}
db.users.findOne({ email: this.email }, (error, user) => {
if (error != null) {
return callback(error)
}
this.setExtraAttributes(user)
callback(null, user)
})
}
)
})
}
)
@@ -140,6 +140,33 @@ class UserHelper {
this._csrfToken = body
}
/**
* Requests user session
*/
async getSession() {
const response = await this.fetch('/dev/session')
const body = await response.text()
if (response.status !== 200) {
throw new Error(
`get session failed: status=${response.status} body=${JSON.stringify(
body
)}`
)
}
return JSON.parse(body)
}
async getEmailConfirmationCode() {
const session = await this.getSession()
const code = session.pendingUserRegistration?.confirmCode
if (!code) {
throw new Error('No confirmation code found in session')
}
return code
}
/**
* Make request to POST /logout
* @param {object} [options] options to pass to request
@@ -353,6 +380,30 @@ class UserHelper {
`cannot register intitutional email: ${options.json.email}`
)
}
const code = await userHelper.getEmailConfirmationCode()
const confirmationResponse = await userHelper.fetch(
'/registration/confirm-email',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
body: JSON.stringify({ code }),
...options,
}
)
if (confirmationResponse.status !== 200) {
throw new Error(
`email confirmation failed: status=${
response.status
} body=${JSON.stringify(body)}`
)
}
userHelper.user = await UserGetter.promises.getUser({
email: userData.email,
})