test(briefwechsel): cover ConversationFilterBar branches
Two persontypeaheads + two date inputs, swap button visible/invisible based on both persons set, sort label DESC vs ASC, chevron rotation, onapplyFilters / ontoggleSort / onswapPersons callbacks fire. 11 tests covering ~20 branches. Refs #496. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,119 @@
|
|||||||
|
import { describe, it, expect, vi, afterEach } from 'vitest';
|
||||||
|
import { cleanup, render } from 'vitest-browser-svelte';
|
||||||
|
import { page } from 'vitest/browser';
|
||||||
|
import ConversationFilterBar from './ConversationFilterBar.svelte';
|
||||||
|
|
||||||
|
afterEach(cleanup);
|
||||||
|
|
||||||
|
const baseProps = (overrides: Record<string, unknown> = {}) => ({
|
||||||
|
senderId: '',
|
||||||
|
receiverId: '',
|
||||||
|
fromDate: '',
|
||||||
|
toDate: '',
|
||||||
|
sortDir: 'DESC',
|
||||||
|
initialSenderName: '',
|
||||||
|
initialReceiverName: '',
|
||||||
|
onapplyFilters: () => {},
|
||||||
|
ontoggleSort: () => {},
|
||||||
|
onswapPersons: () => {},
|
||||||
|
...overrides
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('ConversationFilterBar', () => {
|
||||||
|
it('renders the two PersonTypeahead inputs and the date inputs', async () => {
|
||||||
|
render(ConversationFilterBar, { props: baseProps() });
|
||||||
|
|
||||||
|
const dateInputs = document.querySelectorAll('input[type="date"]');
|
||||||
|
expect(dateInputs.length).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('marks the swap button invisible when only one person is set', async () => {
|
||||||
|
render(ConversationFilterBar, { props: baseProps({ senderId: 'p1' }) });
|
||||||
|
|
||||||
|
const swap = document.querySelector('[data-testid="conv-swap-btn"]') as HTMLElement;
|
||||||
|
expect(swap.className).toContain('invisible');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('marks the swap button visible when both persons are set', async () => {
|
||||||
|
render(ConversationFilterBar, {
|
||||||
|
props: baseProps({ senderId: 'p1', receiverId: 'p2' })
|
||||||
|
});
|
||||||
|
|
||||||
|
const swap = document.querySelector('[data-testid="conv-swap-btn"]') as HTMLElement;
|
||||||
|
expect(swap.className).not.toContain('invisible');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders "Neueste zuerst" when sortDir is DESC', async () => {
|
||||||
|
render(ConversationFilterBar, { props: baseProps({ sortDir: 'DESC' }) });
|
||||||
|
|
||||||
|
await expect.element(page.getByText('Neueste zuerst')).toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders "Älteste zuerst" when sortDir is ASC', async () => {
|
||||||
|
render(ConversationFilterBar, { props: baseProps({ sortDir: 'ASC' }) });
|
||||||
|
|
||||||
|
await expect.element(page.getByText('Älteste zuerst')).toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rotates the chevron 180° when sortDir is ASC', async () => {
|
||||||
|
render(ConversationFilterBar, { props: baseProps({ sortDir: 'ASC' }) });
|
||||||
|
|
||||||
|
const sortBtn = Array.from(document.querySelectorAll('button')).find((b) =>
|
||||||
|
b.textContent?.toLowerCase().includes('älteste')
|
||||||
|
);
|
||||||
|
const chevron = sortBtn?.querySelector('svg');
|
||||||
|
expect(chevron?.getAttribute('class')).toContain('rotate-180');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not rotate the chevron when sortDir is DESC', async () => {
|
||||||
|
render(ConversationFilterBar, { props: baseProps({ sortDir: 'DESC' }) });
|
||||||
|
|
||||||
|
const sortBtn = Array.from(document.querySelectorAll('button')).find((b) =>
|
||||||
|
b.textContent?.toLowerCase().includes('neueste')
|
||||||
|
);
|
||||||
|
const chevron = sortBtn?.querySelector('svg');
|
||||||
|
expect(chevron?.getAttribute('class')).not.toContain('rotate-180');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calls ontoggleSort when the sort button is clicked', async () => {
|
||||||
|
const ontoggleSort = vi.fn();
|
||||||
|
render(ConversationFilterBar, { props: baseProps({ ontoggleSort }) });
|
||||||
|
|
||||||
|
const sortBtn = Array.from(document.querySelectorAll('button')).find((b) =>
|
||||||
|
b.textContent?.toLowerCase().includes('neueste')
|
||||||
|
);
|
||||||
|
sortBtn?.click();
|
||||||
|
expect(ontoggleSort).toHaveBeenCalledOnce();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calls onswapPersons when the swap button is clicked', async () => {
|
||||||
|
const onswapPersons = vi.fn();
|
||||||
|
render(ConversationFilterBar, {
|
||||||
|
props: baseProps({ senderId: 'p1', receiverId: 'p2', onswapPersons })
|
||||||
|
});
|
||||||
|
|
||||||
|
const swap = document.querySelector('[data-testid="conv-swap-btn"]') as HTMLElement;
|
||||||
|
swap.click();
|
||||||
|
expect(onswapPersons).toHaveBeenCalledOnce();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calls onapplyFilters when fromDate input changes', async () => {
|
||||||
|
const onapplyFilters = vi.fn();
|
||||||
|
render(ConversationFilterBar, { props: baseProps({ onapplyFilters }) });
|
||||||
|
|
||||||
|
const fromInput = document.querySelector('#dateFrom') as HTMLInputElement;
|
||||||
|
fromInput.value = '1899-04-14';
|
||||||
|
fromInput.dispatchEvent(new Event('change', { bubbles: true }));
|
||||||
|
expect(onapplyFilters).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calls onapplyFilters when toDate input changes', async () => {
|
||||||
|
const onapplyFilters = vi.fn();
|
||||||
|
render(ConversationFilterBar, { props: baseProps({ onapplyFilters }) });
|
||||||
|
|
||||||
|
const toInput = document.querySelector('#dateTo') as HTMLInputElement;
|
||||||
|
toInput.value = '1950-12-31';
|
||||||
|
toInput.dispatchEvent(new Event('change', { bubbles: true }));
|
||||||
|
expect(onapplyFilters).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user