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; const lookup = (path: string): string | undefined => path.split('.').reduce((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 } }).widgets.calendar; afterEach(() => { cleanup(); }); function renderForm() { const onSave = vi.fn(); const onCancel = vi.fn(); render(); 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(); }); });