feat(SPA): users page and invite modal
This commit is contained in:
1 parent
acdef18b37
commit
6afffc1984
20 files changed
+1880
-55
No files matched your search
+112
-1
@@ -152,7 +152,7 @@ const sixArticlesFixture = [
|
||||
|
||||
const verifiedSession: ApiMock = {
|
||||
status: 200,
|
||||
body: { is_verified: true, username: 'marta' },
|
||||
body: { id: 1, is_verified: true, username: 'marta' },
|
||||
}
|
||||
|
||||
const editorNow = '2026-09-26T11:02:00Z'
|
||||
@@ -565,6 +565,75 @@ function resetConfirmWith(response: ApiMock): Omit<VisualState, 'steps'> {
|
||||
}
|
||||
}
|
||||
|
||||
const usersFixture = [
|
||||
{
|
||||
kind: 'invite',
|
||||
id: 2,
|
||||
email: 'sam.oliveira@renew.example',
|
||||
status: 'pending',
|
||||
created_at: '2026-09-27T09:00:00Z',
|
||||
},
|
||||
{
|
||||
kind: 'invite',
|
||||
id: 1,
|
||||
email: 'p.huber@gmail.com',
|
||||
status: 'expired',
|
||||
created_at: '2026-08-03T09:00:00Z',
|
||||
},
|
||||
{
|
||||
kind: 'user',
|
||||
id: 3,
|
||||
username: 'ines',
|
||||
display_name: 'Inès Duarte',
|
||||
status: 'accepted',
|
||||
created_at: '2026-06-18T09:00:00Z',
|
||||
},
|
||||
{
|
||||
kind: 'user',
|
||||
id: 2,
|
||||
username: 'jonas',
|
||||
display_name: '',
|
||||
status: 'accepted',
|
||||
created_at: '2026-04-02T09:00:00Z',
|
||||
},
|
||||
{
|
||||
kind: 'user',
|
||||
id: 1,
|
||||
username: 'marta',
|
||||
display_name: '',
|
||||
status: 'accepted',
|
||||
created_at: '2026-03-12T09:00:00Z',
|
||||
},
|
||||
]
|
||||
|
||||
function usersApi(overrides: Record<string, ApiMock> = {}): Record<string, ApiMock> {
|
||||
return {
|
||||
'GET /v1/auth/me': verifiedSession,
|
||||
'GET /v1/user/': { status: 200, body: usersFixture },
|
||||
...overrides,
|
||||
}
|
||||
}
|
||||
|
||||
async function openInviteModal(page: Page) {
|
||||
await page.getByRole('button', { name: 'Invite user' }).click()
|
||||
await page.getByRole('dialog').waitFor()
|
||||
await page.mouse.move(0, 0)
|
||||
}
|
||||
|
||||
function inviteWith(email: string, response?: ApiMock) {
|
||||
return async (page: Page) => {
|
||||
await openInviteModal(page)
|
||||
await page.getByPlaceholder('name@example.com').fill(email)
|
||||
if (response) {
|
||||
await page.getByRole('button', { name: 'Send invite', exact: true }).click()
|
||||
await page.mouse.move(0, 0)
|
||||
} else {
|
||||
await page.getByPlaceholder('name@example.com').blur()
|
||||
await page.mouse.move(0, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const integrationOrigin = 'https://cms.renew.example'
|
||||
|
||||
async function clickBaseUrlCopy(page: Page) {
|
||||
@@ -572,6 +641,48 @@ async function clickBaseUrlCopy(page: Page) {
|
||||
}
|
||||
|
||||
export const visualStates: Record<string, Record<string, VisualState>> = {
|
||||
users: {
|
||||
Default: { path: '/users', api: usersApi() },
|
||||
Loading: {
|
||||
path: '/users',
|
||||
api: usersApi({ 'GET /v1/user/': { status: 200, body: usersFixture, hang: true } }),
|
||||
steps: async (page) => {
|
||||
await page.waitForTimeout(400)
|
||||
},
|
||||
},
|
||||
'Only you': {
|
||||
path: '/users',
|
||||
api: usersApi({ 'GET /v1/user/': { status: 200, body: usersFixture.slice(4) } }),
|
||||
},
|
||||
Error: { path: '/users', api: usersApi({ 'GET /v1/user/': { status: 500 } }) },
|
||||
'Invite: default': { path: '/users', api: usersApi(), steps: openInviteModal },
|
||||
'Invite: validation': {
|
||||
path: '/users',
|
||||
api: usersApi(),
|
||||
steps: inviteWith('sam.oliveira@renew'),
|
||||
},
|
||||
'Invite: sending': {
|
||||
path: '/users',
|
||||
api: usersApi({ 'POST /v1/user/invite': { status: 201, hang: true } }),
|
||||
steps: inviteWith('lea.martin@renew.example', { status: 201, hang: true }),
|
||||
},
|
||||
'Invite: already a user (409)': {
|
||||
path: '/users',
|
||||
api: usersApi({
|
||||
'POST /v1/user/invite': {
|
||||
status: 409,
|
||||
body: 'This address already has an account.',
|
||||
},
|
||||
}),
|
||||
steps: inviteWith('jonas@renew.example', { status: 409 }),
|
||||
},
|
||||
'Invite: failed': {
|
||||
path: '/users',
|
||||
api: usersApi({ 'POST /v1/user/invite': { status: 500 } }),
|
||||
steps: inviteWith('lea.martin@renew.example', { status: 500 }),
|
||||
},
|
||||
'Invite sent': { path: '/users', skip: 'clock-sensitive' },
|
||||
},
|
||||
integration: {
|
||||
Default: {
|
||||
path: '/integration',
|
||||
|
||||
Reference in new issue
Block a user