import React from 'react';
import { render, screen } from '@testing-library/react';
import { MemoryRouter, Routes, Route } from 'react-router-dom';
import { vi, describe, it, expect, beforeEach } from 'vitest';
import ProtectedRoute from '../ProtectedRoute';
// Mock the useAuth hook to control its output in tests
const mockUseAuth = vi.fn();
vi.mock('../../contexts/AuthContext', () => ({
useAuth: () => mockUseAuth(),
}));
const TestComponent: React.FC = () =>
Protected Content
;
const LoginComponent: React.FC = () => Login Page
;
const UnauthorizedComponent: React.FC = () => Unauthorized Page
;
const renderWithRouter = (ui: React.ReactNode, { initialEntries = ['/protected'] } = {}) => {
return render(
} />
} />
);
};
describe('ProtectedRoute', () => {
beforeEach(() => {
vi.resetAllMocks();
});
it('shows a loading spinner while authentication is in progress', () => {
mockUseAuth.mockReturnValue({
user: null,
isLoading: true,
isInitialized: false,
});
renderWithRouter(
);
expect(document.querySelector('.animate-spin')).toBeInTheDocument();
expect(screen.queryByText('Protected Content')).not.toBeInTheDocument();
});
it('redirects to the login page if the user is not authenticated', () => {
mockUseAuth.mockReturnValue({
user: null,
isLoading: false,
isInitialized: true,
});
renderWithRouter(
);
expect(screen.getByText('Login Page')).toBeInTheDocument();
expect(screen.queryByText('Protected Content')).not.toBeInTheDocument();
});
it('renders the protected content if the user is authenticated', () => {
mockUseAuth.mockReturnValue({
user: { id: '1', role: 'user' },
isLoading: false,
isInitialized: true,
});
renderWithRouter(
);
expect(screen.getByText('Protected Content')).toBeInTheDocument();
});
it('redirects to an unauthorized page if the user does not have the required role', () => {
mockUseAuth.mockReturnValue({
user: { id: '1', role: 'user' },
isLoading: false,
isInitialized: true,
});
renderWithRouter(
);
expect(screen.getByText('Unauthorized Page')).toBeInTheDocument();
expect(screen.queryByText('Protected Content')).not.toBeInTheDocument();
});
it('renders the protected content if the user has the required admin role', () => {
mockUseAuth.mockReturnValue({
user: { id: '1', role: 'admin' },
isLoading: false,
isInitialized: true,
});
renderWithRouter(
);
expect(screen.getByText('Protected Content')).toBeInTheDocument();
});
it('renders the protected content if the user has the required user role', () => {
mockUseAuth.mockReturnValue({
user: { id: '1', role: 'user' },
isLoading: false,
isInitialized: true,
});
renderWithRouter(
);
expect(screen.getByText('Protected Content')).toBeInTheDocument();
});
});