Update tests and e2e files to support locale-based routing

- Replaced static paths with dynamic locale subpaths (`/[locale]/*`) in imports, URLs, and assertions across tests.
- Updated `next-intl` mocks for improved compatibility with `locale`-aware components.
- Standardized `page.goto` and navigation tests with `/en` as the base locale for consistency.
This commit is contained in:
Felipe Cardoso
2025-11-18 23:26:10 +01:00
parent d1b47006f4
commit da021d0640
42 changed files with 296 additions and 267 deletions

View File

@@ -0,0 +1,29 @@
/**
* Mock for next-intl/navigation
*/
// Create shared mock instances that tests can manipulate
// Note: next-intl's usePathname returns paths WITHOUT locale prefix
export const mockUsePathname = jest.fn(() => '/');
export const mockPush = jest.fn();
export const mockReplace = jest.fn();
export const mockUseRouter = jest.fn(() => ({
push: mockPush,
replace: mockReplace,
prefetch: jest.fn(),
back: jest.fn(),
forward: jest.fn(),
refresh: jest.fn(),
}));
export const mockRedirect = jest.fn();
export const createNavigation = (_routing: any) => ({
Link: ({ children, href, ...props }: any) => (
<a href={href} {...props}>
{children}
</a>
),
redirect: mockRedirect,
usePathname: mockUsePathname,
useRouter: mockUseRouter,
});

View File

@@ -0,0 +1,23 @@
/**
* Mock for next-intl/routing
*/
export const defineRouting = (config: any) => config;
export const createNavigation = (_routing: any) => ({
Link: ({ children, href, ...props }: any) => (
<a href={href} {...props}>
{children}
</a>
),
redirect: jest.fn(),
usePathname: () => '/en/test',
useRouter: () => ({
push: jest.fn(),
replace: jest.fn(),
prefetch: jest.fn(),
back: jest.fn(),
forward: jest.fn(),
refresh: jest.fn(),
}),
});

View File

