const request = require('supertest'); const express = require('express'); // Mock dependencies jest.mock('../../../models', () => ({ sequelize: { authenticate: jest.fn(), }, })); jest.mock('../../../services/s3Service', () => ({ isEnabled: jest.fn(), })); jest.mock('../../../utils/logger', () => ({ info: jest.fn(), error: jest.fn(), warn: jest.fn(), })); const { sequelize } = require('../../../models'); const s3Service = require('../../../services/s3Service'); const healthRoutes = require('../../../routes/health'); describe('Health Routes', () => { let app; beforeEach(() => { app = express(); app.use('/health', healthRoutes); jest.clearAllMocks(); }); describe('GET /health', () => { it('should return 200 when all services are healthy', async () => { sequelize.authenticate.mockResolvedValue(); s3Service.isEnabled.mockReturnValue(true); const response = await request(app).get('/health'); expect(response.status).toBe(200); expect(response.body).toEqual({ status: 'healthy' }); }); it('should return 503 when database is unhealthy', async () => { sequelize.authenticate.mockRejectedValue(new Error('Connection refused')); s3Service.isEnabled.mockReturnValue(true); const response = await request(app).get('/health'); expect(response.status).toBe(503); expect(response.body).toEqual({ status: 'unhealthy' }); }); it('should return healthy when S3 is disabled but database is up', async () => { sequelize.authenticate.mockResolvedValue(); s3Service.isEnabled.mockReturnValue(false); const response = await request(app).get('/health'); expect(response.status).toBe(200); expect(response.body).toEqual({ status: 'healthy' }); }); }); describe('GET /health/live', () => { it('should return 200 alive status', async () => { const response = await request(app).get('/health/live'); expect(response.status).toBe(200); expect(response.body.status).toBe('alive'); expect(response.body).toHaveProperty('timestamp'); }); it('should always return 200 regardless of service state', async () => { // Liveness probe should always pass if the process is running sequelize.authenticate.mockRejectedValue(new Error('DB down')); const response = await request(app).get('/health/live'); expect(response.status).toBe(200); expect(response.body.status).toBe('alive'); }); }); describe('GET /health/ready', () => { it('should return 200 when database is ready', async () => { sequelize.authenticate.mockResolvedValue(); const response = await request(app).get('/health/ready'); expect(response.status).toBe(200); expect(response.body.status).toBe('ready'); expect(response.body).toHaveProperty('timestamp'); }); it('should return 503 when database is not ready', async () => { sequelize.authenticate.mockRejectedValue(new Error('Connection timeout')); const response = await request(app).get('/health/ready'); expect(response.status).toBe(503); expect(response.body.status).toBe('not_ready'); expect(response.body.error).toBe('Database connection failed'); }); }); });