/** * CustomFieldRenderer tests — renders custom fields based on field_type. */ import { describe, it, expect, vi } from 'vitest'; import { render, screen, fireEvent } from '@testing-library/react'; import { CustomFieldRenderer } from '@/components/contacts/CustomFieldRenderer'; import type { CustomFieldDefinition } from '@/api/customFields'; // Mock i18n vi.mock('react-i18next', () => ({ useTranslation: () => ({ t: (key: string) => key }), })); // Mock UI components vi.mock('@/components/ui/Input', () => ({ Input: ({ value, onChange, type, id, ...props }: any) => ( ), })); vi.mock('@/components/ui/Select', () => ({ Select: ({ value, onChange, id, options, children, ...props }: any) => ( ), })); const mockFields: CustomFieldDefinition[] = [ { name: 'lead_source', label: 'Lead Source', label_key: 'custom.leadSource', field_type: 'select', options: ['website', 'referral', 'cold_call'], default_value: null, required: false, entity: 'contact', plugin: 'test_plugin', value: 'website', }, { name: 'score', label: 'Score', label_key: 'custom.score', field_type: 'number', options: [], default_value: 0, required: false, entity: 'contact', plugin: 'test_plugin', value: 42, }, { name: 'active', label: 'Active', label_key: 'custom.active', field_type: 'boolean', options: [], default_value: false, required: false, entity: 'contact', plugin: 'test_plugin', value: true, }, ]; describe('CustomFieldRenderer', () => { it('renders read mode with field values', () => { render(); expect(screen.getByTestId('custom-fields-read')).toBeInTheDocument(); expect(screen.getByText('website')).toBeInTheDocument(); expect(screen.getByText('42')).toBeInTheDocument(); expect(screen.getByText('✓')).toBeInTheDocument(); }); it('renders edit mode with form controls', () => { render( ); expect(screen.getByTestId('custom-fields-edit')).toBeInTheDocument(); expect(screen.getByTestId('select-cf-lead_source')).toBeInTheDocument(); expect(screen.getByTestId('input-cf-score')).toBeInTheDocument(); expect(document.getElementById('cf-active')).toBeInTheDocument(); }); it('calls onChange when select value changes', () => { const onChange = vi.fn(); render( ); const select = screen.getByTestId('select-cf-lead_source'); fireEvent.change(select, { target: { value: 'referral' } }); expect(onChange).toHaveBeenCalledWith('lead_source', 'referral'); }); it('renders nothing when fields array is empty', () => { const { container } = render(); expect(container.firstChild).toBeNull(); }); it('renders multiselect field with checkboxes', () => { const multiField: CustomFieldDefinition = { name: 'tags', label: 'Tags', label_key: 'custom.tags', field_type: 'multiselect', options: ['vip', 'customer', 'lead'], default_value: [], required: false, entity: 'contact', plugin: 'test_plugin', value: ['vip'], }; render( ); const checkboxes = screen.getAllByRole('checkbox'); expect(checkboxes).toHaveLength(3); expect(checkboxes[0]).toBeChecked(); }); });