refactor(persons): replace inline delete modal with ConfirmService in NameHistoryEditCard
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
import { describe, it, expect, vi, afterEach } from 'vitest';
|
||||
import { cleanup, render } from 'vitest-browser-svelte';
|
||||
import { page } from 'vitest/browser';
|
||||
import NameHistoryEditCard from './NameHistoryEditCard.svelte';
|
||||
import { createConfirmService, CONFIRM_KEY } from '$lib/services/confirm.svelte.js';
|
||||
|
||||
vi.mock('$app/forms', () => ({ enhance: () => () => {} }));
|
||||
|
||||
afterEach(cleanup);
|
||||
|
||||
const aliases = [
|
||||
{ id: 'a1', lastName: 'Müller', firstName: 'Anna', type: 'BIRTH', sortOrder: 0 },
|
||||
{ id: 'a2', lastName: 'Schmidt', firstName: null, type: 'MARRIED', sortOrder: 1 }
|
||||
];
|
||||
|
||||
function renderCard(overrides: Record<string, unknown> = {}) {
|
||||
const service = createConfirmService();
|
||||
const result = render(NameHistoryEditCard, {
|
||||
props: { aliases, canWrite: true, ...overrides },
|
||||
context: new Map([[CONFIRM_KEY, service]])
|
||||
});
|
||||
return { ...result, service };
|
||||
}
|
||||
|
||||
// ─── Rendering ────────────────────────────────────────────────────────────────
|
||||
|
||||
describe('NameHistoryEditCard — rendering', () => {
|
||||
it('renders alias last names', async () => {
|
||||
renderCard();
|
||||
await expect.element(page.getByText('Müller')).toBeInTheDocument();
|
||||
await expect.element(page.getByText('Schmidt')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders delete buttons when canWrite', async () => {
|
||||
renderCard();
|
||||
const btns = document.querySelectorAll('button[type="button"]');
|
||||
expect(btns.length).toBeGreaterThanOrEqual(2);
|
||||
});
|
||||
|
||||
it('does not render delete buttons when canWrite is false', async () => {
|
||||
renderCard({ canWrite: false });
|
||||
const btns = document.querySelectorAll<HTMLButtonElement>('button[type="button"]');
|
||||
expect(btns.length).toBe(0);
|
||||
});
|
||||
|
||||
it('does not show the inline delete modal (replaced by ConfirmService)', async () => {
|
||||
renderCard();
|
||||
// The old inline modal div with "fixed inset-0" should not exist
|
||||
const modal = document.querySelector('.fixed.inset-0');
|
||||
expect(modal).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Delete confirmation ──────────────────────────────────────────────────────
|
||||
|
||||
describe('NameHistoryEditCard — delete confirmation', () => {
|
||||
it('opens confirm dialog when delete button is clicked', async () => {
|
||||
const { service } = renderCard();
|
||||
const deleteBtn = document.querySelector<HTMLButtonElement>('button[type="button"]')!;
|
||||
deleteBtn.click();
|
||||
await vi.waitFor(() => expect(service.options).not.toBeNull());
|
||||
expect(service.options?.destructive).toBe(true);
|
||||
service.settle(false);
|
||||
});
|
||||
|
||||
it('submits removeAlias form when user confirms', async () => {
|
||||
const { service } = renderCard();
|
||||
const requestSubmit = vi
|
||||
.spyOn(HTMLFormElement.prototype, 'requestSubmit')
|
||||
.mockImplementation(() => {});
|
||||
|
||||
const deleteBtn = document.querySelector<HTMLButtonElement>('button[type="button"]')!;
|
||||
deleteBtn.click();
|
||||
await vi.waitFor(() => expect(service.options).not.toBeNull());
|
||||
service.settle(true);
|
||||
|
||||
// Wait for the async handleDelete callback to call requestSubmit
|
||||
await vi.waitFor(() => expect(requestSubmit).toHaveBeenCalledOnce());
|
||||
requestSubmit.mockRestore();
|
||||
});
|
||||
|
||||
it('does not submit form when user cancels', async () => {
|
||||
const { service } = renderCard();
|
||||
const requestSubmit = vi
|
||||
.spyOn(HTMLFormElement.prototype, 'requestSubmit')
|
||||
.mockImplementation(() => {});
|
||||
|
||||
const deleteBtn = document.querySelector<HTMLButtonElement>('button[type="button"]')!;
|
||||
deleteBtn.click();
|
||||
await vi.waitFor(() => expect(service.options).not.toBeNull());
|
||||
service.settle(false);
|
||||
await vi.waitFor(() => expect(service.options).toBeNull());
|
||||
|
||||
// Allow pending microtasks to flush before asserting
|
||||
await Promise.resolve();
|
||||
expect(requestSubmit).not.toHaveBeenCalled();
|
||||
requestSubmit.mockRestore();
|
||||
});
|
||||
|
||||
it('submits with the correct aliasId when second alias is deleted', async () => {
|
||||
const { service } = renderCard();
|
||||
const requestSubmit = vi
|
||||
.spyOn(HTMLFormElement.prototype, 'requestSubmit')
|
||||
.mockImplementation(() => {});
|
||||
|
||||
// Click delete button for the second alias (Schmidt)
|
||||
const deleteBtns = document.querySelectorAll<HTMLButtonElement>('button[type="button"]');
|
||||
deleteBtns[1].click();
|
||||
await vi.waitFor(() => expect(service.options).not.toBeNull());
|
||||
service.settle(true);
|
||||
|
||||
await vi.waitFor(() => expect(requestSubmit).toHaveBeenCalledOnce());
|
||||
const submittedForm = requestSubmit.mock.instances[0] as HTMLFormElement;
|
||||
const aliasIdInput = submittedForm.querySelector<HTMLInputElement>('input[name="aliasId"]');
|
||||
expect(aliasIdInput?.value).toBe('a2');
|
||||
requestSubmit.mockRestore();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user