@@ -4,7 +4,7 @@
*/
import { render, screen } from '@testing-library/react';
import LoginPage from '@/app/(auth)/login/page';
import LoginPage from '@/app/[locale]/(auth)/login/page';
// Mock dynamic import
jest.mock('next/dynamic', () => ({

View File

@@ -4,20 +4,20 @@
*/
import { render, screen, act } from '@testing-library/react';
import { useSearchParams, useRouter } from 'next/navigation';
import PasswordResetConfirmContent from '@/app/(auth)/password-reset/confirm/PasswordResetConfirmContent';
import { useSearchParams } from 'next/navigation';
import { useRouter } from '@/lib/i18n/routing';
import PasswordResetConfirmContent from '@/app/[locale]/(auth)/password-reset/confirm/PasswordResetConfirmContent';
// Mock Next.js navigation
jest.mock('next/navigation', () => ({
useSearchParams: jest.fn(),
useRouter: jest.fn(),
default: jest.fn(),
}));
// Mock Next.js Link
jest.mock('next/link', () => ({
__esModule: true,
default: ({ children, href }: { children: React.ReactNode; href: string }) => (
// Mock i18n routing
jest.mock('@/lib/i18n/routing', () => ({
useRouter: jest.fn(),
Link: ({ children, href }: { children: React.ReactNode; href: string }) => (
<a href={href}>{children}</a>
),
}));

View File

@@ -4,10 +4,10 @@
*/
import { render, screen } from '@testing-library/react';
import PasswordResetConfirmPage from '@/app/(auth)/password-reset/confirm/page';
import PasswordResetConfirmPage from '@/app/[locale]/(auth)/password-reset/confirm/page';
// Mock the content component
jest.mock('@/app/(auth)/password-reset/confirm/PasswordResetConfirmContent', () => ({
jest.mock('@/app/[locale]/(auth)/password-reset/confirm/PasswordResetConfirmContent', () => ({
__esModule: true,
default: () => <div data-testid="password-reset-confirm-content">Content</div>,
}));

View File

@@ -4,7 +4,7 @@
*/
import { render, screen } from '@testing-library/react';
import PasswordResetPage from '@/app/(auth)/password-reset/page';
import PasswordResetPage from '@/app/[locale]/(auth)/password-reset/page';
// Mock dynamic import
jest.mock('next/dynamic', () => ({

View File

@@ -4,7 +4,7 @@
*/
import { render, screen } from '@testing-library/react';
import RegisterPage from '@/app/(auth)/register/page';
import RegisterPage from '@/app/[locale]/(auth)/register/page';
// Mock dynamic import
jest.mock('next/dynamic', () => ({

View File

@@ -4,7 +4,7 @@
*/
import { redirect } from 'next/navigation';
import SettingsPage from '@/app/(authenticated)/settings/page';
import SettingsPage from '@/app/[locale]/(authenticated)/settings/page';
// Mock Next.js navigation - redirect throws to interrupt execution
jest.mock('next/navigation', () => ({
@@ -18,8 +18,9 @@ describe('SettingsPage', () => {
jest.clearAllMocks();
});
it('redirects to /settings/profile', () => {
expect(() => SettingsPage()).toThrow('NEXT_REDIRECT');
expect(redirect).toHaveBeenCalledWith('/settings/profile');
it('redirects to /settings/profile with locale prefix', async () => {
const params = Promise.resolve({ locale: 'en' });
await expect(SettingsPage({ params })).rejects.toThrow('NEXT_REDIRECT');
expect(redirect).toHaveBeenCalledWith('/en/settings/profile');
});
});

View File

@@ -5,7 +5,7 @@
import { render, screen } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import PasswordSettingsPage from '@/app/(authenticated)/settings/password/page';
import PasswordSettingsPage from '@/app/[locale]/(authenticated)/settings/password/page';
describe('PasswordSettingsPage', () => {
const queryClient = new QueryClient({

View File

@@ -4,7 +4,7 @@
*/
import { render, screen } from '@testing-library/react';
import PreferencesPage from '@/app/(authenticated)/settings/preferences/page';
import PreferencesPage from '@/app/[locale]/(authenticated)/settings/preferences/page';
describe('PreferencesPage', () => {
it('renders page title', () => {

View File

@@ -5,7 +5,7 @@
import { render, screen } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import ProfileSettingsPage from '@/app/(authenticated)/settings/profile/page';
import ProfileSettingsPage from '@/app/[locale]/(authenticated)/settings/profile/page';
import { AuthProvider } from '@/lib/auth/AuthContext';
// Mock API hooks

View File

@@ -5,7 +5,7 @@
import { render, screen } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import SessionsPage from '@/app/(authenticated)/settings/sessions/page';
import SessionsPage from '@/app/[locale]/(authenticated)/settings/sessions/page';
// Mock the API client
jest.mock('@/lib/api/client', () => ({

View File

@@ -5,7 +5,7 @@
import { render, screen } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import AdminLayout from '@/app/admin/layout';
import AdminLayout from '@/app/[locale]/admin/layout';
import { useAuth } from '@/lib/auth/AuthContext';
// Mock dependencies

View File

@@ -3,7 +3,7 @@
*/
import { render, screen } from '@testing-library/react';
import OrganizationMembersPage from '@/app/admin/organizations/[id]/members/page';
import OrganizationMembersPage from '@/app/[locale]/admin/organizations/[id]/members/page';
// Mock Next.js Link
jest.mock('next/link', () => ({

View File

@@ -4,7 +4,7 @@
*/
import { render, screen } from '@testing-library/react';
import AdminOrganizationsPage from '@/app/admin/organizations/page';
import AdminOrganizationsPage from '@/app/[locale]/admin/organizations/page';
// Mock the entire OrganizationManagementContent component
jest.mock('@/components/admin/organizations/OrganizationManagementContent', () => ({

View File

@@ -4,7 +4,7 @@
*/
import { render, screen } from '@testing-library/react';
import AdminPage from '@/app/admin/page';
import AdminPage from '@/app/[locale]/admin/page';
import { useAdminStats } from '@/lib/api/hooks/useAdmin';
// Mock the useAdminStats hook

View File

@@ -4,7 +4,7 @@
*/
import { render, screen } from '@testing-library/react';
import AdminSettingsPage from '@/app/admin/settings/page';
import AdminSettingsPage from '@/app/[locale]/admin/settings/page';
describe('AdminSettingsPage', () => {
it('renders page title', () => {

View File

@@ -5,7 +5,7 @@
import { render, screen } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import AdminUsersPage from '@/app/admin/users/page';
import AdminUsersPage from '@/app/[locale]/admin/users/page';
import { useAuth } from '@/lib/auth/AuthContext';
import { useAdminUsers } from '@/lib/api/hooks/useAdmin';

View File

@@ -3,7 +3,7 @@
*/
import { render, screen, within } from '@testing-library/react';
import DemoTourPage from '@/app/demos/page';
import DemoTourPage from '@/app/[locale]/demos/page';
// Mock Next.js Link
jest.mock('next/link', () => ({

View File

@@ -4,7 +4,7 @@
*/
import { render, screen } from '@testing-library/react';
import ForbiddenPage, { metadata } from '@/app/forbidden/page';
import ForbiddenPage, { metadata } from '@/app/[locale]/forbidden/page';
describe('ForbiddenPage', () => {
it('has correct metadata', () => {

View File

@@ -4,7 +4,7 @@
*/
import { render, screen, within, fireEvent } from '@testing-library/react';
import Home from '@/app/page';
import Home from '@/app/[locale]/page';
// Mock Next.js components
jest.mock('next/image', () => ({

View File

@@ -7,7 +7,7 @@ import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { AdminSidebar } from '@/components/admin/AdminSidebar';
import { useAuth } from '@/lib/auth/AuthContext';
import { usePathname } from 'next/navigation';
import { mockUsePathname } from 'next-intl/navigation';
import type { User } from '@/lib/stores/authStore';
// Mock dependencies
@@ -16,10 +16,6 @@ jest.mock('@/lib/auth/AuthContext', () => ({
AuthProvider: ({ children }: { children: React.ReactNode }) => <>{children}</>,
}));
jest.mock('next/navigation', () => ({
usePathname: jest.fn(),
}));
// Helper to create mock user
function createMockUser(overrides: Partial<User> = {}): User {
return {
@@ -39,7 +35,7 @@ function createMockUser(overrides: Partial<User> = {}): User {
describe('AdminSidebar', () => {
beforeEach(() => {
jest.clearAllMocks();
(usePathname as jest.Mock).mockReturnValue('/admin');
mockUsePathname.mockReturnValue('/admin');
(useAuth as unknown as jest.Mock).mockReturnValue({
user: createMockUser(),
});
@@ -97,7 +93,7 @@ describe('AdminSidebar', () => {
describe('Active State Highlighting', () => {
it('highlights dashboard link when on /admin', () => {
(usePathname as jest.Mock).mockReturnValue('/admin');
mockUsePathname.mockReturnValue('/admin');
render(<AdminSidebar />);
@@ -106,7 +102,7 @@ describe('AdminSidebar', () => {
});
it('highlights users link when on /admin/users', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/users');
mockUsePathname.mockReturnValue('/admin/users');
render(<AdminSidebar />);
@@ -115,7 +111,7 @@ describe('AdminSidebar', () => {
});
it('highlights users link when on /admin/users/123', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/users/123');
mockUsePathname.mockReturnValue('/admin/users/123');
render(<AdminSidebar />);
@@ -124,7 +120,7 @@ describe('AdminSidebar', () => {
});
it('highlights organizations link when on /admin/organizations', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/organizations');
mockUsePathname.mockReturnValue('/admin/organizations');
render(<AdminSidebar />);
@@ -133,7 +129,7 @@ describe('AdminSidebar', () => {
});
it('highlights settings link when on /admin/settings', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/settings');
mockUsePathname.mockReturnValue('/admin/settings');
render(<AdminSidebar />);
@@ -142,7 +138,7 @@ describe('AdminSidebar', () => {
});
it('does not highlight dashboard when on other admin routes', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/users');
mockUsePathname.mockReturnValue('/admin/users');
render(<AdminSidebar />);

View File

@@ -5,21 +5,17 @@
import { render, screen } from '@testing-library/react';
import { Breadcrumbs } from '@/components/admin/Breadcrumbs';
import { usePathname } from 'next/navigation';
// Mock dependencies
jest.mock('next/navigation', () => ({
usePathname: jest.fn(),
}));
import { mockUsePathname } from 'next-intl/navigation';
describe('Breadcrumbs', () => {
beforeEach(() => {
jest.clearAllMocks();
mockUsePathname.mockReturnValue('/');
});
describe('Rendering', () => {
it('renders breadcrumbs container with correct test id', () => {
(usePathname as jest.Mock).mockReturnValue('/admin');
mockUsePathname.mockReturnValue('/admin');
render(<Breadcrumbs />);
@@ -27,7 +23,7 @@ describe('Breadcrumbs', () => {
});
it('renders breadcrumbs with proper aria-label', () => {
(usePathname as jest.Mock).mockReturnValue('/admin');
mockUsePathname.mockReturnValue('/admin');
render(<Breadcrumbs />);
@@ -36,7 +32,7 @@ describe('Breadcrumbs', () => {
});
it('returns null for empty pathname', () => {
(usePathname as jest.Mock).mockReturnValue('');
mockUsePathname.mockReturnValue('');
const { container } = render(<Breadcrumbs />);
@@ -44,7 +40,7 @@ describe('Breadcrumbs', () => {
});
it('returns null for root pathname', () => {
(usePathname as jest.Mock).mockReturnValue('/');
mockUsePathname.mockReturnValue('/');
const { container } = render(<Breadcrumbs />);
@@ -54,7 +50,7 @@ describe('Breadcrumbs', () => {
describe('Single Level Navigation', () => {
it('renders single breadcrumb for /admin', () => {
(usePathname as jest.Mock).mockReturnValue('/admin');
mockUsePathname.mockReturnValue('/admin');
render(<Breadcrumbs />);
@@ -63,7 +59,7 @@ describe('Breadcrumbs', () => {
});
it('renders current page without link', () => {
(usePathname as jest.Mock).mockReturnValue('/admin');
mockUsePathname.mockReturnValue('/admin');
render(<Breadcrumbs />);
@@ -75,7 +71,7 @@ describe('Breadcrumbs', () => {
describe('Multi-Level Navigation', () => {
it('renders breadcrumbs for /admin/users', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/users');
mockUsePathname.mockReturnValue('/admin/users');
render(<Breadcrumbs />);
@@ -84,7 +80,7 @@ describe('Breadcrumbs', () => {
});
it('renders parent breadcrumbs as links', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/users');
mockUsePathname.mockReturnValue('/admin/users');
render(<Breadcrumbs />);
@@ -94,7 +90,7 @@ describe('Breadcrumbs', () => {
});
it('renders last breadcrumb as current page', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/users');
mockUsePathname.mockReturnValue('/admin/users');
render(<Breadcrumbs />);
@@ -104,7 +100,7 @@ describe('Breadcrumbs', () => {
});
it('renders breadcrumbs for /admin/organizations', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/organizations');
mockUsePathname.mockReturnValue('/admin/organizations');
render(<Breadcrumbs />);
@@ -113,7 +109,7 @@ describe('Breadcrumbs', () => {
});
it('renders breadcrumbs for /admin/settings', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/settings');
mockUsePathname.mockReturnValue('/admin/settings');
render(<Breadcrumbs />);
@@ -124,7 +120,7 @@ describe('Breadcrumbs', () => {
describe('Three-Level Navigation', () => {
it('renders all levels correctly', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/users/123');
mockUsePathname.mockReturnValue('/admin/users/123');
render(<Breadcrumbs />);
@@ -134,7 +130,7 @@ describe('Breadcrumbs', () => {
});
it('renders all parent links correctly', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/users/123');
mockUsePathname.mockReturnValue('/admin/users/123');
render(<Breadcrumbs />);
@@ -146,7 +142,7 @@ describe('Breadcrumbs', () => {
});
it('renders last level as current page', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/users/123');
mockUsePathname.mockReturnValue('/admin/users/123');
render(<Breadcrumbs />);
@@ -158,7 +154,7 @@ describe('Breadcrumbs', () => {
describe('Separator Icons', () => {
it('renders separator between breadcrumbs', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/users');
mockUsePathname.mockReturnValue('/admin/users');
const { container } = render(<Breadcrumbs />);
@@ -168,7 +164,7 @@ describe('Breadcrumbs', () => {
});
it('does not render separator before first breadcrumb', () => {
(usePathname as jest.Mock).mockReturnValue('/admin');
mockUsePathname.mockReturnValue('/admin');
const { container } = render(<Breadcrumbs />);
@@ -178,7 +174,7 @@ describe('Breadcrumbs', () => {
});
it('renders correct number of separators', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/users/123');
mockUsePathname.mockReturnValue('/admin/users/123');
const { container } = render(<Breadcrumbs />);
@@ -190,7 +186,7 @@ describe('Breadcrumbs', () => {
describe('Label Mapping', () => {
it('uses predefined label for admin', () => {
(usePathname as jest.Mock).mockReturnValue('/admin');
mockUsePathname.mockReturnValue('/admin');
render(<Breadcrumbs />);
@@ -198,7 +194,7 @@ describe('Breadcrumbs', () => {
});
it('uses predefined label for users', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/users');
mockUsePathname.mockReturnValue('/admin/users');
render(<Breadcrumbs />);
@@ -206,7 +202,7 @@ describe('Breadcrumbs', () => {
});
it('uses predefined label for organizations', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/organizations');
mockUsePathname.mockReturnValue('/admin/organizations');
render(<Breadcrumbs />);
@@ -214,7 +210,7 @@ describe('Breadcrumbs', () => {
});
it('uses predefined label for settings', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/settings');
mockUsePathname.mockReturnValue('/admin/settings');
render(<Breadcrumbs />);
@@ -222,7 +218,7 @@ describe('Breadcrumbs', () => {
});
it('uses pathname segment for unmapped paths', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/unknown-path');
mockUsePathname.mockReturnValue('/admin/unknown-path');
render(<Breadcrumbs />);
@@ -230,7 +226,7 @@ describe('Breadcrumbs', () => {
});
it('displays numeric IDs as-is', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/users/123');
mockUsePathname.mockReturnValue('/admin/users/123');
render(<Breadcrumbs />);
@@ -240,7 +236,7 @@ describe('Breadcrumbs', () => {
describe('Styling', () => {
it('applies correct styles to parent links', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/users');
mockUsePathname.mockReturnValue('/admin/users');
render(<Breadcrumbs />);
@@ -250,7 +246,7 @@ describe('Breadcrumbs', () => {
});
it('applies correct styles to current page', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/users');
mockUsePathname.mockReturnValue('/admin/users');
render(<Breadcrumbs />);
@@ -262,7 +258,7 @@ describe('Breadcrumbs', () => {
describe('Accessibility', () => {
it('has proper navigation role', () => {
(usePathname as jest.Mock).mockReturnValue('/admin');
mockUsePathname.mockReturnValue('/admin');
render(<Breadcrumbs />);
@@ -270,7 +266,7 @@ describe('Breadcrumbs', () => {
});
it('has aria-label for navigation', () => {
(usePathname as jest.Mock).mockReturnValue('/admin');
mockUsePathname.mockReturnValue('/admin');
render(<Breadcrumbs />);
@@ -279,7 +275,7 @@ describe('Breadcrumbs', () => {
});
it('marks current page with aria-current', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/users');
mockUsePathname.mockReturnValue('/admin/users');
render(<Breadcrumbs />);
@@ -288,7 +284,7 @@ describe('Breadcrumbs', () => {
});
it('marks separator icons as aria-hidden', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/users');
mockUsePathname.mockReturnValue('/admin/users');
const { container } = render(<Breadcrumbs />);
@@ -299,7 +295,7 @@ describe('Breadcrumbs', () => {
});
it('parent breadcrumbs are keyboard accessible', () => {
(usePathname as jest.Mock).mockReturnValue('/admin/users');
mockUsePathname.mockReturnValue('/admin/users');
render(<Breadcrumbs />);

View File

@@ -5,18 +5,17 @@
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { useRouter, useSearchParams } from 'next/navigation';
import { useSearchParams } from 'next/navigation';
import { OrganizationManagementContent } from '@/components/admin/organizations/OrganizationManagementContent';
import { useAuth } from '@/lib/auth/AuthContext';
import { useAdminOrganizations } from '@/lib/api/hooks/useAdmin';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { mockPush } from 'next-intl/navigation';
// Mock Next.js navigation
const mockPush = jest.fn();
const mockSearchParams = new URLSearchParams();
jest.mock('next/navigation', () => ({
useRouter: jest.fn(),
useSearchParams: jest.fn(),
}));
@@ -52,7 +51,6 @@ jest.mock('@/components/admin/organizations/OrganizationFormDialog', () => ({
) : null,
}));
const mockUseRouter = useRouter as jest.MockedFunction<typeof useRouter>;
const mockUseSearchParams = useSearchParams as jest.MockedFunction<typeof useSearchParams>;
const mockUseAuth = useAuth as jest.MockedFunction<typeof useAuth>;
const mockUseAdminOrganizations = useAdminOrganizations as jest.MockedFunction<
@@ -101,12 +99,6 @@ describe('OrganizationManagementContent', () => {
jest.clearAllMocks();
mockUseRouter.mockReturnValue({
push: mockPush,
replace: jest.fn(),
prefetch: jest.fn(),
} as any);
mockUseSearchParams.mockReturnValue(mockSearchParams as any);
mockUseAuth.mockReturnValue({

View File

@@ -6,17 +6,7 @@
import { render, screen, waitFor, act } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { AuthGuard } from '@/components/auth/AuthGuard';
// Mock Next.js navigation
const mockPush = jest.fn();
const mockPathname = '/protected';
jest.mock('next/navigation', () => ({
useRouter: () => ({
push: mockPush,
}),
usePathname: () => mockPathname,
}));
import { mockUsePathname, mockPush } from 'next-intl/navigation';
// Mock auth state via Context
let mockAuthState: {
@@ -64,6 +54,10 @@ describe('AuthGuard', () => {
beforeEach(() => {
jest.clearAllMocks();
jest.useFakeTimers();
// Configure pathname mock
mockUsePathname.mockReturnValue('/protected');
// Reset to default unauthenticated state
mockAuthState = {
isAuthenticated: false,

View File

@@ -8,7 +8,7 @@ import userEvent from '@testing-library/user-event';
import { Header } from '@/components/layout/Header';
import { useAuth } from '@/lib/auth/AuthContext';
import { useLogout } from '@/lib/api/hooks/useAuth';
import { usePathname } from 'next/navigation';
import { mockUsePathname } from 'next-intl/navigation';
import type { User } from '@/lib/stores/authStore';
// Mock dependencies
@@ -21,10 +21,6 @@ jest.mock('@/lib/api/hooks/useAuth', () => ({
useLogout: jest.fn(),
}));
jest.mock('next/navigation', () => ({
usePathname: jest.fn(),
}));
jest.mock('@/components/theme', () => ({
ThemeToggle: () => <div data-testid="theme-toggle">Theme Toggle</div>,
}));
@@ -51,7 +47,7 @@ describe('Header', () => {
beforeEach(() => {
jest.clearAllMocks();
(usePathname as jest.Mock).mockReturnValue('/');
mockUsePathname.mockReturnValue('/');
(useLogout as jest.Mock).mockReturnValue({
mutate: mockLogout,
@@ -156,7 +152,7 @@ describe('Header', () => {
});
it('highlights active navigation link', () => {
(usePathname as jest.Mock).mockReturnValue('/admin');
mockUsePathname.mockReturnValue('/admin');
(useAuth as unknown as jest.Mock).mockReturnValue({
user: createMockUser({ is_superuser: true }),
});