import { render, screen } from '@testing-library/react'; import { describe, expect, it, vi } from 'vitest'; import type { AgentPublicProfile, AgentReviewItem } from '@/lib/agents-api'; import type { ListingDetail } from '@/lib/listings-api'; import { AgentProfileClient } from '../agent-profile-client'; // Mock next/image vi.mock('next/image', () => ({ default: (props: Record) => , })); // Mock lucide-react vi.mock('lucide-react', () => ({ BadgeCheck: () => , Building2: () => B, Calendar: () => C, MapPin: () => M, Phone: () => P, Mail: () => E, Star: ({ className }: { className?: string }) => ( ), Home: () => H, MessageSquare: () => M, TrendingUp: () => TU, Award: () => AW, BarChart2: () => BC, })); // Mock recharts (avoid canvas/SVG issues in test env) vi.mock('recharts', () => ({ LineChart: ({ children }: { children: React.ReactNode }) =>
{children}
, Line: () => null, XAxis: () => null, YAxis: () => null, CartesianGrid: () => null, Tooltip: () => null, ResponsiveContainer: ({ children }: { children: React.ReactNode }) =>
{children}
, })); // Mock design-system components that require browser APIs vi.mock('@/components/design-system', () => ({ KpiCard: ({ label, value }: { label: string; value: React.ReactNode }) => (
{label} {value}
), DataTable: () =>
, EmptyState: ({ title }: { title: string }) =>
{title}
, StatusChip: ({ status }: { status: string }) => {status}, })); // Mock i18n/navigation vi.mock('@/i18n/navigation', () => ({ Link: ({ children, href }: { children: React.ReactNode; href: string }) => ( {children} ), })); // Mock image-blur vi.mock('@/lib/image-blur', () => ({ shimmerBlurDataURL: () => 'data:image/svg+xml;base64,mock', })); // Mock inquiry modal vi.mock('@/components/listings/inquiry-modal', () => ({ InquiryModal: () => null, })); function makeAgent(overrides: Partial = {}): AgentPublicProfile { return { id: 'agent-1', fullName: 'Nguyễn Văn A', avatarUrl: null, phone: '0912345678', email: 'nguyen@example.com', agency: 'Công ty BĐS ABC', licenseNumber: 'GPHN-2025-001', bio: 'Chuyên viên tư vấn bất động sản khu vực Quận 7', qualityScore: 85, totalDeals: 45, isVerified: true, serviceAreas: ['Quận 7', 'Quận 2', 'Nhà Bè'], memberSince: '2023-06-15T00:00:00Z', activeListings: [], avgReviewRating: 4.5, totalReviews: 20, ...overrides, }; } function makeReview(overrides: Partial = {}): AgentReviewItem { return { id: 'review-1', userId: 'user-1', userName: 'Trần Thị B', targetType: 'agent', targetId: 'agent-1', rating: 5, comment: 'Tư vấn rất nhiệt tình', createdAt: '2026-01-20T10:00:00Z', ...overrides, }; } const defaultProps = { listings: [] as ListingDetail[], listingsTotal: 0 }; describe('AgentProfileClient', () => { it('renders agent name', () => { render(); expect(screen.getByRole('heading', { level: 1 })).toHaveTextContent('Nguyễn Văn A'); }); it('renders verified badge when verified', () => { render(); expect(screen.getByText('KYC xác minh')).toBeInTheDocument(); }); it('does not render verified badge when not verified', () => { render(); expect(screen.queryByText('KYC xác minh')).not.toBeInTheDocument(); }); it('renders agency name', () => { render(); expect(screen.getByText('Công ty BĐS ABC')).toBeInTheDocument(); }); it('renders license number', () => { render(); expect(screen.getByText(/GPHN-2025-001/)).toBeInTheDocument(); }); it('renders bio', () => { render(); expect(screen.getByText(/Chuyên viên tư vấn bất động sản/)).toBeInTheDocument(); }); it('renders service areas', () => { render(); expect(screen.getByText('Quận 7')).toBeInTheDocument(); expect(screen.getByText('Quận 2')).toBeInTheDocument(); expect(screen.getByText('Nhà Bè')).toBeInTheDocument(); }); it('renders quality score', () => { render(); expect(screen.getAllByText('85').length).toBeGreaterThan(0); expect(screen.getAllByText('Xuất sắc').length).toBeGreaterThan(0); }); it('renders "Tốt" for quality score 60-79', () => { render(); expect(screen.getByText('Tốt')).toBeInTheDocument(); }); it('renders contact card', () => { render(); expect(screen.getAllByText('Liên hệ môi giới').length).toBeGreaterThan(0); expect(screen.getAllByText('Gọi ngay').length).toBeGreaterThan(0); }); it('renders phone number', () => { render(); expect(screen.getAllByText('0912345678').length).toBeGreaterThan(0); }); it('renders email when present', () => { render(); expect(screen.getAllByText('nguyen@example.com').length).toBeGreaterThan(0); }); it('renders reviews section', () => { const reviews = [makeReview()]; render(); expect(screen.getByText('Tư vấn rất nhiệt tình')).toBeInTheDocument(); expect(screen.getByText('Trần Thị B')).toBeInTheDocument(); }); it('shows empty state when no reviews', () => { render(); expect(screen.getByText('Chưa có đánh giá')).toBeInTheDocument(); }); it('renders breadcrumb navigation', () => { render(); expect(screen.getByText('Trang chủ')).toBeInTheDocument(); }); it('renders avatar placeholder when no avatarUrl', () => { render(); expect(screen.getByText('N')).toBeInTheDocument(); // First letter of Nguyễn }); it('renders deal count KPI', () => { render(); expect(screen.getByText('Đã giao dịch')).toBeInTheDocument(); expect(screen.getAllByText('45').length).toBeGreaterThan(0); }); });