/* eslint-disable import-x/order */ import { fireEvent, render, screen } from '@testing-library/react'; import * as React from 'react'; import { beforeEach, describe, expect, it, vi } from 'vitest'; // Mock lucide-react icons to avoid SVG rendering issues vi.mock('lucide-react', () => ({ ChevronDown: () => , LayoutDashboard: () => , LogOut: () => , Menu: () => , Moon: () => , Shield: () => , Sun: () => , User: () => , X: () => , })); import { Navbar, type NavbarProps } from '../navbar'; const renderLink: NavbarProps['renderLink'] = ({ href, children, className, onClick }) => ( {children} ); const baseLabels: NavbarProps['labels'] = { login: 'Đăng nhập', register: 'Đăng ký', dashboard: 'Quản lý', admin: 'Quản trị', profile: 'Hồ sơ', logout: 'Đăng xuất', openMenu: 'Mở menu', closeMenu: 'Đóng menu', darkMode: 'Chế độ tối', lightMode: 'Chế độ sáng', mainNav: 'Điều hướng chính', }; const baseLinks: NavbarProps['links'] = [ { href: '/', label: 'Trang chủ', isActive: true }, { href: '/search', label: 'Tìm kiếm', isActive: false }, { href: '/pricing', label: 'Bảng giá', isActive: false }, ]; const defaultProps: NavbarProps = { brand: 'GoodGo', links: baseLinks, user: null, dashboardHref: '/dashboard', theme: 'light', onToggleTheme: vi.fn(), onLogout: vi.fn(), labels: baseLabels, renderLink, }; describe('Navbar', () => { beforeEach(() => { vi.clearAllMocks(); }); it('renders the brand name', () => { render(); expect(screen.getByText('GoodGo')).toBeInTheDocument(); }); it('renders as a banner landmark', () => { render(); expect(screen.getByRole('banner')).toBeInTheDocument(); }); it('renders desktop nav links', () => { render(); expect(screen.getAllByText('Trang chủ').length).toBeGreaterThan(0); expect(screen.getAllByText('Tìm kiếm').length).toBeGreaterThan(0); expect(screen.getAllByText('Bảng giá').length).toBeGreaterThan(0); }); it('renders login and register buttons when unauthenticated', () => { render(); expect(screen.getAllByText('Đăng nhập').length).toBeGreaterThan(0); expect(screen.getAllByText('Đăng ký').length).toBeGreaterThan(0); }); it('does not render dashboard button when unauthenticated', () => { render(); expect(screen.queryByText('Quản lý')).toBeNull(); }); it('renders user full name when authenticated', () => { render( , ); expect(screen.getAllByText('Nguyễn Văn A').length).toBeGreaterThan(0); }); it('renders dashboard button for authenticated user', () => { render( , ); expect(screen.getByText('Quản lý')).toBeInTheDocument(); }); it('renders admin label for ADMIN role', () => { render( , ); expect(screen.getByText('Quản trị')).toBeInTheDocument(); }); it('shows moon icon in light theme', () => { render(); expect(screen.getByTestId('icon-moon')).toBeInTheDocument(); }); it('shows sun icon in dark theme', () => { render(); expect(screen.getByTestId('icon-sun')).toBeInTheDocument(); }); it('calls onToggleTheme when theme button is clicked', () => { const onToggleTheme = vi.fn(); render(); const themeBtn = screen.getByRole('button', { name: 'Chế độ tối' }); fireEvent.click(themeBtn); expect(onToggleTheme).toHaveBeenCalledTimes(1); }); it('toggles mobile menu on hamburger click', () => { render(); const hamburger = screen.getByRole('button', { name: 'Mở menu' }); fireEvent.click(hamburger); expect(screen.getByRole('button', { name: 'Đóng menu' })).toBeInTheDocument(); }); it('renders main nav accessible label', () => { render(); const navEls = screen.getAllByRole('navigation'); const mainNavs = navEls.filter((el) => el.getAttribute('aria-label') === 'Điều hướng chính'); expect(mainNavs.length).toBeGreaterThan(0); }); it('renders notification slot when provided', () => { render( 🔔} />, ); expect(screen.getByRole('button', { name: 'Thông báo' })).toBeInTheDocument(); }); it('renders language switcher slot when provided', () => { render( VI} />, ); expect(screen.getByTestId('lang-sw')).toBeInTheDocument(); }); it('calls onLogout and closes mobile menu when logout clicked', async () => { const onLogout = vi.fn().mockResolvedValue(undefined); render( , ); // Open mobile menu fireEvent.click(screen.getByRole('button', { name: 'Mở menu' })); const logoutBtn = screen.getByRole('button', { name: 'Đăng xuất' }); fireEvent.click(logoutBtn); expect(onLogout).toHaveBeenCalledTimes(1); }); });