Files
hive/frontend/src/contexts/__tests__/AuthContext.test.tsx
anthonyrawlins aacb45156b Set up comprehensive frontend testing infrastructure
- Install Jest for unit testing with React Testing Library
- Install Playwright for end-to-end testing
- Configure Jest with proper TypeScript support and module mapping
- Create test setup files and utilities for both unit and e2e tests

Components:
* Jest configuration with coverage thresholds
* Playwright configuration with browser automation
* Unit tests for LoginForm, AuthContext, and useSocketIO hook
* E2E tests for authentication, dashboard, and agents workflows
* GitHub Actions workflow for automated testing
* Mock data and API utilities for consistent testing
* Test documentation with best practices

Testing features:
- Unit tests with 70% coverage threshold
- E2E tests with API mocking and user journey testing
- CI/CD integration for automated test runs
- Cross-browser testing support with Playwright
- Authentication system testing end-to-end

🚀 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-11 14:06:34 +10:00

178 lines
5.7 KiB
TypeScript

import { renderHook, act } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { AuthProvider, useAuth } from '../AuthContext';
import * as authApi from '../../api/auth';
import { mockApiResponses, mockUser } from '../../test/utils';
// Mock the auth API
jest.mock('../../api/auth');
const mockAuthApi = authApi as jest.Mocked<typeof authApi>;
// Mock localStorage
const mockLocalStorage = {
getItem: jest.fn(),
setItem: jest.fn(),
removeItem: jest.fn(),
clear: jest.fn(),
};
Object.defineProperty(window, 'localStorage', {
value: mockLocalStorage,
});
const createWrapper = () => {
const queryClient = new QueryClient({
defaultOptions: {
queries: { retry: false, gcTime: 0 },
mutations: { retry: false },
},
});
return ({ children }: { children: React.ReactNode }) => (
<QueryClientProvider client={queryClient}>
<AuthProvider>{children}</AuthProvider>
</QueryClientProvider>
);
};
describe('AuthContext', () => {
beforeEach(() => {
jest.clearAllMocks();
mockLocalStorage.getItem.mockReturnValue(null);
});
it('initializes with no user when no token in localStorage', () => {
const { result } = renderHook(() => useAuth(), { wrapper: createWrapper() });
expect(result.current.user).toBeNull();
expect(result.current.isAuthenticated).toBe(false);
expect(result.current.isLoading).toBe(false);
});
it('attempts to load user when token exists in localStorage', async () => {
mockLocalStorage.getItem.mockReturnValue('mock-token');
mockAuthApi.getCurrentUser.mockResolvedValue(mockUser);
const { result } = renderHook(() => useAuth(), { wrapper: createWrapper() });
// Initially loading
expect(result.current.isLoading).toBe(true);
// Wait for the async operation to complete
await act(async () => {
await new Promise(resolve => setTimeout(resolve, 0));
});
expect(result.current.user).toEqual(mockUser);
expect(result.current.isAuthenticated).toBe(true);
expect(result.current.isLoading).toBe(false);
});
it('clears user data when token is invalid', async () => {
mockLocalStorage.getItem.mockReturnValue('invalid-token');
mockAuthApi.getCurrentUser.mockRejectedValue(new Error('Unauthorized'));
const { result } = renderHook(() => useAuth(), { wrapper: createWrapper() });
await act(async () => {
await new Promise(resolve => setTimeout(resolve, 0));
});
expect(result.current.user).toBeNull();
expect(result.current.isAuthenticated).toBe(false);
expect(mockLocalStorage.removeItem).toHaveBeenCalledWith('token');
});
it('logs in user successfully', async () => {
mockAuthApi.login.mockResolvedValue(mockApiResponses.auth.login);
const { result } = renderHook(() => useAuth(), { wrapper: createWrapper() });
await act(async () => {
await result.current.login('test@example.com', 'password123');
});
expect(mockAuthApi.login).toHaveBeenCalledWith({
email: 'test@example.com',
password: 'password123',
});
expect(mockLocalStorage.setItem).toHaveBeenCalledWith('token', 'mock-jwt-token');
expect(result.current.user).toEqual(mockUser);
expect(result.current.isAuthenticated).toBe(true);
});
it('throws error on login failure', async () => {
const loginError = new Error('Invalid credentials');
mockAuthApi.login.mockRejectedValue(loginError);
const { result } = renderHook(() => useAuth(), { wrapper: createWrapper() });
await expect(act(async () => {
await result.current.login('test@example.com', 'wrongpassword');
})).rejects.toThrow('Invalid credentials');
expect(result.current.user).toBeNull();
expect(result.current.isAuthenticated).toBe(false);
});
it('logs out user successfully', async () => {
// First set up an authenticated user
mockLocalStorage.getItem.mockReturnValue('mock-token');
mockAuthApi.getCurrentUser.mockResolvedValue(mockUser);
const { result } = renderHook(() => useAuth(), { wrapper: createWrapper() });
await act(async () => {
await new Promise(resolve => setTimeout(resolve, 0));
});
// Now logout
await act(async () => {
result.current.logout();
});
expect(mockLocalStorage.removeItem).toHaveBeenCalledWith('token');
expect(result.current.user).toBeNull();
expect(result.current.isAuthenticated).toBe(false);
});
it('updates user data', async () => {
// First set up an authenticated user
mockLocalStorage.getItem.mockReturnValue('mock-token');
mockAuthApi.getCurrentUser.mockResolvedValue(mockUser);
const { result } = renderHook(() => useAuth(), { wrapper: createWrapper() });
await act(async () => {
await new Promise(resolve => setTimeout(resolve, 0));
});
const updatedUser = { ...mockUser, full_name: 'Updated Name' };
act(() => {
result.current.updateUser(updatedUser);
});
expect(result.current.user).toEqual(updatedUser);
});
it('handles register functionality', async () => {
const registerData = {
email: 'newuser@example.com',
password: 'password123',
full_name: 'New User',
username: 'newuser',
};
mockAuthApi.register.mockResolvedValue(mockApiResponses.auth.login);
const { result } = renderHook(() => useAuth(), { wrapper: createWrapper() });
await act(async () => {
await result.current.register(registerData);
});
expect(mockAuthApi.register).toHaveBeenCalledWith(registerData);
expect(result.current.user).toEqual(mockUser);
expect(result.current.isAuthenticated).toBe(true);
});
});