From bfa4d5ba8567f1f612ad07282497ae17e2d3b59f Mon Sep 17 00:00:00 2001 From: Niek Otten Date: Thu, 16 Jul 2026 14:28:19 +0200 Subject: [PATCH] test(self-service): the submit confirmation offers to withdraw, keyed by the reference (refs #12) Co-Authored-By: Claude Opus 4.8 (1M context) --- .../registration/registration-page.spec.ts | 44 ++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/apps/self-service/src/app/registration/registration-page.spec.ts b/apps/self-service/src/app/registration/registration-page.spec.ts index 284f7da..1119762 100644 --- a/apps/self-service/src/app/registration/registration-page.spec.ts +++ b/apps/self-service/src/app/registration/registration-page.spec.ts @@ -17,12 +17,22 @@ class FakeAuth extends AuthService { } } -function providers(post = vi.fn().mockReturnValue(of({ registrationId: 'reg-9', status: 'Ingediend' }))) { +function providers( + post = vi.fn().mockReturnValue(of({ registrationId: 'reg-9', status: 'Ingediend' })), + withdraw = vi.fn().mockReturnValue(of(undefined)), +) { return { post, + withdraw, providers: [ { provide: AuthService, useClass: FakeAuth }, - { provide: BffApiV1Service, useValue: { postSelfServiceRegistrations: post } }, + { + provide: BffApiV1Service, + useValue: { + postSelfServiceRegistrations: post, + postSelfServiceRegistrationsIdWithdraw: withdraw, + }, + }, ], }; } @@ -56,6 +66,36 @@ describe('RegistrationPage', () => { expect(screen.getByRole('button', { name: /indienen/i })).toBeTruthy(); }); + it('offers to withdraw after submitting, and withdrawing confirms', async () => { + const { withdraw, providers: p } = providers(); + await render(RegistrationPage, { providers: p }); + + fireEvent.click(screen.getByRole('button', { name: /indienen/i })); + await screen.findByText(/ontvangen/i); + + fireEvent.click(await screen.findByRole('button', { name: /trek aanvraag in/i })); + + // The withdrawal is keyed by the reference the submit returned, and the page confirms it. + expect(withdraw).toHaveBeenCalledWith('reg-9'); + expect(await screen.findByText(/ingetrokken/i)).toBeTruthy(); + }); + + it('surfaces a withdraw failure and keeps the action available', async () => { + const { providers: p } = providers( + vi.fn().mockReturnValue(of({ registrationId: 'reg-9', status: 'Ingediend' })), + vi.fn().mockReturnValue(throwError(() => new Error('withdraw rejected'))), + ); + await render(RegistrationPage, { providers: p }); + + fireEvent.click(screen.getByRole('button', { name: /indienen/i })); + await screen.findByText(/ontvangen/i); + fireEvent.click(await screen.findByRole('button', { name: /trek aanvraag in/i })); + + expect(await screen.findByRole('alert')).toBeTruthy(); + expect(screen.queryByText(/is ingetrokken/i)).toBeNull(); + expect(screen.getByRole('button', { name: /trek aanvraag in/i })).toBeTruthy(); + }); + it('has no WCAG 2.1 AA violations on the submit page', async () => { // The portal is Dutch; the real index.html sets lang. Set it here so the document-level // html-has-lang rule reflects the app, not the bare jsdom document.