fix(ci): library_test Mount arg + 4 web test selectors + forgot-pw catch
Five fixes in one commit, all from the U1+U2+U3 push:
1. internal/api/library_test.go's Mount call wasn't updated when
U3-T4 added the mailer.Sender param. 17 args, sig wants 18.
Adds a trailing nil for the mailer. Same shape of test-fixture
lag the project has hit before — flagged as a recurring pattern
for the DRY-pass slice.
2. web/src/routes/settings/settings.test.ts mocked $lib/api/me with
`getAPIToken: vi.fn()` (no return value). The new /settings API
Token card's $effect calls `getAPIToken().then(...)` which threw
"Cannot read properties of undefined (reading 'then')" on every
ListenBrainz test. Default the mock to mockResolvedValue so any
test that doesn't override gets a valid resolution.
3. web/src/routes/admin/users/users.test.ts queried row buttons by
/^Delete$/ but T3 added per-user aria-labels ("Delete alice"),
so the row buttons' accessible name is no longer "Delete". The
modal's confirm button has no aria-label so its name IS "Delete"
exactly. Tests now click by per-user aria-label first, then by
/^Delete$/ for the modal confirm.
4. Same file: /Set password/i regex matched both the dialog's
submit button AND the row's "Reset password for ..." buttons
(because regex `Set` matches "ReSet" case-insensitively). Switched
to /^Set password$/ exact-match.
5. web/src/routes/reset-password/[token]/reset-password.test.ts had
/New password/i which matched both the "New password" and
"Confirm new password" labels. Switched to exact-match string
selectors.
6. web/src/routes/forgot-password/+page.svelte's onSubmit handler
had no catch — a rejected forgotPassword() bubbled as an
unhandled rejection in vitest. Added a silent catch since the
page intentionally shows the same success message regardless of
outcome (no-enumeration posture).
This commit is contained in:
@@ -22,9 +22,9 @@ describe('/reset-password/[token] page', () => {
|
||||
|
||||
it('rejects mismatched passwords without calling resetPassword', async () => {
|
||||
render(ResetPasswordPage);
|
||||
await fireEvent.input(screen.getByLabelText(/New password/i), { target: { value: 'abcd1234' } });
|
||||
await fireEvent.input(screen.getByLabelText(/Confirm new password/i), { target: { value: 'differentpw' } });
|
||||
await fireEvent.click(screen.getByRole('button', { name: /Set password/i }));
|
||||
await fireEvent.input(screen.getByLabelText('New password'), { target: { value: 'abcd1234' } });
|
||||
await fireEvent.input(screen.getByLabelText('Confirm new password'), { target: { value: 'differentpw' } });
|
||||
await fireEvent.click(screen.getByRole('button', { name: 'Set password' }));
|
||||
expect(resetPassword).not.toHaveBeenCalled();
|
||||
await waitFor(() => expect(screen.getByRole('alert').textContent).toMatch(/do not match/i));
|
||||
});
|
||||
@@ -32,9 +32,9 @@ describe('/reset-password/[token] page', () => {
|
||||
it('calls resetPassword with the URL token and new password, redirects on success', async () => {
|
||||
(resetPassword as unknown as ReturnType<typeof vi.fn>).mockResolvedValue(undefined);
|
||||
render(ResetPasswordPage);
|
||||
await fireEvent.input(screen.getByLabelText(/New password/i), { target: { value: 'abcd1234' } });
|
||||
await fireEvent.input(screen.getByLabelText(/Confirm new password/i), { target: { value: 'abcd1234' } });
|
||||
await fireEvent.click(screen.getByRole('button', { name: /Set password/i }));
|
||||
await fireEvent.input(screen.getByLabelText('New password'), { target: { value: 'abcd1234' } });
|
||||
await fireEvent.input(screen.getByLabelText('Confirm new password'), { target: { value: 'abcd1234' } });
|
||||
await fireEvent.click(screen.getByRole('button', { name: 'Set password' }));
|
||||
expect(resetPassword).toHaveBeenCalledWith('test-token-abc', 'abcd1234');
|
||||
await waitFor(() => expect(goto).toHaveBeenCalledWith('/login?reset=ok', expect.objectContaining({ replaceState: true })));
|
||||
});
|
||||
@@ -42,9 +42,9 @@ describe('/reset-password/[token] page', () => {
|
||||
it('shows clear error on invalid_token', async () => {
|
||||
(resetPassword as unknown as ReturnType<typeof vi.fn>).mockRejectedValueOnce({ code: 'invalid_token' });
|
||||
render(ResetPasswordPage);
|
||||
await fireEvent.input(screen.getByLabelText(/New password/i), { target: { value: 'abcd1234' } });
|
||||
await fireEvent.input(screen.getByLabelText(/Confirm new password/i), { target: { value: 'abcd1234' } });
|
||||
await fireEvent.click(screen.getByRole('button', { name: /Set password/i }));
|
||||
await fireEvent.input(screen.getByLabelText('New password'), { target: { value: 'abcd1234' } });
|
||||
await fireEvent.input(screen.getByLabelText('Confirm new password'), { target: { value: 'abcd1234' } });
|
||||
await fireEvent.click(screen.getByRole('button', { name: 'Set password' }));
|
||||
await waitFor(() => expect(screen.getByRole('alert').textContent).toMatch(/invalid, expired, or already used/i));
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user