Files
tessera-ctl/apps/web/src/components/settings/calendar-source-form.test.tsx
T
schalli 2306a6dee1 feat(web): typabhaengiger URL-Platzhalter + EWS-Hinweis im Kalenderquellen-Formular
- Platzhalter je Typ (CalDAV/ICS/Exchange-Graph/Exchange-EWS), ohne Typ weiterhin https://
- Grauer Hinweis unter dem Feld nur bei Exchange + EWS, unterhalb eines eventuellen Fehlers
- Neuer Komponententest mit 6 Faellen (TDD: rot vor der Implementierung)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 12:47:09 +02:00

114 lines
4.5 KiB
TypeScript

import { cleanup, fireEvent, render, screen } from '@testing-library/react';
import { afterEach, describe, expect, it, vi } from 'vitest';
import de from '@/messages/de.json';
import { CalendarSourceForm } from './calendar-source-form';
/**
* calendar-source-form.test — NEU (quick-260916-hiv). Deckt den
* typabhaengigen URL-Platzhalter und den grauen EWS-Hinweis ab.
* Texte aus der echten de.json.
*/
vi.mock('next-intl', async () => {
const messages = (await import('@/messages/de.json')).default as Record<string, unknown>;
const lookup = (path: string): string | undefined =>
path.split('.').reduce<unknown>((o, k) => (o && typeof o === 'object' ? (o as any)[k] : undefined), messages) as
| string
| undefined;
return {
useTranslations: (ns?: string) => (key: string) => lookup(ns ? `${ns}.${key}` : key) ?? key,
};
});
vi.mock('@/lib/calendar-api', () => ({
testSourceConfig: vi.fn(),
testSource: vi.fn(),
}));
const t = (de as { widgets: { calendar: Record<string, string> } }).widgets.calendar;
afterEach(() => {
cleanup();
});
function renderForm() {
const onSave = vi.fn();
const onCancel = vi.fn();
render(<CalendarSourceForm onSave={onSave} onCancel={onCancel} />);
return {
onSave,
onCancel,
urlInput: screen.getByLabelText(/Adresse \(URL\)/) as HTMLInputElement,
typeSelect: screen.getByLabelText(/^Typ/) as HTMLSelectElement,
};
}
describe('CalendarSourceForm — URL-Platzhalter je Typ + EWS-Hinweis (quick-260916-hiv)', () => {
it('Test 1: ohne Typ zeigt das URL-Feld https:// und keinen EWS-Hinweis', () => {
const { urlInput } = renderForm();
expect(urlInput.placeholder).toBe('https://');
expect(screen.queryByTestId('source-url-hint-ews')).not.toBeInTheDocument();
});
it('Test 2: CalDAV zeigt den CalDAV-Platzhalter, keinen Hinweis', () => {
const { urlInput, typeSelect } = renderForm();
fireEvent.change(typeSelect, { target: { value: 'caldav' } });
expect(urlInput.placeholder).toBe(t.formFieldUrlPlaceholderCaldav);
expect(screen.queryByTestId('source-url-hint-ews')).not.toBeInTheDocument();
});
it('Test 3: ICS zeigt den ICS-Platzhalter, keinen Hinweis', () => {
const { urlInput, typeSelect } = renderForm();
fireEvent.change(typeSelect, { target: { value: 'ics' } });
expect(urlInput.placeholder).toBe(t.formFieldUrlPlaceholderIcs);
expect(screen.queryByTestId('source-url-hint-ews')).not.toBeInTheDocument();
});
it('Test 4: Exchange (Standardmodus Graph) zeigt den Graph-Platzhalter, keinen Hinweis', () => {
const { urlInput, typeSelect } = renderForm();
fireEvent.change(typeSelect, { target: { value: 'exchange' } });
expect(urlInput.placeholder).toBe(t.formFieldUrlPlaceholderGraph);
expect(screen.queryByTestId('source-url-hint-ews')).not.toBeInTheDocument();
});
it('Test 5: Exchange + EWS zeigt den EWS-Platzhalter und den grauen Hinweis; zurueck auf Graph verschwindet beides', () => {
const { urlInput, typeSelect } = renderForm();
fireEvent.change(typeSelect, { target: { value: 'exchange' } });
const exchangeModeSelect = screen.getByLabelText(/Exchange-Anbindung/) as HTMLSelectElement;
fireEvent.change(exchangeModeSelect, { target: { value: 'ews' } });
expect(urlInput.placeholder).toBe(t.formFieldUrlPlaceholderEws);
const hint = screen.getByTestId('source-url-hint-ews');
expect(hint).toHaveTextContent(t.formFieldUrlHintEws);
expect(hint.className).toContain('text-muted-foreground');
fireEvent.change(exchangeModeSelect, { target: { value: 'graph' } });
expect(screen.queryByTestId('source-url-hint-ews')).not.toBeInTheDocument();
expect(urlInput.placeholder).toBe(t.formFieldUrlPlaceholderGraph);
});
it('Test 6: Exchange + EWS mit http-Fehler zeigt Fehler UND Hinweis, Hinweis steht nach dem Fehler', () => {
const { urlInput, typeSelect } = renderForm();
fireEvent.change(typeSelect, { target: { value: 'exchange' } });
const exchangeModeSelect = screen.getByLabelText(/Exchange-Anbindung/) as HTMLSelectElement;
fireEvent.change(exchangeModeSelect, { target: { value: 'ews' } });
fireEvent.change(urlInput, { target: { value: 'http://mail.firma.de/EWS/Exchange.asmx' } });
const fehler = screen.getByText(t.formUrlErrorHttps);
const hinweis = screen.getByTestId('source-url-hint-ews');
expect(fehler).toBeInTheDocument();
expect(hinweis).toBeInTheDocument();
expect(fehler.compareDocumentPosition(hinweis) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
});
});