/** * Tests fuer My-Tasks Dashboard * Sprint 4: Stakeholder-Views & Rollenbasierte Features */ import React from 'react' import { render, screen, fireEvent, waitFor } from '@testing-library/react' import '@testing-library/jest-dom' // Mock next/navigation const mockPush = jest.fn() jest.mock('next/navigation', () => ({ useRouter: () => ({ push: mockPush, }), })) // Mock localStorage const localStorageMock = { getItem: jest.fn(), setItem: jest.fn(), removeItem: jest.fn(), clear: jest.fn(), } Object.defineProperty(window, 'localStorage', { value: localStorageMock }) // Import nach Mocks import MyTasksPage from '@/app/admin/compliance/my-tasks/page' describe('MyTasksPage', () => { beforeEach(() => { jest.clearAllMocks() localStorageMock.getItem.mockReturnValue(null) }) describe('Rendering', () => { it('rendert Seitentitel', () => { render() expect(screen.getByText(/Meine Aufgaben|My Tasks/i)).toBeInTheDocument() }) it('zeigt Statistik-Karten', () => { render() // Statistik-Kategorien sollten sichtbar sein expect(screen.getByText(/Offen|Open/i)).toBeInTheDocument() expect(screen.getByText(/In Bearbeitung|In Progress/i)).toBeInTheDocument() expect(screen.getByText(/Heute fällig|Due Today/i)).toBeInTheDocument() expect(screen.getByText(/Überfällig|Overdue/i)).toBeInTheDocument() }) it('zeigt Task-Liste mit Mock-Daten', () => { render() // Mindestens ein Task sollte sichtbar sein (Mock-Daten) expect(screen.getAllByRole('button').length).toBeGreaterThan(0) }) }) describe('Filter-Funktionalität', () => { it('zeigt Status-Filter Dropdown', () => { render() const statusFilter = screen.getByRole('combobox', { name: /status/i }) expect(statusFilter).toBeInTheDocument() }) it('zeigt Typ-Filter Dropdown', () => { render() const typeFilter = screen.getByRole('combobox', { name: /typ|type/i }) expect(typeFilter).toBeInTheDocument() }) it('zeigt Prioritaet-Filter Dropdown', () => { render() const priorityFilter = screen.getByRole('combobox', { name: /priorität|priority/i }) expect(priorityFilter).toBeInTheDocument() }) it('filtert Tasks nach Status', async () => { render() const statusFilter = screen.getByRole('combobox', { name: /status/i }) fireEvent.change(statusFilter, { target: { value: 'pending' } }) // Nach Filter-Aenderung sollten nur pending Tasks sichtbar sein await waitFor(() => { const tasks = screen.getAllByRole('listitem') // Alle sichtbaren Tasks sollten pending Status haben tasks.forEach(task => { expect(task).not.toHaveTextContent(/Abgeschlossen|Completed/i) }) }) }) }) describe('Sortierung', () => { it('zeigt Sortier-Optionen', () => { render() const sortSelect = screen.getByRole('combobox', { name: /sortieren|sort/i }) expect(sortSelect).toBeInTheDocument() }) it('kann nach Faelligkeit sortieren', () => { render() const sortSelect = screen.getByRole('combobox', { name: /sortieren|sort/i }) fireEvent.change(sortSelect, { target: { value: 'due_date' } }) // Erste Task sollte die frueheste Faelligkeit haben // (Implementierung haengt von Mock-Daten ab) }) it('kann nach Prioritaet sortieren', () => { render() const sortSelect = screen.getByRole('combobox', { name: /sortieren|sort/i }) fireEvent.change(sortSelect, { target: { value: 'priority' } }) // Erste Task sollte hoechste Prioritaet haben }) }) describe('Task-Typen', () => { it('zeigt control_review Tasks', () => { render() // control_review Tasks sollten in der Liste sein expect(screen.queryByText(/Control|Kontrolle/i)).toBeDefined() }) it('zeigt evidence_upload Tasks', () => { render() // evidence_upload Tasks sollten in der Liste sein expect(screen.queryByText(/Evidence|Nachweis/i)).toBeDefined() }) it('zeigt signoff Tasks', () => { render() // signoff Tasks sollten in der Liste sein expect(screen.queryByText(/Sign-off|Freigabe/i)).toBeDefined() }) it('zeigt risk_treatment Tasks', () => { render() // risk_treatment Tasks sollten in der Liste sein expect(screen.queryByText(/Risiko|Risk/i)).toBeDefined() }) }) describe('Task-Klick', () => { it('navigiert zum entsprechenden Control bei control_review', async () => { render() // Finde einen control_review Task und klicke const controlTask = screen.getAllByRole('button').find(btn => btn.textContent?.includes('Control') || btn.textContent?.includes('Kontrolle') ) if (controlTask) { fireEvent.click(controlTask) expect(mockPush).toHaveBeenCalled() } }) it('navigiert zur Evidence-Seite bei evidence_upload', async () => { render() const evidenceTask = screen.getAllByRole('button').find(btn => btn.textContent?.includes('Evidence') || btn.textContent?.includes('Nachweis') ) if (evidenceTask) { fireEvent.click(evidenceTask) expect(mockPush).toHaveBeenCalled() } }) }) describe('Prioritaets-Darstellung', () => { it('zeigt critical Tasks mit roter Markierung', () => { render() // Critical Tasks sollten rote Markierung haben const criticalBadges = document.querySelectorAll('.bg-red-500, .text-red-500, .border-red-500') // Mindestens ein critical Task sollte vorhanden sein (aus Mock-Daten) }) it('zeigt high Tasks mit oranger Markierung', () => { render() // High Tasks sollten orange Markierung haben const highBadges = document.querySelectorAll('.bg-orange-500, .text-orange-500, .border-orange-500') }) it('zeigt medium Tasks mit gelber Markierung', () => { render() // Medium Tasks sollten gelbe Markierung haben const mediumBadges = document.querySelectorAll('.bg-yellow-500, .text-yellow-500, .border-yellow-500') }) }) describe('Sprachumschaltung', () => { it('zeigt deutschen Text als Standard', () => { localStorageMock.getItem.mockReturnValue(null) render() expect(screen.getByText(/Meine Aufgaben/i)).toBeInTheDocument() }) it('zeigt englischen Text bei en-Einstellung', () => { localStorageMock.getItem.mockReturnValue('en') render() expect(screen.getByText(/My Tasks/i)).toBeInTheDocument() }) }) describe('Leere-State', () => { it('zeigt Hinweis wenn keine Tasks vorhanden', () => { // Mock: Keine Tasks // render mit leerem Task-Array // expect(screen.getByText(/Keine Aufgaben|No tasks/i)).toBeInTheDocument() }) }) })