diff --git a/PROGRESS.md b/PROGRESS.md index 1e3868b..70569b0 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -7,8 +7,8 @@ **Offene Pakete (nach Größe, kleinste zuerst):** 1. **Saved-Filters 422-Test** — ✅ erledigt (d7b3c7c... der Fix wurde 2026-08-28 in `0d052ab` deployed) -2. **AppShell ×4 + Router ×2 Mock-Fixes** — useCurrentUser-Export fehlt im `@/api/hooks`-Mock (AppShell.test.tsx Zeile 14, ~10 Z.) + QueryClientProvider für Router-Tests (2,Z.); siehe #357 -3. **ContactEditModal File-Level** — separate Ursache, braucht Mock-Diagnose +2. **AppShell ×4 + Router ×2 Mock-Fixes** — ✅ erledigt (2026-08-28): AppShell war bereits grün (useCurrentUser-Mock existierte in Zeile 9; Plan-Eintrag veraltet, bewiesen: Lauf 23:00 'Tests 2 failed (6)' = nur Router). Router.test.tsx gefixt: QueryClientProvider + Mocks useCurrentUser/useUserPermissions → **2/2 passed (2.03s)** +3. **ContactEditModal File-Level** — ✅ erledigt (2026-08-28): Geister-Test nach §10 gelöscht. Ursache bewiesen: ContactEditModal.tsx (349 Z.) wurde in db4701b (BUG-080/082) gelöscht, Test blieb → Vitest 'Failed to resolve import' (1 failed, no tests). Ersatz ContactEditForm.tsx lebt und wird von ContactsList/ContactDetailPage genutzt 4. **custom_field_definitions generisch machen** — ENTITY_PLUGIN_OWNERS-Muster wie W4b anwenden (app/routes/custom_field_definitions.py + app/services/entity_permission_service.py) 5. **Sidebar /contacts statische Route entfernen** — routes/index.tsx Zeile 250; erst PluginRouteRenderer beweisen (Kritikpunkt 21: Production-Build + Reload-Test), dann entfernen 6. **Kontakt-Model ins ContactsPlugin** — groß (~30 Import-Stellen, Alembic-Kette), bewusst zurückgestellt diff --git a/frontend/src/__tests__/contacts/ContactEditModal.test.tsx b/frontend/src/__tests__/contacts/ContactEditModal.test.tsx deleted file mode 100644 index d8dac05..0000000 --- a/frontend/src/__tests__/contacts/ContactEditModal.test.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import React from 'react'; -import { describe, it, expect, vi } from 'vitest'; -import { render, screen, fireEvent, waitFor } from '@testing-library/react'; - -// ContactEditModal imports UI components that transitively load lucide-react. -// To avoid OOM in the vitest worker, we test via a stub that validates the -// component's interface contract (props, rendering, callbacks). -vi.mock('@/components/contacts/ContactEditModal', () => ({ - ContactEditModal: ({ open, onClose, contact, onSaved }: any) => { - if (!open) return null; - const isEdit = !!contact; - return ( -
-

{isEdit ? 'Kontakt bearbeiten' : 'Kontakt erstellen'}

- - - - - - -
- ); - }, -})); - -import { ContactEditModal } from '@/components/contacts/ContactEditModal'; - -const defaultProps = { - open: true, - onClose: vi.fn(), - contact: null, - onSaved: vi.fn(), -}; - -describe('ContactEditModal', () => { - it('renders modal when open', () => { - render(); - expect(screen.getByTestId('modal-stub')).toBeInTheDocument(); - }); - - it('does not render when closed', () => { - render(); - expect(screen.queryByTestId('modal-stub')).not.toBeInTheDocument(); - }); - - it('renders type select', () => { - render(); - expect(screen.getByTestId('contact-type-select')).toBeInTheDocument(); - }); - - it('renders name input for company type', () => { - render(); - expect(screen.getByTestId('contact-name-input')).toBeInTheDocument(); - }); - - it('renders submit button', () => { - render(); - expect(screen.getByTestId('contact-submit-btn')).toBeInTheDocument(); - }); - - it('renders cancel button', () => { - render(); - expect(screen.getByText(/abbrechen/i)).toBeInTheDocument(); - }); - - it('calls onClose when cancel button clicked', () => { - render(); - fireEvent.click(screen.getByText(/abbrechen/i)); - expect(defaultProps.onClose).toHaveBeenCalled(); - }); - - it('renders create title for new contact', () => { - render(); - expect(screen.getByText('Kontakt erstellen')).toBeInTheDocument(); - }); - - it('renders edit title when editing existing contact', () => { - render(); - expect(screen.getByText('Kontakt bearbeiten')).toBeInTheDocument(); - }); -}); diff --git a/frontend/src/__tests__/shell/Router.test.tsx b/frontend/src/__tests__/shell/Router.test.tsx index 2c4c491..abf21c5 100644 --- a/frontend/src/__tests__/shell/Router.test.tsx +++ b/frontend/src/__tests__/shell/Router.test.tsx @@ -1,22 +1,41 @@ import React from 'react'; import { describe, it, expect, vi } from 'vitest'; -import { render, screen, act } from '@testing-library/react'; -import { MemoryRouter, Route, Routes, Navigate } from 'react-router-dom'; +import { render, screen } from '@testing-library/react'; +import { MemoryRouter, Route, Routes } from 'react-router-dom'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { ProtectedRoute } from '@/routes/ProtectedRoute'; import { useAuthStore } from '@/store/authStore'; +// Mock API hooks used by useAuth (ProtectedRoute → useAuth → useCurrentUser) +vi.mock('@/api/hooks', () => ({ + useCurrentUser: () => ({ data: null, isLoading: false, isError: false, error: null }), +})); + +// Mock permissions fetch (useAuth → useUserPermissions → apiGet) +vi.mock('@/hooks/useUserPermissions', () => ({ + useUserPermissions: () => ({}), +})); + function ProtectedTest() { + const client = new QueryClient({ + defaultOptions: { + queries: { retry: false, staleTime: 0, gcTime: 0 }, + mutations: { retry: false }, + }, + }); return ( - - - Login} /> - -
Protected
- - } /> -
-
+ + + + Login} /> + +
Protected
+ + } /> +
+
+
); }