news-complete.test.ts•4.24 kB
/**
* Complete news API tests with axios mocking to prevent real API calls
*/
import { describe, test, expect, beforeEach, jest, beforeAll, afterAll } from '@jest/globals';
import request from 'supertest';
import { Express } from 'express';
// Import the axios mock first to ensure it's applied before any imports that use axios
import '../mocks/axios.mock';
import { McpServer } from '../../server';
import { cacheService } from '../../utils/cache';
describe('News API Integration Tests', () => {
let app: Express;
let server: McpServer;
// Set up before all tests
beforeAll(async () => {
// Mock environment for testing
process.env.NODE_ENV = 'test';
// Mock database connection
jest.mock('../../utils/db', () => ({
connectDb: jest.fn().mockResolvedValue(undefined),
disconnectDb: jest.fn().mockResolvedValue(undefined),
prisma: {
article: {
findMany: jest.fn().mockResolvedValue([]),
findUnique: jest.fn().mockResolvedValue(null),
count: jest.fn().mockResolvedValue(0)
}
}
}));
// Create server without actually starting it
server = new McpServer();
app = server.getApp();
});
// Clean up after tests
afterAll(async () => {
jest.resetAllMocks();
});
// Reset cache and mocks before each test
beforeEach(() => {
cacheService.clear();
jest.clearAllMocks();
});
// Test: Get top news
test('GET /api/news/top should return top news articles', async () => {
const response = await request(app)
.get('/api/news/top')
.expect('Content-Type', /json/)
.expect(200);
expect(response.body.success).toBe(true);
expect(Array.isArray(response.body.data)).toBe(true);
if (response.body.data.length > 0) {
const article = response.body.data[0];
expect(article).toHaveProperty('title');
expect(article).toHaveProperty('uuid');
}
});
// Test: Get top news with category filter
test('GET /api/news/top with category filter should work', async () => {
const response = await request(app)
.get('/api/news/top?categories=technology')
.expect('Content-Type', /json/)
.expect(200);
expect(response.body.success).toBe(true);
expect(Array.isArray(response.body.data)).toBe(true);
});
// Test: Get news with pagination
test('GET /api/news/all should support pagination', async () => {
const response = await request(app)
.get('/api/news/all?page=1&limit=10')
.expect('Content-Type', /json/)
.expect(200);
expect(response.body.success).toBe(true);
expect(Array.isArray(response.body.data)).toBe(true);
expect(response.body.meta).toBeDefined();
expect(response.body.meta).toHaveProperty('page');
expect(response.body.meta).toHaveProperty('limit');
});
// Test: Get article by UUID
test('GET /api/news/uuid/:uuid should return a specific article', async () => {
const response = await request(app)
.get('/api/news/uuid/test-uuid-1')
.expect('Content-Type', /json/)
.expect(200);
expect(response.body.success).toBe(true);
expect(response.body.data).toHaveProperty('uuid');
expect(response.body.data.uuid).toBe('test-uuid-1');
});
// Test: 404 for non-existent article
test('GET /api/news/uuid/:uuid should return 404 for non-existent article', async () => {
const response = await request(app)
.get('/api/news/uuid/non-existent-uuid')
.expect('Content-Type', /json/)
.expect(404);
expect(response.body.success).toBe(false);
expect(response.body.error).toBeDefined();
});
// Test: Cache functionality
test('API should use cache for repeated requests', async () => {
// Clear cache stats
const initialStats = cacheService.getStats();
// First request - should miss cache
await request(app)
.get('/api/news/top')
.expect(200);
// Second request - should hit cache
await request(app)
.get('/api/news/top')
.expect(200);
// Check cache stats
const finalStats = cacheService.getStats();
expect(finalStats.hits).toBeGreaterThan(initialStats.hits);
});
});