Phase 6.6: Mail-Settings-Forms on RHF + Zod
- MailSettings account form: RHF+Zod (email valid, password required, imap/smtp host required, ports numeric) - SignatureManager: RHF+Zod (name required, body_html, is_default) - RuleEditor: RHF+Zod (name required, priority numeric) - LabelManager: RHF+Zod (name required, color optional) - VacationResponder: RHF+Zod (enabled, dates with end>start validation, subject, body) - Error display under each field - Preserved all existing functionality: CRUD, templates, variables - Added 2 validation tests for MailSettings account form
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
import React from 'react';
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
|
||||
vi.mock('@/api/mail', () => ({
|
||||
fetchAccounts: vi.fn().mockResolvedValue([]),
|
||||
createAccount: vi.fn().mockResolvedValue({ id: 'a1', email: 'test@example.com', display_name: '', imap_host: '', imap_port: 993, smtp_host: '', smtp_port: 587, is_shared: false, is_active: true }),
|
||||
deleteAccount: vi.fn(),
|
||||
testConnection: vi.fn(),
|
||||
triggerSync: vi.fn(),
|
||||
updateAccount: vi.fn(),
|
||||
fetchFolders: vi.fn().mockResolvedValue([]),
|
||||
}));
|
||||
|
||||
vi.mock('@/components/ui/Toast', () => ({
|
||||
useToast: () => ({ success: vi.fn(), error: vi.fn(), info: vi.fn(), warning: vi.fn() }),
|
||||
}));
|
||||
|
||||
vi.mock('@/components/mail/SignatureManager', () => ({ SignatureManager: () => null }));
|
||||
vi.mock('@/components/mail/RuleEditor', () => ({ RuleEditor: () => null }));
|
||||
vi.mock('@/components/mail/LabelManager', () => ({ LabelManager: () => null }));
|
||||
vi.mock('@/components/mail/VacationResponder', () => ({ VacationResponder: () => null }));
|
||||
vi.mock('@/components/mail/PgpSettings', () => ({ PgpSettings: () => null }));
|
||||
|
||||
import { MailSettingsPage } from '@/pages/MailSettings';
|
||||
import { createAccount } from '@/api/mail';
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('MailSettings account form validation (RHF + Zod)', () => {
|
||||
it('shows validation error when email is empty', async () => {
|
||||
render(<MemoryRouter><MailSettingsPage /></MemoryRouter>);
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('mail-settings-page')).toBeInTheDocument();
|
||||
}, { timeout: 3000 });
|
||||
// Click add account button
|
||||
const addBtn = screen.getByTestId('add-account-btn');
|
||||
fireEvent.click(addBtn);
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('add-account-form')).toBeInTheDocument();
|
||||
});
|
||||
// Submit empty form
|
||||
const form = screen.getByTestId('add-account-form').querySelector('form');
|
||||
expect(form).toBeTruthy();
|
||||
fireEvent.submit(form!);
|
||||
await waitFor(() => {
|
||||
const errors = screen.getAllByText(/erforderlich|required/i);
|
||||
expect(errors.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
it('calls createAccount when form is valid', async () => {
|
||||
render(<MemoryRouter><MailSettingsPage /></MemoryRouter>);
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('mail-settings-page')).toBeInTheDocument();
|
||||
}, { timeout: 3000 });
|
||||
const addBtn = screen.getByTestId('add-account-btn');
|
||||
fireEvent.click(addBtn);
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('add-account-form')).toBeInTheDocument();
|
||||
});
|
||||
const form = screen.getByTestId('add-account-form').querySelector('form');
|
||||
const inputs = form!.querySelectorAll('input');
|
||||
// Fill email, imap_host, smtp_host, password
|
||||
fireEvent.change(inputs[0], { target: { value: 'test@example.com' } }); // email
|
||||
fireEvent.change(inputs[3], { target: { value: 'imap.example.com' } }); // imap_host
|
||||
fireEvent.change(inputs[5], { target: { value: 'smtp.example.com' } }); // smtp_host
|
||||
fireEvent.change(inputs[7], { target: { value: 'password123' } }); // password
|
||||
fireEvent.submit(form!);
|
||||
await waitFor(() => {
|
||||
expect(createAccount).toHaveBeenCalledWith(expect.objectContaining({ email: 'test@example.com', imap_host: 'imap.example.com', smtp_host: 'smtp.example.com' }));
|
||||
}, { timeout: 3000 });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user