import { describe, it, expect, vi, beforeEach } from 'vitest'; import { render, screen, fireEvent, waitFor } from '@testing-library/react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { BrowserRouter } from 'react-router-dom'; import { ReportsPage } from '../Reports'; // Mock the API hooks vi.mock('@/api/reports', () => ({ useReportTemplates: vi.fn(() => ({ data: [ { id: 'tpl-1', name: 'My Report', description: 'Test', template_type: 'jinja2', content: '', output_format: 'pdf', created_by: 'user-1' }, { id: 'tpl-2', name: 'CSV Report', description: 'Test CSV', template_type: 'jinja2', content: 'name,email', output_format: 'csv', created_by: 'user-1' }, ], isLoading: false, })), useReportPresets: vi.fn(() => ({ data: [ { key: 'contact_list', name: 'Kontaktliste', description: 'Liste aller Kontakte', icon: 'Users', output_formats: ['pdf', 'print', 'csv', 'excel'] }, { key: 'company_list', name: 'Firmenliste', description: 'Liste aller Firmen', icon: 'Building2', output_formats: ['pdf', 'print', 'csv', 'excel'] }, ], })), useCreateReportTemplate: vi.fn(() => ({ mutateAsync: vi.fn().mockResolvedValue({}), isPending: false, })), useUpdateReportTemplate: vi.fn(() => ({ mutateAsync: vi.fn().mockResolvedValue({}), isPending: false, })), useDeleteReportTemplate: vi.fn(() => ({ mutateAsync: vi.fn().mockResolvedValue({}), isPending: false, })), useGenerateReport: vi.fn(() => ({ mutateAsync: vi.fn().mockResolvedValue({ data: new Blob(['test'], { type: 'application/pdf' }) }), isPending: false, })), useGeneratePresetReport: vi.fn(() => ({ mutateAsync: vi.fn().mockResolvedValue({ data: new Blob(['test'], { type: 'application/pdf' }) }), isPending: false, })), downloadBlob: vi.fn(), })); // Mock i18next vi.mock('react-i18next', () => ({ useTranslation: () => ({ t: (key: string, fallback?: string) => fallback || key, i18n: { language: 'de' }, }), })); // Mock toast vi.mock('@/components/ui/Toast', () => ({ useToast: () => ({ toast: { success: vi.fn(), error: vi.fn() }, }), })); // Mock lucide-react icons vi.mock('lucide-react', () => { const Icon = ({ className }: { className?: string }) =>
; return { BarChart3: Icon, Building2: Icon, Calendar: Icon, CalendarDays: Icon, Download: Icon, FileText: Icon, Loader2: Icon, Plus: Icon, Printer: Icon, Save: Icon, ShieldCheck: Icon, Trash2: Icon, Users: Icon, }; }); // Helper to render with providers function renderWithProviders(ui: React.ReactElement) { const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false }, mutations: { retry: false } }, }); return render( {ui} ); } describe('ReportsPage', () => { beforeEach(() => { vi.clearAllMocks(); }); it('renders the reports page with title and preset quick actions', () => { renderWithProviders(); expect(screen.getByTestId('reports-page')).toBeInTheDocument(); expect(screen.getByTestId('preset-quick-actions')).toBeInTheDocument(); // Should have preset buttons for contact_list and company_list expect(screen.getByTestId('preset-contact_list-pdf')).toBeInTheDocument(); expect(screen.getByTestId('preset-company_list-pdf')).toBeInTheDocument(); }); it('displays templates in the template list', () => { renderWithProviders(); expect(screen.getByTestId('template-list-panel')).toBeInTheDocument(); expect(screen.getByText('My Report')).toBeInTheDocument(); expect(screen.getByText('CSV Report')).toBeInTheDocument(); }); it('clicking new template button shows editor with default content', () => { renderWithProviders(); const newBtn = screen.getByTestId('btn-new-template'); fireEvent.click(newBtn); // Editor should be visible with template name input expect(screen.getByTestId('input-template-name')).toBeInTheDocument(); expect(screen.getByTestId('textarea-template-content')).toBeInTheDocument(); expect(screen.getByTestId('btn-save-template')).toBeInTheDocument(); }); it('selecting a template loads it into the editor', () => { renderWithProviders(); // Click on the first template fireEvent.click(screen.getByText('My Report')); // Editor should show the template name const nameInput = screen.getByTestId('input-template-name') as HTMLInputElement; expect(nameInput.value).toBe('My Report'); }); it('shows download history section', () => { renderWithProviders(); expect(screen.getByTestId('download-history')).toBeInTheDocument(); }); });