import { render, screen, fireEvent } from '@testing-library/react'; import { describe, it, expect, vi } from 'vitest'; import { ContactDetail } from '../contact-detail'; import type { ContactCard } from '@/lib/jmap/types'; const contact: ContactCard = { id: '1', addressBookIds: {}, name: { components: [{ kind: 'given', value: 'Alice' }, { kind: 'surname', value: 'Smith' }], isOrdered: true }, emails: { e0: { address: 'alice@example.com' } }, phones: { p0: { number: '+33612345678' } }, organizations: { o0: { name: 'Acme Corp' } }, addresses: { a0: { street: '123 Main St', locality: 'Paris', country: 'France' } }, notes: { n0: { note: 'VIP customer' } }, }; describe('ContactDetail', () => { it('shows empty state when contact is null', () => { render(); expect(screen.getByText('detail.no_contact_selected')).toBeInTheDocument(); }); it('displays the contact name', () => { render(); expect(screen.getByText('Alice Smith')).toBeInTheDocument(); }); it('displays email addresses as mailto links', () => { render(); const link = screen.getByText('alice@example.com'); expect(link.closest('a')).toHaveAttribute('href', 'mailto:alice@example.com'); }); it('displays phone numbers', () => { render(); expect(screen.getByText('+33612345678')).toBeInTheDocument(); }); it('displays organization name', () => { render(); const matches = screen.getAllByText('Acme Corp'); expect(matches.length).toBeGreaterThanOrEqual(1); }); it('calls onEdit when edit button is clicked', () => { const onEdit = vi.fn(); render(); fireEvent.click(screen.getByText('form.edit_title')); expect(onEdit).toHaveBeenCalledOnce(); }); it('calls onDelete when delete button is clicked', () => { const onDelete = vi.fn(); render(); const trashButtons = screen.getAllByRole('button').filter( btn => btn.querySelector('svg') && btn.textContent?.trim() === '' ); fireEvent.click(trashButtons[trashButtons.length - 1]); expect(onDelete).toHaveBeenCalledOnce(); }); });