import { describe, it, expect, vi } from 'vitest'; import { render, screen } from '@testing-library/react'; const { mockUsePathname } = vi.hoisted(() => ({ mockUsePathname: vi.fn(), })); const { mockUseApi } = vi.hoisted(() => ({ mockUseApi: vi.fn(), })); vi.mock('next/navigation', () => ({ usePathname: mockUsePathname, })); vi.mock('next/link', () => ({ // eslint-disable-next-line @typescript-eslint/no-explicit-any default: (props: any) => {props.children}, })); vi.mock('@/lib/useApi', () => ({ useApi: mockUseApi })); import { Sidebar } from '../layout/Sidebar'; describe('Sidebar', () => { beforeEach(() => { vi.clearAllMocks(); mockUsePathname.mockReturnValue('/dashboard'); mockUseApi.mockReturnValue({ profile: { displayName: 'Alice' } }); }); it('renders brand name', () => { render(); expect(screen.getByText('MeshiTrack')).toBeInTheDocument(); }); it('renders navigation sections', () => { render(); expect(screen.getByText('Dashboard')).toBeInTheDocument(); expect(screen.getByText('Medicines')).toBeInTheDocument(); expect(screen.getByText('Food')).toBeInTheDocument(); expect(screen.getByText('Settings')).toBeInTheDocument(); }); it('renders medicines nav items', () => { render(); expect(screen.getByText('Cabinet')).toBeInTheDocument(); expect(screen.getByText('Schedule & Log')).toBeInTheDocument(); expect(screen.getByText('Regimens')).toBeInTheDocument(); expect(screen.getByText('Library')).toBeInTheDocument(); }); it('renders food nav items', () => { render(); expect(screen.getByText('Recipes')).toBeInTheDocument(); expect(screen.getByText('Pantry')).toBeInTheDocument(); }); it('highlights active route', () => { mockUsePathname.mockReturnValue('/medicines/cabinet'); render(); const cabinetLink = screen.getByText('Cabinet').closest('a'); expect(cabinetLink).toHaveAttribute('href', '/medicines/cabinet'); }); it('shows user avatar with display name', () => { render(); expect(screen.getByLabelText('Alice')).toBeInTheDocument(); }); it('shows fallback name when no profile', () => { mockUseApi.mockReturnValue({ profile: null }); render(); expect(screen.getByLabelText('User')).toBeInTheDocument(); }); it('highlights nested route', () => { mockUsePathname.mockReturnValue('/medicines/cabinet/some-id'); render(); // Cabinet link should still match via startsWith const cabinetLink = screen.getByText('Cabinet').closest('a'); expect(cabinetLink).toBeInTheDocument(); }); });