Backend Infrastructure: - Complete Express server setup with security middleware (helmet, CORS, rate limiting) - Comprehensive error handling and logging with Winston - Authentication system with JWT tokens and session management - Database models and migrations for Users, Documents, Feedback, and Processing Jobs - API routes structure for authentication and document management - Integration tests for all server components (86 tests passing) Frontend Infrastructure: - React application with TypeScript and Vite - Authentication UI with login form, protected routes, and logout functionality - Authentication context with proper async state management - Component tests with proper async handling (25 tests passing) - Tailwind CSS styling and responsive design Key Features: - User registration, login, and authentication - Protected routes with role-based access control - Comprehensive error handling and user feedback - Database schema with proper relationships - Security middleware and validation - Production-ready build configuration Test Coverage: 111/111 tests passing Tasks Completed: 1-5 (Project setup, Database, Auth system, Frontend UI, Backend infrastructure) Ready for Task 6: File upload backend infrastructure
92 lines
3.3 KiB
TypeScript
92 lines
3.3 KiB
TypeScript
import request from 'supertest';
|
|
import app from '../index';
|
|
|
|
describe('Server Setup', () => {
|
|
describe('Health Check', () => {
|
|
it('should return 200 for health check endpoint', async () => {
|
|
const response = await request(app).get('/health');
|
|
|
|
expect(response.status).toBe(200);
|
|
expect(response.body).toHaveProperty('status', 'ok');
|
|
expect(response.body).toHaveProperty('timestamp');
|
|
expect(response.body).toHaveProperty('uptime');
|
|
expect(response.body).toHaveProperty('environment');
|
|
});
|
|
});
|
|
|
|
describe('API Root', () => {
|
|
it('should return API information', async () => {
|
|
const response = await request(app).get('/api');
|
|
|
|
expect(response.status).toBe(200);
|
|
expect(response.body).toHaveProperty('message', 'CIM Document Processor API');
|
|
expect(response.body).toHaveProperty('version', '1.0.0');
|
|
expect(response.body).toHaveProperty('endpoints');
|
|
expect(response.body.endpoints).toHaveProperty('auth');
|
|
expect(response.body.endpoints).toHaveProperty('documents');
|
|
expect(response.body.endpoints).toHaveProperty('health');
|
|
});
|
|
});
|
|
|
|
describe('Authentication Routes', () => {
|
|
it('should have auth routes mounted', async () => {
|
|
const response = await request(app).post('/api/auth/login');
|
|
|
|
// Should not return 404 (route exists)
|
|
expect(response.status).not.toBe(404);
|
|
});
|
|
});
|
|
|
|
describe('Document Routes', () => {
|
|
it('should have document routes mounted', async () => {
|
|
const response = await request(app).get('/api/documents');
|
|
|
|
// Should return 401 (unauthorized) rather than 404 (not found)
|
|
// This indicates the route exists but requires authentication
|
|
expect(response.status).toBe(401);
|
|
});
|
|
});
|
|
|
|
describe('404 Handler', () => {
|
|
it('should return 404 for non-existent routes', async () => {
|
|
const response = await request(app).get('/api/nonexistent');
|
|
|
|
expect(response.status).toBe(404);
|
|
expect(response.body).toHaveProperty('success', false);
|
|
expect(response.body).toHaveProperty('error');
|
|
expect(response.body).toHaveProperty('message');
|
|
});
|
|
});
|
|
|
|
describe('CORS', () => {
|
|
it('should include CORS headers', async () => {
|
|
const response = await request(app)
|
|
.options('/api')
|
|
.set('Origin', 'http://localhost:3000');
|
|
|
|
expect(response.headers).toHaveProperty('access-control-allow-origin');
|
|
expect(response.headers).toHaveProperty('access-control-allow-methods');
|
|
expect(response.headers).toHaveProperty('access-control-allow-headers');
|
|
});
|
|
});
|
|
|
|
describe('Security Headers', () => {
|
|
it('should include security headers', async () => {
|
|
const response = await request(app).get('/health');
|
|
|
|
expect(response.headers).toHaveProperty('x-frame-options');
|
|
expect(response.headers).toHaveProperty('x-content-type-options');
|
|
expect(response.headers).toHaveProperty('x-xss-protection');
|
|
});
|
|
});
|
|
|
|
describe('Rate Limiting', () => {
|
|
it('should include rate limit headers', async () => {
|
|
const response = await request(app).get('/health');
|
|
|
|
expect(response.headers).toHaveProperty('ratelimit-limit');
|
|
expect(response.headers).toHaveProperty('ratelimit-remaining');
|
|
expect(response.headers).toHaveProperty('ratelimit-reset');
|
|
});
|
|
});
|
|
});
|