Implemented responsive layout system with: - Header: Top navigation with profile menu and mobile hamburger - Sidebar: Desktop-only navigation sidebar (lg and above) - Breadcrumbs: Auto-generated navigation breadcrumbs - Layout: Main wrapper component with configurable options Features: - Responsive design (mobile, tablet, desktop) - Active route highlighting - User profile integration via auth store - Click-outside dropdown closing - Comprehensive test coverage (49 tests passing) Updated (main) layout to use new Layout component system. Updated dashboard page to work with new layout structure. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
108 lines
3.5 KiB
TypeScript
108 lines
3.5 KiB
TypeScript
import { render, screen } from '@testing-library/react';
|
|
import { Breadcrumbs } from '../Breadcrumbs';
|
|
import { usePathname } from 'next/navigation';
|
|
|
|
// Mock Next.js navigation
|
|
jest.mock('next/navigation', () => ({
|
|
usePathname: jest.fn(),
|
|
}));
|
|
|
|
describe('Breadcrumbs Component', () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
it('does not render on login page', () => {
|
|
(usePathname as jest.Mock).mockReturnValue('/login');
|
|
const { container } = render(<Breadcrumbs />);
|
|
expect(container.firstChild).toBeNull();
|
|
});
|
|
|
|
it('does not render on verify-otp page', () => {
|
|
(usePathname as jest.Mock).mockReturnValue('/verify-otp');
|
|
const { container } = render(<Breadcrumbs />);
|
|
expect(container.firstChild).toBeNull();
|
|
});
|
|
|
|
it('renders home icon link', () => {
|
|
(usePathname as jest.Mock).mockReturnValue('/dashboard');
|
|
render(<Breadcrumbs />);
|
|
|
|
const homeLink = screen.getByLabelText('Home');
|
|
expect(homeLink).toHaveAttribute('href', '/dashboard');
|
|
});
|
|
|
|
it('renders single breadcrumb for dashboard', () => {
|
|
(usePathname as jest.Mock).mockReturnValue('/dashboard');
|
|
render(<Breadcrumbs />);
|
|
|
|
expect(screen.getByText('Dashboard')).toBeInTheDocument();
|
|
expect(screen.getByText('Dashboard')).toHaveAttribute('aria-current', 'page');
|
|
});
|
|
|
|
it('renders breadcrumbs for nested route', () => {
|
|
(usePathname as jest.Mock).mockReturnValue('/beneficiaries/123');
|
|
render(<Breadcrumbs />);
|
|
|
|
expect(screen.getByText('Loved Ones')).toBeInTheDocument();
|
|
expect(screen.getByText('#123')).toBeInTheDocument();
|
|
});
|
|
|
|
it('renders breadcrumbs for deep nested route', () => {
|
|
(usePathname as jest.Mock).mockReturnValue('/beneficiaries/123/sensors');
|
|
render(<Breadcrumbs />);
|
|
|
|
expect(screen.getByText('Loved Ones')).toBeInTheDocument();
|
|
expect(screen.getByText('#123')).toBeInTheDocument();
|
|
expect(screen.getByText('Sensors')).toBeInTheDocument();
|
|
});
|
|
|
|
it('renders proper mapped labels', () => {
|
|
(usePathname as jest.Mock).mockReturnValue('/beneficiaries/123/subscription');
|
|
render(<Breadcrumbs />);
|
|
|
|
expect(screen.getByText('Loved Ones')).toBeInTheDocument();
|
|
expect(screen.getByText('Subscription')).toBeInTheDocument();
|
|
});
|
|
|
|
it('capitalizes unknown segments', () => {
|
|
(usePathname as jest.Mock).mockReturnValue('/unknown-route');
|
|
render(<Breadcrumbs />);
|
|
|
|
expect(screen.getByText('Unknown-route')).toBeInTheDocument();
|
|
});
|
|
|
|
it('marks last item as current page', () => {
|
|
(usePathname as jest.Mock).mockReturnValue('/beneficiaries/123/sensors');
|
|
render(<Breadcrumbs />);
|
|
|
|
const currentPage = screen.getByText('Sensors');
|
|
expect(currentPage).toHaveAttribute('aria-current', 'page');
|
|
});
|
|
|
|
it('makes intermediate items clickable', () => {
|
|
(usePathname as jest.Mock).mockReturnValue('/beneficiaries/123/sensors');
|
|
render(<Breadcrumbs />);
|
|
|
|
const lovedOnesLink = screen.getByText('Loved Ones').closest('a');
|
|
expect(lovedOnesLink).toHaveAttribute('href', '/beneficiaries');
|
|
|
|
const idLink = screen.getByText('#123').closest('a');
|
|
expect(idLink).toHaveAttribute('href', '/beneficiaries/123');
|
|
});
|
|
|
|
it('handles settings route', () => {
|
|
(usePathname as jest.Mock).mockReturnValue('/settings');
|
|
render(<Breadcrumbs />);
|
|
|
|
expect(screen.getByText('Settings')).toBeInTheDocument();
|
|
});
|
|
|
|
it('handles profile route', () => {
|
|
(usePathname as jest.Mock).mockReturnValue('/profile');
|
|
render(<Breadcrumbs />);
|
|
|
|
expect(screen.getByText('Profile')).toBeInTheDocument();
|
|
});
|
|
});
|