Some checks failed
API Docs (Node.js Express) / test (16) (push) Failing after 5m42s
API Docs (Node.js Express) / test (20) (push) Has been cancelled
API Docs (Node.js Express) / build (push) Has been cancelled
API Docs (Node.js Express) / security (push) Has been cancelled
API Docs (Node.js Express) / test (18) (push) Has been cancelled
LabFusion CI/CD Pipeline / api-gateway (push) Has been cancelled
LabFusion CI/CD Pipeline / service-adapters (push) Has been cancelled
LabFusion CI/CD Pipeline / api-docs (push) Has been cancelled
LabFusion CI/CD Pipeline / frontend (push) Has been cancelled
LabFusion CI/CD Pipeline / integration-tests (push) Has been cancelled
LabFusion CI/CD Pipeline / security-scan (push) Has been cancelled
Docker Build and Push / build-and-push (push) Has been cancelled
Docker Build and Push / security-scan (push) Has been cancelled
Docker Build and Push / deploy-staging (push) Has been cancelled
Docker Build and Push / deploy-production (push) Has been cancelled
Frontend (React) / test (16) (push) Has been cancelled
Frontend (React) / test (18) (push) Has been cancelled
Frontend (React) / test (20) (push) Has been cancelled
Frontend (React) / build (push) Has been cancelled
Frontend (React) / lighthouse (push) Has been cancelled
Frontend (React) / security (push) Has been cancelled
Integration Tests / performance-tests (push) Has been cancelled
Service Adapters (Python FastAPI) / security (push) Has been cancelled
Service Adapters (Python FastAPI) / test (3.1) (push) Has been cancelled
Service Adapters (Python FastAPI) / test (3.11) (push) Has been cancelled
Service Adapters (Python FastAPI) / test (3.12) (push) Has been cancelled
Service Adapters (Python FastAPI) / test (3.9) (push) Has been cancelled
Service Adapters (Python FastAPI) / build (push) Has been cancelled
Integration Tests / integration-tests (push) Has been cancelled
173 lines
5.4 KiB
JavaScript
173 lines
5.4 KiB
JavaScript
const request = require('supertest')
|
|
const app = require('../server')
|
|
|
|
// Mock axios to avoid actual HTTP requests during tests
|
|
jest.mock('axios')
|
|
const axios = require('axios')
|
|
|
|
describe('API Docs Service', () => {
|
|
let server
|
|
|
|
beforeAll(() => {
|
|
// Start the server for testing
|
|
server = app.listen(0) // Use random available port
|
|
})
|
|
|
|
afterAll((done) => {
|
|
// Close the server after tests
|
|
server.close(done)
|
|
})
|
|
|
|
describe('GET /health', () => {
|
|
it('should return health status', async () => {
|
|
const response = await request(app)
|
|
.get('/health')
|
|
.expect(200)
|
|
|
|
expect(response.body).toHaveProperty('status', 'healthy')
|
|
expect(response.body).toHaveProperty('timestamp')
|
|
expect(new Date(response.body.timestamp)).toBeInstanceOf(Date)
|
|
})
|
|
})
|
|
|
|
describe('GET /services', () => {
|
|
beforeEach(() => {
|
|
// Reset axios mocks
|
|
jest.clearAllMocks()
|
|
})
|
|
|
|
it('should return service status for all services', async () => {
|
|
// Mock successful health checks for active services
|
|
axios.get.mockImplementation((url) => {
|
|
if (url.includes('/health')) {
|
|
return Promise.resolve({
|
|
headers: { 'x-response-time': '50ms' }
|
|
})
|
|
}
|
|
return Promise.reject(new Error('Not found'))
|
|
})
|
|
|
|
const response = await request(app)
|
|
.get('/services')
|
|
.expect(200)
|
|
|
|
expect(response.body).toHaveProperty('api-gateway')
|
|
expect(response.body).toHaveProperty('service-adapters')
|
|
expect(response.body).toHaveProperty('metrics-collector')
|
|
expect(response.body).toHaveProperty('notification-service')
|
|
|
|
// Check structure of service status
|
|
Object.values(response.body).forEach(service => {
|
|
expect(service).toHaveProperty('name')
|
|
expect(service).toHaveProperty('url')
|
|
expect(service).toHaveProperty('status')
|
|
})
|
|
})
|
|
|
|
it('should handle service health check failures', async () => {
|
|
// Mock all health checks to fail
|
|
axios.get.mockRejectedValue(new Error('Connection refused'))
|
|
|
|
const response = await request(app)
|
|
.get('/services')
|
|
.expect(200)
|
|
|
|
// All services should show as unhealthy or planned
|
|
Object.values(response.body).forEach(service => {
|
|
expect(['unhealthy', 'planned']).toContain(service.status)
|
|
if (service.status === 'unhealthy') {
|
|
expect(service).toHaveProperty('error')
|
|
}
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('GET /openapi.json', () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks()
|
|
})
|
|
|
|
it('should return unified OpenAPI specification', async () => {
|
|
// Mock service spec responses
|
|
axios.get.mockImplementation((url) => {
|
|
if (url.includes('/v3/api-docs')) {
|
|
return Promise.resolve({
|
|
data: {
|
|
openapi: '3.0.0',
|
|
info: { title: 'API Gateway', version: '1.0.0' },
|
|
paths: { '/test': { get: { summary: 'Test endpoint' } } },
|
|
components: { schemas: {} }
|
|
}
|
|
})
|
|
}
|
|
if (url.includes('/openapi.json')) {
|
|
return Promise.resolve({
|
|
data: {
|
|
openapi: '3.0.0',
|
|
info: { title: 'Service Adapters', version: '1.0.0' },
|
|
paths: { '/health': { get: { summary: 'Health check' } } },
|
|
components: { schemas: {} }
|
|
}
|
|
})
|
|
}
|
|
return Promise.reject(new Error('Not found'))
|
|
})
|
|
|
|
const response = await request(app)
|
|
.get('/openapi.json')
|
|
.expect(200)
|
|
|
|
expect(response.body).toHaveProperty('openapi', '3.0.0')
|
|
expect(response.body).toHaveProperty('info')
|
|
expect(response.body).toHaveProperty('paths')
|
|
expect(response.body).toHaveProperty('components')
|
|
expect(response.body).toHaveProperty('tags')
|
|
|
|
// Check that paths are prefixed with service names
|
|
expect(response.body.paths).toHaveProperty('/api-gateway/test')
|
|
expect(response.body.paths).toHaveProperty('/service-adapters/health')
|
|
})
|
|
|
|
it('should handle service spec fetch failures gracefully', async () => {
|
|
// Mock all service spec requests to fail
|
|
axios.get.mockRejectedValue(new Error('Service unavailable'))
|
|
|
|
const response = await request(app)
|
|
.get('/openapi.json')
|
|
.expect(200)
|
|
|
|
expect(response.body).toHaveProperty('openapi', '3.0.0')
|
|
expect(response.body).toHaveProperty('info')
|
|
expect(response.body).toHaveProperty('paths')
|
|
expect(response.body).toHaveProperty('components')
|
|
expect(response.body).toHaveProperty('tags')
|
|
|
|
// Should still have tags for all services
|
|
expect(response.body.tags).toHaveLength(4)
|
|
})
|
|
})
|
|
|
|
describe('GET /api-docs.json', () => {
|
|
it('should return API docs service specification', async () => {
|
|
const response = await request(app)
|
|
.get('/api-docs.json')
|
|
.expect(200)
|
|
|
|
expect(response.body).toHaveProperty('openapi', '3.0.0')
|
|
expect(response.body).toHaveProperty('info')
|
|
expect(response.body.info).toHaveProperty('title', 'LabFusion API Docs Service')
|
|
})
|
|
})
|
|
|
|
describe('GET /', () => {
|
|
it('should serve Swagger UI', async () => {
|
|
const response = await request(app)
|
|
.get('/')
|
|
.expect(200)
|
|
|
|
expect(response.text).toContain('swagger-ui')
|
|
expect(response.text).toContain('LabFusion API Documentation')
|
|
})
|
|
})
|
|
})
|