diff --git a/frontend/src/__tests__/mail/ComposeModal.test.tsx b/frontend/src/__tests__/mail/ComposeModal.test.tsx index 6d7232b..0522c32 100644 --- a/frontend/src/__tests__/mail/ComposeModal.test.tsx +++ b/frontend/src/__tests__/mail/ComposeModal.test.tsx @@ -4,6 +4,7 @@ import { render, screen, fireEvent, waitFor } from '@testing-library/react'; import { MemoryRouter } from 'react-router-dom'; vi.mock('@/api/mail', () => ({ + decodeMimeHeader: (s: string) => s, fetchTemplates: vi.fn().mockResolvedValue([ { id: 't1', name: 'Welcome', subject: 'Welcome!', body: '
Welcome {{name}}
', variables: ['name'] }, ]), @@ -57,7 +58,7 @@ describe('ComposeModal', () => { it('renders editor', () => { renderModal(); - expect(screen.getByTestId('compose-editor')).toBeInTheDocument(); + expect(screen.getByTestId('rich-text-editor-container')).toBeInTheDocument(); }); it('renders send button', () => { diff --git a/frontend/src/__tests__/mail/MailPage.test.tsx b/frontend/src/__tests__/mail/MailPage.test.tsx index 3a22d3d..91736a2 100644 --- a/frontend/src/__tests__/mail/MailPage.test.tsx +++ b/frontend/src/__tests__/mail/MailPage.test.tsx @@ -4,6 +4,7 @@ import { render, screen, fireEvent, waitFor } from '@testing-library/react'; import { MemoryRouter } from 'react-router-dom'; vi.mock('@/api/mail', () => ({ + decodeMimeHeader: (s: string) => s, fetchAccounts: vi.fn().mockResolvedValue([ { id: 'acc1', email: 'test@example.com', display_name: 'Test User', is_shared: false, is_active: true, imap_host: '', imap_port: 993, smtp_host: '', smtp_port: 587 }, ]), @@ -100,8 +101,8 @@ describe('MailPage', () => { it('renders folders after loading', async () => { renderWithRouter(); await waitFor(() => { - expect(screen.getByText('INBOX')).toBeInTheDocument(); - expect(screen.getByText('Sent')).toBeInTheDocument(); + expect(screen.getAllByText('INBOX').length).toBeGreaterThan(0); + expect(screen.getAllByText('Sent').length).toBeGreaterThan(0); }); }); @@ -145,7 +146,7 @@ describe('MailPage', () => { }); fireEvent.click(screen.getByText('Test Subject')); await waitFor(() => { - expect(screen.getByTestId('mail-detail')).toBeInTheDocument(); + expect(screen.getAllByTestId('mail-detail').length).toBeGreaterThan(0); }); }); @@ -156,7 +157,7 @@ describe('MailPage', () => { }); fireEvent.click(screen.getByText('Test Subject')); await waitFor(() => { - expect(screen.getByTestId('mail-detail-toolbar')).toBeInTheDocument(); + expect(screen.getAllByTestId('mail-detail-toolbar').length).toBeGreaterThan(0); }); }); }); diff --git a/frontend/src/__tests__/settings/SettingsRoles.test.tsx b/frontend/src/__tests__/settings/SettingsRoles.test.tsx index 26f4ead..5489beb 100644 --- a/frontend/src/__tests__/settings/SettingsRoles.test.tsx +++ b/frontend/src/__tests__/settings/SettingsRoles.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { describe, it, expect, vi } from 'vitest'; -import { render, screen, fireEvent } from '@testing-library/react'; +import { render, screen, fireEvent, waitFor } from '@testing-library/react'; import { MemoryRouter } from 'react-router-dom'; import { SettingsRolesPage } from '@/pages/SettingsRoles'; @@ -8,6 +8,66 @@ vi.mock('@/components/ui/Toast', () => ({ useToast: () => ({ success: vi.fn(), error: vi.fn(), info: vi.fn() }), })); +const { mockRoles, forceUpdateRef } = vi.hoisted(() => { + const forceUpdateRef: { current: () => void } = { current: () => {} }; + const mockRoles = [ + { id: '1', name: 'Administrator', permissions: { all: true }, denied_permissions: [], field_permissions: {} }, + { id: '2', name: 'Mitarbeiter', permissions: { 'companies.read': true, 'contacts.read': true }, denied_permissions: [], field_permissions: {} }, + { id: '3', name: 'Gast', permissions: {}, denied_permissions: [], field_permissions: {} }, + ]; + return { mockRoles, forceUpdateRef }; +}); + +vi.mock('@/api/hooks', () => ({ + useRoles: () => { + const [, setUpdate] = React.useState({}); + forceUpdateRef.current = () => setUpdate({}); + return { + data: { + items: mockRoles.map(r => ({ ...r })), + total: mockRoles.length, + }, + isLoading: false, + isError: false, + error: null, + refetch: () => forceUpdateRef.current(), + }; + }, + useCreateRole: () => ({ + mutateAsync: async (data: any) => { + const newRole = { id: String(mockRoles.length + 1), name: data.name, permissions: data.permissions || {}, denied_permissions: data.denied_permissions || [], field_permissions: data.field_permissions || {} }; + mockRoles.push(newRole); + forceUpdateRef.current(); + return newRole; + }, + isPending: false, + }), + useUpdateRole: () => ({ + mutateAsync: async (payload: any) => { + const idx = mockRoles.findIndex(r => r.id === payload.id); + if (idx >= 0) { + mockRoles[idx] = { ...mockRoles[idx], ...payload.data }; + } + forceUpdateRef.current(); + return undefined; + }, + isPending: false, + }), + useDeleteRole: () => ({ mutateAsync: vi.fn().mockResolvedValue(undefined), isPending: false }), + usePermissions: () => ({ + data: { + all: [ + { key: 'companies.read', label: 'Firmen lesen', category: 'system' }, + { key: 'companies.write', label: 'Firmen schreiben', category: 'system' }, + { key: 'contacts.read', label: 'Kontakte lesen', category: 'system' }, + { key: 'contacts.write', label: 'Kontakte schreiben', category: 'system' }, + ], + field_definitions: [], + }, + isLoading: false, + }), +})); + describe('SettingsRolesPage', () => { it('renders roles page', () => { render(