forked from cardosofelipe/fast-next-template
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:
@@ -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 />);
|
||||
|
||||
|
||||
@@ -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 />);
|
||||
|
||||
|
||||
@@ -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({
|
||||
|
||||
Reference in New Issue
Block a user