import { fireEvent, render, screen } from '@testing-library/react'; import { describe, expect, it } from 'vitest'; import type { ValuationComparable } from '@/lib/valuation-api'; import { ComparablesTable } from '../comparables-table'; const comparables: ValuationComparable[] = [ { id: 'c1', title: 'Căn hộ Vinhomes', address: '123 Nguyễn Huệ', district: 'Quận 1', priceVND: '5000000000', areaM2: 75, pricePerM2: 66_666_666, similarity: 0.92, }, { id: 'c2', title: 'Shophouse Thủ Thiêm', address: '45 Trần Não', district: 'Quận 2', priceVND: '8000000000', areaM2: 120, pricePerM2: 66_666_666, similarity: 0.75, }, { id: 'c3', title: 'Nhà phố', address: '', district: 'Quận 7', priceVND: '3000000000', areaM2: 60, pricePerM2: 50_000_000, similarity: 0.62, }, ]; describe('ComparablesTable', () => { it('renders header with count and row per comparable', () => { render(); expect(screen.getByText('Bất động sản tương tự')).toBeInTheDocument(); expect( screen.getByText(/3 bất động sản có đặc điểm tương tự/), ).toBeInTheDocument(); expect(screen.getByText('Căn hộ Vinhomes')).toBeInTheDocument(); expect(screen.getByText('Shophouse Thủ Thiêm')).toBeInTheDocument(); expect(screen.getByText('Nhà phố')).toBeInTheDocument(); }); it('shows similarity badges with correct variants', () => { render(); expect(screen.getByText('92% tương tự')).toBeInTheDocument(); expect(screen.getByText('75% tương tự')).toBeInTheDocument(); expect(screen.getByText('62% tương tự')).toBeInTheDocument(); }); it('renders address with em-dash separator when present', () => { render(); expect( screen.getByText(/Quận 1\s*—\s*123 Nguyễn Huệ/), ).toBeInTheDocument(); }); it('omits address dash when address empty', () => { render(); const text = screen.getByText(/Quận 7/).textContent ?? ''; expect(text).not.toContain('—'); }); it('returns null when comparables list is empty', () => { const { container } = render(); expect(container.firstChild).toBeNull(); }); it('toggles sort when a column header is clicked', () => { render(); const areaBtn = screen.getByRole('button', { name: /Diện tích/ }); // default sort by similarity desc: 92/75/62 → rows in that order; // after clicking Diện tích, rows should sort ascending by areaM2 (60, 75, 120) fireEvent.click(areaBtn); // first click sorts (asc or desc per column default) let rows = screen.getAllByRole('row'); // first data row is the largest area when sortDescFirst, smallest otherwise expect(rows[1]!.textContent).toMatch(/(60|120) m²/); fireEvent.click(areaBtn); // toggle to opposite direction rows = screen.getAllByRole('row'); expect(rows[1]!.textContent).toMatch(/(60|120) m²/); }); });