Skip to main content
Glama

News Aggregator API

api-integration.test.ts6.12 kB
/** * Integration Tests for News API * * These tests verify the complete request-response cycle * while mocking external API calls to ensure reliable tests. */ import { describe, test, expect, beforeAll, afterAll, beforeEach, jest } from '@jest/globals'; import supertest from 'supertest'; import { app, server } from '../../server'; import axios from 'axios'; // Mock axios to prevent real external API calls jest.mock('axios'); const mockedAxios = axios as jest.Mocked<typeof axios>; // Sample test data const mockArticles = [ { uuid: '123e4567-e89b-12d3-a456-426614174000', // Using a properly formatted UUID title: 'Test Article 1', description: 'Test description 1', content: 'Test content 1', url: 'https://example.com/test1', image_url: 'https://example.com/test1.jpg', source: 'Test Source', categories: ['technology'], published_at: '2023-01-01T12:00:00Z', created_at: '2023-01-01T12:00:00Z', updated_at: '2023-01-01T12:00:00Z' }, { uuid: '223e4567-e89b-12d3-a456-426614174001', // Using another properly formatted UUID title: 'Test Article 2', description: 'Test description 2', content: 'Test content 2', url: 'https://example.com/test2', image_url: 'https://example.com/test2.jpg', source: 'Test Source', categories: ['business'], published_at: '2023-01-02T12:00:00Z', created_at: '2023-01-02T12:00:00Z', updated_at: '2023-01-02T12:00:00Z' } ]; describe('API Integration Tests', () => { // Using any type to avoid TypeScript errors with supertest let request: any; let port: number; beforeAll(() => { // Use a random port to avoid conflicts port = Math.floor(Math.random() * 10000) + 10000; server.listen(port); request = supertest(app); }); afterAll(async () => { return new Promise<void>((resolve) => { // Properly close the server server.close(() => { resolve(); }); }); }); beforeEach(() => { // Reset mocks jest.clearAllMocks(); }); describe('GET /api/news/top', () => { test('returns top news articles', async () => { // Arrange - mock axios response mockedAxios.get.mockResolvedValueOnce({ data: { data: mockArticles, meta: { found: 2, returned: 2 } } }); // Act const response = await request.get('/api/news/top'); // Assert expect(response.status).toBe(200); expect(response.body.success).toBe(true); expect(response.body.data.data).toHaveLength(2); expect(response.body.data.data[0].uuid).toBe('123e4567-e89b-12d3-a456-426614174000'); expect(response.body.data.meta.found).toBe(2); }); test('filters by category', async () => { // Arrange - mock axios response mockedAxios.get.mockResolvedValueOnce({ data: { data: [mockArticles[0]], // Only the tech article meta: { found: 1, returned: 1 } } }); // Act const response = await request.get('/api/news/top?categories=technology'); // Assert expect(response.status).toBe(200); expect(response.body.success).toBe(true); expect(response.body.data.data).toHaveLength(1); expect(response.body.data.data[0].categories).toContain('technology'); // Verify that axios was called with the right parameters expect(mockedAxios.get).toHaveBeenCalledWith( expect.any(String), expect.objectContaining({ params: expect.objectContaining({ categories: 'technology' }) }) ); }); }); describe('GET /api/news/uuid/:uuid', () => { test('returns a specific news article by UUID', async () => { // Arrange mockedAxios.get.mockResolvedValueOnce({ data: { data: mockArticles[0] } }); // Act const response = await request.get('/api/news/uuid/123e4567-e89b-12d3-a456-426614174000'); // Assert expect(response.status).toBe(200); expect(response.body.success).toBe(true); expect(response.body.data.data.uuid).toBe('123e4567-e89b-12d3-a456-426614174000'); expect(response.body.data.data.title).toBe('Test Article 1'); }); test('returns 404 when article is not found', async () => { // Arrange - mock a 404 error response from the API // Using a properly formatted UUID that doesn't exist const nonExistentUuid = '00000000-0000-0000-0000-000000000000'; // Create an error with a response property to simulate Axios error structure // Note: The controller checks for the string "404" in the error message to set status code to 404 const errorResponse = new Error('Article not found - 404'); (errorResponse as any).response = { status: 404, statusText: 'Not Found', data: { message: 'Article not found' } }; // Mock axios to return this error for this specific UUID mockedAxios.get.mockImplementationOnce((url, config) => { if (url.includes(nonExistentUuid)) { return Promise.reject(errorResponse); } return Promise.resolve({ data: {} } as any); // Should never reach this }); // Act const response = await request.get(`/api/news/uuid/${nonExistentUuid}`); // Assert expect(response.status).toBe(404); expect(response.body.success).toBe(false); expect(response.body.error).toBeDefined(); }); }); describe('GET /api/cache/stats', () => { test('returns cache statistics', async () => { // Act const response = await request.get('/api/cache/stats'); // Assert expect(response.status).toBe(200); expect(response.body.success).toBe(true); expect(response.body.data).toHaveProperty('hits'); expect(response.body.data).toHaveProperty('misses'); expect(response.body.data).toHaveProperty('keys'); }); }); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Malachi-devel/the-news-api-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server