import { describe, it, expect, afterEach, vi } from 'vitest'; import { cleanup, render } from 'vitest-browser-svelte'; import { page } from 'vitest/browser'; import ConfirmDialog from './ConfirmDialog.svelte'; import { createConfirmService, CONFIRM_KEY } from '$lib/shared/services/confirm.svelte.js'; afterEach(cleanup); function renderDialog() { const service = createConfirmService(); const result = render(ConfirmDialog, { context: new Map([[CONFIRM_KEY, service]]) }); return { ...result, service }; } describe('ConfirmDialog', () => { it('renders the title when options are set', async () => { const { service } = renderDialog(); service.confirm({ title: 'Delete this item?' }); await expect.element(page.getByText('Delete this item?')).toBeInTheDocument(); service.settle(false); }); it('renders the body when provided', async () => { const { service } = renderDialog(); service.confirm({ title: 'Delete?', body: 'This cannot be undone.' }); await expect.element(page.getByText('This cannot be undone.')).toBeInTheDocument(); service.settle(false); }); it('does not render body element when body is omitted', async () => { const { service } = renderDialog(); service.confirm({ title: 'Delete?' }); await expect.element(page.getByText('Delete?')).toBeInTheDocument(); const body = document.querySelector('p'); expect(body).toBeNull(); service.settle(false); }); it('applies bg-danger class on confirm button when destructive', async () => { const { service } = renderDialog(); service.confirm({ title: 'Delete?', destructive: true }); await expect.element(page.getByText('Delete?')).toBeInTheDocument(); const confirmBtn = document.querySelector('button[class*="bg-danger"]'); expect(confirmBtn).not.toBeNull(); service.settle(false); }); it('applies bg-primary class on confirm button when not destructive', async () => { const { service } = renderDialog(); service.confirm({ title: 'Confirm action?' }); await expect.element(page.getByText('Confirm action?')).toBeInTheDocument(); const confirmBtn = document.querySelector('button[class*="bg-primary"]'); expect(confirmBtn).not.toBeNull(); service.settle(false); }); it('renders custom confirmLabel when provided', async () => { const { service } = renderDialog(); service.confirm({ title: 'Remove?', confirmLabel: 'Yes, remove it' }); await expect.element(page.getByRole('button', { name: 'Yes, remove it' })).toBeInTheDocument(); service.settle(false); }); it('renders custom cancelLabel when provided', async () => { const { service } = renderDialog(); service.confirm({ title: 'Remove?', cancelLabel: 'No, keep it' }); await expect.element(page.getByRole('button', { name: 'No, keep it' })).toBeInTheDocument(); service.settle(false); }); it('settles true when confirm button is clicked', async () => { const { service } = renderDialog(); const resultPromise = service.confirm({ title: 'Do it?' }); await expect.element(page.getByText('Do it?')).toBeInTheDocument(); const confirmBtn = document.querySelectorAll('button[type="button"]')[1]; confirmBtn.click(); expect(await resultPromise).toBe(true); }); it('settles false when cancel button is clicked', async () => { const { service } = renderDialog(); const resultPromise = service.confirm({ title: 'Do it?' }); await expect.element(page.getByText('Do it?')).toBeInTheDocument(); const cancelBtn = document.querySelectorAll('button[type="button"]')[0]; cancelBtn.click(); expect(await resultPromise).toBe(false); }); it('hides content when no options are set', () => { renderDialog(); const heading = document.querySelector('#confirm-title'); expect(heading).toBeNull(); }); it('has aria-labelledby pointing to the title element', async () => { const { service } = renderDialog(); service.confirm({ title: 'Accessible title' }); await expect.element(page.getByText('Accessible title')).toBeInTheDocument(); const dialog = document.querySelector('dialog'); expect(dialog?.getAttribute('aria-labelledby')).toBe('confirm-title'); const title = document.getElementById('confirm-title'); expect(title).not.toBeNull(); service.settle(false); }); it('does not show content after settling', async () => { const { service } = renderDialog(); service.confirm({ title: 'Gone soon?' }); await expect.element(page.getByText('Gone soon?')).toBeInTheDocument(); service.settle(false); await vi.waitFor(() => { expect(document.querySelector('#confirm-title')).toBeNull(); }); }); });