108 lines
3.4 KiB
TypeScript
108 lines
3.4 KiB
TypeScript
import { page } from 'vitest/browser';
|
|
import { describe, it, expect, vi } from 'vitest';
|
|
import { render } from 'vitest-browser-svelte';
|
|
import ProclamationBrowser from './ProclamationBrowser.svelte';
|
|
|
|
const categories = [
|
|
{ id: 1, name: 'Physical' },
|
|
{ id: 2, name: 'Mental' },
|
|
{ id: 3, name: 'Empty' }
|
|
];
|
|
|
|
const groups = [
|
|
{ id: 1, name: 'Prayers' },
|
|
{ id: 2, name: 'Scripture' }
|
|
];
|
|
|
|
const proclamations = [
|
|
{ id: 'p1', name: 'Healing', categoryId: 1, groupId: 1 },
|
|
{ id: 'p2', name: 'Strength', categoryId: 1, groupId: 1 },
|
|
{ id: 'p3', name: 'Focus', categoryId: 1, groupId: null },
|
|
{ id: 'p4', name: 'Calm', categoryId: 2, groupId: 2 }
|
|
];
|
|
|
|
function mount(overrides: Record<string, unknown> = {}) {
|
|
return render(ProclamationBrowser, {
|
|
categories,
|
|
groups,
|
|
proclamations,
|
|
selectedIds: [],
|
|
onChange: () => {},
|
|
...overrides
|
|
});
|
|
}
|
|
|
|
async function click(locator: { element: () => HTMLElement | SVGElement }) {
|
|
const el = locator.element() as HTMLElement;
|
|
el.click();
|
|
}
|
|
|
|
describe('ProclamationBrowser', () => {
|
|
it('collapses categories by default', async () => {
|
|
mount();
|
|
|
|
await expect.element(page.getByRole('button', { name: 'Physical' })).toBeInTheDocument();
|
|
await expect.element(page.getByRole('checkbox', { name: 'Healing' })).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('reveals pre-expanded groups and their proclamations when a category opens', async () => {
|
|
mount();
|
|
|
|
await click(page.getByRole('button', { name: 'Physical' }));
|
|
|
|
await expect.element(page.getByText('Prayers')).toBeInTheDocument();
|
|
await expect.element(page.getByRole('checkbox', { name: 'Healing' })).toBeInTheDocument();
|
|
await expect.element(page.getByRole('checkbox', { name: 'Strength' })).toBeInTheDocument();
|
|
});
|
|
|
|
it('hides groups that have no proclamations in the category', async () => {
|
|
mount();
|
|
|
|
await click(page.getByRole('button', { name: 'Physical' }));
|
|
|
|
await expect.element(page.getByText('Scripture')).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('lists ungrouped proclamations below the groups', async () => {
|
|
mount();
|
|
|
|
await click(page.getByRole('button', { name: 'Physical' }));
|
|
|
|
await expect.element(page.getByRole('checkbox', { name: 'Focus' })).toBeInTheDocument();
|
|
});
|
|
|
|
it('reports toggled selections through onChange', async () => {
|
|
const onChange = vi.fn();
|
|
mount({ selectedIds: ['p1'], onChange });
|
|
|
|
await click(page.getByRole('button', { name: 'Physical' }));
|
|
await click(page.getByRole('checkbox', { name: 'Strength' }));
|
|
|
|
expect(onChange).toHaveBeenCalledWith(['p1', 'p2']);
|
|
|
|
await click(page.getByRole('checkbox', { name: 'Healing' }));
|
|
expect(onChange).toHaveBeenCalledWith([]);
|
|
});
|
|
|
|
it('shows selected titles in the summary and keeps selection across collapse', async () => {
|
|
mount({ selectedIds: ['p1'] });
|
|
|
|
await expect.element(page.getByText('Selected (1)')).toBeInTheDocument();
|
|
|
|
await click(page.getByRole('button', { name: 'Physical' }));
|
|
const checkbox = (await page
|
|
.getByRole('checkbox', { name: 'Healing' })
|
|
.element()) as HTMLInputElement;
|
|
expect(checkbox.checked).toBe(true);
|
|
|
|
await click(page.getByRole('button', { name: 'Physical' }));
|
|
await expect.element(page.getByRole('checkbox', { name: 'Healing' })).not.toBeInTheDocument();
|
|
await click(page.getByRole('button', { name: 'Physical' }));
|
|
|
|
const reopened = (await page
|
|
.getByRole('checkbox', { name: 'Healing' })
|
|
.element()) as HTMLInputElement;
|
|
expect(reopened.checked).toBe(true);
|
|
});
|
|
});
|