fix(frontend): remove locale-dependent routing and migrate to centralized locale-aware router
- Replaced `next/navigation` with `@/lib/i18n/routing` across components, pages, and tests. - Removed redundant `locale` props from `ProjectWizard` and related pages. - Updated navigation to exclude explicit `locale` in paths. - Refactored tests to use mocks from `next-intl/navigation`.
This commit is contained in:
@@ -77,13 +77,8 @@ jest.mock('@/components/projects/wizard/useWizardState', () => ({
|
||||
})),
|
||||
}));
|
||||
|
||||
// Mock router
|
||||
const mockPush = jest.fn();
|
||||
jest.mock('next/navigation', () => ({
|
||||
useRouter: () => ({
|
||||
push: mockPush,
|
||||
}),
|
||||
}));
|
||||
// Import mock from next-intl/navigation mock (used by @/lib/i18n/routing)
|
||||
import { mockPush } from 'next-intl/navigation';
|
||||
|
||||
// Mock API client
|
||||
const mockPost = jest.fn();
|
||||
@@ -131,36 +126,36 @@ describe('ProjectWizard', () => {
|
||||
|
||||
describe('Rendering', () => {
|
||||
it('renders the step indicator', () => {
|
||||
render(<ProjectWizard locale="en" />, { wrapper: createWrapper() });
|
||||
render(<ProjectWizard />, { wrapper: createWrapper() });
|
||||
expect(screen.getByTestId('step-indicator')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders BasicInfoStep on step 1', () => {
|
||||
mockWizardState.step = 1;
|
||||
render(<ProjectWizard locale="en" />, { wrapper: createWrapper() });
|
||||
render(<ProjectWizard />, { wrapper: createWrapper() });
|
||||
expect(screen.getByTestId('basic-info-step')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders ComplexityStep on step 2', () => {
|
||||
mockWizardState.step = 2;
|
||||
render(<ProjectWizard locale="en" />, { wrapper: createWrapper() });
|
||||
render(<ProjectWizard />, { wrapper: createWrapper() });
|
||||
expect(screen.getByTestId('complexity-step')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders AgentChatStep on step 5', () => {
|
||||
mockWizardState.step = 5;
|
||||
render(<ProjectWizard locale="en" />, { wrapper: createWrapper() });
|
||||
render(<ProjectWizard />, { wrapper: createWrapper() });
|
||||
expect(screen.getByTestId('agent-chat-step')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders ReviewStep on step 6', () => {
|
||||
mockWizardState.step = 6;
|
||||
render(<ProjectWizard locale="en" />, { wrapper: createWrapper() });
|
||||
render(<ProjectWizard />, { wrapper: createWrapper() });
|
||||
expect(screen.getByTestId('review-step')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('applies custom className', () => {
|
||||
const { container } = render(<ProjectWizard locale="en" className="custom-class" />, {
|
||||
const { container } = render(<ProjectWizard className="custom-class" />, {
|
||||
wrapper: createWrapper(),
|
||||
});
|
||||
expect(container.firstChild).toHaveClass('custom-class');
|
||||
@@ -171,7 +166,7 @@ describe('ProjectWizard', () => {
|
||||
it('calls goNext when Next button is clicked', async () => {
|
||||
const user = userEvent.setup();
|
||||
mockWizardState.step = 1;
|
||||
render(<ProjectWizard locale="en" />, { wrapper: createWrapper() });
|
||||
render(<ProjectWizard />, { wrapper: createWrapper() });
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /next/i }));
|
||||
expect(mockGoNext).toHaveBeenCalled();
|
||||
@@ -180,7 +175,7 @@ describe('ProjectWizard', () => {
|
||||
it('calls goBack when Back button is clicked', async () => {
|
||||
const user = userEvent.setup();
|
||||
mockWizardState.step = 2;
|
||||
render(<ProjectWizard locale="en" />, { wrapper: createWrapper() });
|
||||
render(<ProjectWizard />, { wrapper: createWrapper() });
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /back/i }));
|
||||
expect(mockGoBack).toHaveBeenCalled();
|
||||
@@ -188,21 +183,21 @@ describe('ProjectWizard', () => {
|
||||
|
||||
it('hides Back button on step 1', () => {
|
||||
mockWizardState.step = 1;
|
||||
render(<ProjectWizard locale="en" />, { wrapper: createWrapper() });
|
||||
render(<ProjectWizard />, { wrapper: createWrapper() });
|
||||
const backButton = screen.getByRole('button', { name: /back/i });
|
||||
expect(backButton).toHaveClass('invisible');
|
||||
});
|
||||
|
||||
it('shows Back button visible on step 2', () => {
|
||||
mockWizardState.step = 2;
|
||||
render(<ProjectWizard locale="en" />, { wrapper: createWrapper() });
|
||||
render(<ProjectWizard />, { wrapper: createWrapper() });
|
||||
const backButton = screen.getByRole('button', { name: /back/i });
|
||||
expect(backButton).not.toHaveClass('invisible');
|
||||
});
|
||||
|
||||
it('shows Create Project button on review step', () => {
|
||||
mockWizardState.step = 6;
|
||||
render(<ProjectWizard locale="en" />, { wrapper: createWrapper() });
|
||||
render(<ProjectWizard />, { wrapper: createWrapper() });
|
||||
expect(screen.getByRole('button', { name: /create project/i })).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -211,7 +206,7 @@ describe('ProjectWizard', () => {
|
||||
it('skips client mode step in script mode', () => {
|
||||
mockWizardState.step = 3;
|
||||
mockWizardState.complexity = 'script';
|
||||
render(<ProjectWizard locale="en" />, { wrapper: createWrapper() });
|
||||
render(<ProjectWizard />, { wrapper: createWrapper() });
|
||||
// ClientModeStep should not render for script mode
|
||||
expect(screen.queryByTestId('client-mode-step')).not.toBeInTheDocument();
|
||||
});
|
||||
@@ -219,14 +214,14 @@ describe('ProjectWizard', () => {
|
||||
it('skips autonomy step in script mode', () => {
|
||||
mockWizardState.step = 4;
|
||||
mockWizardState.complexity = 'script';
|
||||
render(<ProjectWizard locale="en" />, { wrapper: createWrapper() });
|
||||
render(<ProjectWizard />, { wrapper: createWrapper() });
|
||||
// AutonomyStep should not render for script mode
|
||||
expect(screen.queryByTestId('autonomy-step')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows script mode indicator', () => {
|
||||
mockWizardState.complexity = 'script';
|
||||
render(<ProjectWizard locale="en" />, { wrapper: createWrapper() });
|
||||
render(<ProjectWizard />, { wrapper: createWrapper() });
|
||||
expect(screen.getByText(/script mode/i)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -235,7 +230,7 @@ describe('ProjectWizard', () => {
|
||||
it('shows success screen after creation', async () => {
|
||||
const user = userEvent.setup();
|
||||
mockWizardState.step = 6;
|
||||
render(<ProjectWizard locale="en" />, { wrapper: createWrapper() });
|
||||
render(<ProjectWizard />, { wrapper: createWrapper() });
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /create project/i }));
|
||||
|
||||
@@ -247,7 +242,7 @@ describe('ProjectWizard', () => {
|
||||
it('displays project name in success message', async () => {
|
||||
const user = userEvent.setup();
|
||||
mockWizardState.step = 6;
|
||||
render(<ProjectWizard locale="en" />, { wrapper: createWrapper() });
|
||||
render(<ProjectWizard />, { wrapper: createWrapper() });
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /create project/i }));
|
||||
|
||||
@@ -259,7 +254,7 @@ describe('ProjectWizard', () => {
|
||||
it('navigates to project dashboard on success', async () => {
|
||||
const user = userEvent.setup();
|
||||
mockWizardState.step = 6;
|
||||
render(<ProjectWizard locale="en" />, { wrapper: createWrapper() });
|
||||
render(<ProjectWizard />, { wrapper: createWrapper() });
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /create project/i }));
|
||||
|
||||
@@ -270,13 +265,14 @@ describe('ProjectWizard', () => {
|
||||
});
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /go to project dashboard/i }));
|
||||
expect(mockPush).toHaveBeenCalledWith('/en/projects/test-project');
|
||||
// Locale-aware router adds locale prefix automatically
|
||||
expect(mockPush).toHaveBeenCalledWith('/projects/test-project');
|
||||
});
|
||||
|
||||
it('allows creating another project', async () => {
|
||||
const user = userEvent.setup();
|
||||
mockWizardState.step = 6;
|
||||
render(<ProjectWizard locale="en" />, { wrapper: createWrapper() });
|
||||
render(<ProjectWizard />, { wrapper: createWrapper() });
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /create project/i }));
|
||||
|
||||
@@ -294,7 +290,7 @@ describe('ProjectWizard', () => {
|
||||
mockPost.mockRejectedValue(new Error('Network error'));
|
||||
const user = userEvent.setup();
|
||||
mockWizardState.step = 6;
|
||||
render(<ProjectWizard locale="en" />, { wrapper: createWrapper() });
|
||||
render(<ProjectWizard />, { wrapper: createWrapper() });
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /create project/i }));
|
||||
|
||||
@@ -307,13 +303,13 @@ describe('ProjectWizard', () => {
|
||||
describe('Button States', () => {
|
||||
it('disables Next button when cannot proceed', () => {
|
||||
mockWizardState.projectName = '';
|
||||
render(<ProjectWizard locale="en" />, { wrapper: createWrapper() });
|
||||
render(<ProjectWizard />, { wrapper: createWrapper() });
|
||||
expect(screen.getByRole('button', { name: /next/i })).toBeDisabled();
|
||||
});
|
||||
|
||||
it('enables Next button when can proceed', () => {
|
||||
mockWizardState.projectName = 'Valid Name';
|
||||
render(<ProjectWizard locale="en" />, { wrapper: createWrapper() });
|
||||
render(<ProjectWizard />, { wrapper: createWrapper() });
|
||||
expect(screen.getByRole('button', { name: /next/i })).not.toBeDisabled();
|
||||
});
|
||||
|
||||
@@ -323,7 +319,7 @@ describe('ProjectWizard', () => {
|
||||
);
|
||||
const user = userEvent.setup();
|
||||
mockWizardState.step = 6;
|
||||
render(<ProjectWizard locale="en" />, { wrapper: createWrapper() });
|
||||
render(<ProjectWizard />, { wrapper: createWrapper() });
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /create project/i }));
|
||||
expect(screen.getByText(/creating/i)).toBeInTheDocument();
|
||||
|
||||
Reference in New Issue
Block a user