import React from 'react'; import { describe, it, expect, vi, beforeEach } from 'vitest'; import { render, screen, fireEvent, waitFor } from '@testing-library/react'; import { AppointmentModal } from '@/components/calendar/AppointmentModal'; import type { Calendar } from '@/api/calendar'; vi.mock('@/api/calendar', async () => { const actual = await vi.importActual('@/api/calendar'); return { ...actual, createEntry: vi.fn(), updateEntry: vi.fn(), deleteEntry: vi.fn(), }; }); import { createEntry } from '@/api/calendar'; const calendars: Calendar[] = [ { id: 'cal-1', name: 'Persönlich', color: '#3B82F6', type: 'personal', owner_id: 'u-1' }, ]; beforeEach(() => { vi.clearAllMocks(); }); describe('AppointmentModal validation (RHF + Zod)', () => { it('shows validation error when title is empty', async () => { render( ); fireEvent.click(screen.getByTestId('appointment-save')); const err = await screen.findByTestId('appointment-error'); expect(err.textContent?.toLowerCase()).toContain('erforderlich'); }); it('shows error when end is before start', async () => { render( ); // Set title so only date validation fails fireEvent.change(screen.getByTestId('appointment-title'), { target: { value: 'Test' } }); // Set end before start fireEvent.change(screen.getByTestId('appointment-end'), { target: { value: '2026-07-01T08:00' } }); fireEvent.click(screen.getByTestId('appointment-save')); await waitFor(() => { const err = screen.queryByTestId('appointment-error'); expect(err).toBeTruthy(); }); }); it('submits successfully with valid data', async () => { (createEntry as unknown as ReturnType).mockResolvedValue({ id: 'e-1', calendar_id: 'cal-1', entry_type: 'appointment', subtype: 'normal', title: 'Test', description: null, location: null, start_at: '2026-07-01T09:00:00.000Z', end_at: '2026-07-01T10:00:00.000Z', all_day: false, priority: 'medium', status: 'open', created_by: 'u-1', }); const onSaved = vi.fn(); render( ); fireEvent.change(screen.getByTestId('appointment-title'), { target: { value: 'Test Termin' } }); fireEvent.click(screen.getByTestId('appointment-save')); await waitFor(() => { expect(createEntry).toHaveBeenCalledTimes(1); }); expect(onSaved).toHaveBeenCalled(); }); });