refac: hardening pass with multiple overhauls

This commit is contained in:
fsylvain committed 2026-09-29 10:55:23 +02:00
1 parent b0f7b7892b
commit da36c78bc0
28 files changed
+1375 -39

No files matched your search

@@ -368,3 +368,95 @@ describe('Success', () => {
await vi.waitFor(() => expect(router.currentRoute.value.path).toBe('/home'))
})
})
describe('Failed lookup', () => {
const lookupKey = 'GET /v1/auth/invite?c=abc123'
const alertTitle = "Couldn't check your invite"
const alertText = 'Something went wrong on the server. Try again in a moment.'
function tryAgainButton(wrapper: Wrapper) {
return wrapper.findAll('button').find((button) => button.text() === 'Try again')
}
function expectFailedLookup(wrapper: Wrapper) {
expect(wrapper.text()).toContain(alertTitle)
expect(wrapper.text()).toContain(alertText)
expect(tryAgainButton(wrapper)).toBeTruthy()
expect(wrapper.text()).not.toContain('Checking your invite…')
expect(wrapper.find('form').exists()).toBe(false)
expect(emailInput(wrapper).exists()).toBe(false)
expect(wrapper.text()).not.toContain("This invite link doesn't work")
}
it.each([
{ name: 'answers 500', handler: () => mockResponse(500) },
{ name: 'answers 502', handler: () => mockResponse(502) },
{
name: 'fails with a network error',
handler: () => Promise.reject(new TypeError('Failed to fetch')),
},
])('shows the alert and a Try again button when the lookup $name', async ({ handler }) => {
const { wrapper } = await mountAccept('/invite/accept?c=abc123', { [lookupKey]: handler })
expectFailedLookup(wrapper)
expect(wrapper.find('[role="alert"]').exists()).toBe(true)
})
it('looks the invite up again when Try again is activated', async () => {
let calls = 0
const { wrapper, fetchMock } = await mountAccept('/invite/accept?c=abc123', {
[lookupKey]: () => {
calls += 1
return calls === 1
? mockResponse(500)
: new Promise<Response>((resolve) =>
setTimeout(
() =>
resolve(
mockResponse(200, { email: 'lea.martin@renew.example' }),
),
0,
),
)
},
})
await tryAgainButton(wrapper)!.trigger('click')
expect(wrapper.text()).toContain('Checking your invite…')
expect(wrapper.text()).not.toContain(alertTitle)
expect(fetchMock).toHaveBeenCalledTimes(2)
await new Promise((resolve) => setTimeout(resolve, 5))
await flushPromises()
expect((emailInput(wrapper).element as HTMLInputElement).value).toBe(
'lea.martin@renew.example',
)
expect(wrapper.find('h1').text()).toBe('Accept your invite')
})
it('shows the alert again with an enabled button when the lookup fails again', async () => {
const { wrapper, fetchMock } = await mountAccept('/invite/accept?c=abc123', {
[lookupKey]: () => mockResponse(500),
})
await tryAgainButton(wrapper)!.trigger('click')
await flushPromises()
expect(fetchMock).toHaveBeenCalledTimes(2)
expectFailedLookup(wrapper)
expect(tryAgainButton(wrapper)!.attributes('disabled')).toBeUndefined()
})
it.each([
{ status: 404, text: "This invite link doesn't work" },
{ status: 410, text: 'This invite has expired' },
])('keeps the design state when the lookup answers $status', async ({ status, text }) => {
const { wrapper } = await mountAccept('/invite/accept?c=abc123', {
[lookupKey]: () => mockResponse(status),
})
expect(wrapper.text()).toContain(text)
expect(wrapper.text()).not.toContain(alertTitle)
expect(tryAgainButton(wrapper)).toBeUndefined()
})
})