119 lines
4.6 KiB
TypeScript
119 lines
4.6 KiB
TypeScript
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();
|
|
});
|
|
});
|