feat: invitation accept screen and api

This commit is contained in:
fsylvain committed 2026-09-29 09:21:53 +02:00
1 parent 310cfd528e
commit 55525c06d6
23 files changed
+2043 -11

No files matched your search

+78
View File
@@ -640,6 +640,33 @@ async function clickBaseUrlCopy(page: Page) {
await page.getByRole('button', { name: 'Copy', exact: true }).first().click()
}
const acceptInvitePath = '/invite/accept?c=abc123'
const acceptInviteEmail = 'lea.martin@renew.example'
function acceptInviteWith(response: ApiMock): Omit<VisualState, 'steps'> {
return {
path: acceptInvitePath,
api: {
'GET /v1/auth/invite': { status: 200, body: { email: acceptInviteEmail } },
'POST /v1/auth/invite/accept': response,
},
}
}
async function fillAcceptInvite(page: Page, username: string, password: string) {
await page.getByPlaceholder('e.g. lea').fill(username)
await page.getByPlaceholder('e.g. lea').blur()
await page.locator('input[autocomplete="new-password"]').fill(password)
await page.locator('input[autocomplete="new-password"]').blur()
}
function submitAcceptInvite(username: string, password: string) {
return async (page: Page) => {
await fillAcceptInvite(page, username, password)
await page.locator('input[autocomplete="new-password"]').press('Enter')
}
}
export const visualStates: Record<string, Record<string, VisualState>> = {
users: {
Default: { path: '/users', api: usersApi() },
@@ -1401,4 +1428,55 @@ export const visualStates: Record<string, Record<string, VisualState>> = {
steps: submitResetConfirm('limewash2026', 'limewash2026'),
},
},
'accept-invite': {
'Checking the link': {
path: acceptInvitePath,
api: { 'GET /v1/auth/invite': { status: 200, hang: true } },
},
Default: acceptInviteWith({ status: 200 }),
'Validation errors': {
...acceptInviteWith({ status: 200 }),
steps: async (page) => {
await fillAcceptInvite(page, 'ma', 'lime')
await page.locator('input[autocomplete="new-password"]').press('Enter')
},
},
'Filled, valid': {
...acceptInviteWith({ status: 200 }),
steps: async (page) => {
await fillAcceptInvite(page, 'lea', 'limewash2026')
await page.getByRole('button', { name: 'Show password' }).click()
},
},
Submitting: {
...acceptInviteWith({ status: 200, hang: true }),
steps: submitAcceptInvite('lea', 'limewash2026'),
},
'Username taken (409)': {
...acceptInviteWith({ status: 409, body: 'That username is taken. Try another.' }),
steps: submitAcceptInvite('marta', 'limewash2026'),
},
'Invalid or used link (404)': {
path: acceptInvitePath,
api: { 'GET /v1/auth/invite': { status: 404 } },
},
'Expired link (410)': {
path: acceptInvitePath,
api: { 'GET /v1/auth/invite': { status: 410 } },
},
'Server error': {
...acceptInviteWith({ status: 500 }),
steps: submitAcceptInvite('lea', 'limewash2026'),
},
Success: {
...acceptInviteWith({ status: 200, body: { message: 'ok' } }),
paused: true,
api: {
'GET /v1/auth/invite': { status: 200, body: { email: acceptInviteEmail } },
'POST /v1/auth/invite/accept': { status: 200, body: { message: 'ok' } },
'GET /v1/auth/me': { status: 200, body: { is_verified: true } },
},
steps: submitAcceptInvite('lea', 'limewash2026'),
},
},
}