Skip to main content
Glama

News Aggregator API

final-controller.test.ts6.4 kB
/** * Final, reliable tests for the News Controller * * This version fixes all the structure mismatches and properly tests the controller behavior. */ import { describe, test, expect, beforeEach, afterEach, jest } from '@jest/globals'; import { Request, Response } from 'express'; // Mock the services before importing the controller const mockGetTopNews = jest.fn(); const mockGetAllNews = jest.fn(); const mockGetNewsByUuid = jest.fn(); const mockGetNewsSources = jest.fn(); // Mock the NewsService before importing the controller jest.mock('../services/news.service', () => { return { NewsService: jest.fn().mockImplementation(() => ({ getTopNews: mockGetTopNews, getAllNews: mockGetAllNews, getNewsByUuid: mockGetNewsByUuid, getNewsSources: mockGetNewsSources })) }; }); // Mock the cache service to prevent actual cache operations jest.mock('../utils/cache', () => ({ cacheService: { get: jest.fn(), set: jest.fn(), has: jest.fn(), clear: jest.fn(), getStats: jest.fn().mockReturnValue({ hits: 0, misses: 0, keys: 0 }) } })); // Import the controller after setting up mocks import { NewsController } from '../controllers/news.controller'; describe('NewsController Tests', () => { let controller: NewsController; let req: Partial<Request>; let res: Partial<Response>; beforeEach(() => { // Create a fresh controller controller = new NewsController(); // Reset mock functions jest.clearAllMocks(); // Set up request with all necessary properties req = { query: { search: undefined, search_fields: undefined, locale: undefined, categories: undefined, exclude_categories: undefined, domains: undefined, exclude_domains: undefined, source_ids: undefined, exclude_source_ids: undefined, language: undefined, published_before: undefined, published_after: undefined, limit: undefined, page: undefined, sort: undefined }, params: {} }; // Set up response res = { status: jest.fn().mockReturnThis(), json: jest.fn() }; }); afterEach(() => { jest.clearAllMocks(); }); describe('getTopNews', () => { test('returns 200 and wrapped data when service succeeds', async () => { // Arrange - mock the service response const mockArticles = [{ uuid: 'test-123', title: 'Test Article' }]; mockGetTopNews.mockResolvedValueOnce({ data: mockArticles, meta: { found: 1, returned: 1 } }); // Act - call the controller method await controller.getTopNews(req as Request, res as Response); // Assert - verify proper response format expect(res.status).toHaveBeenCalledWith(200); expect(res.json).toHaveBeenCalledWith({ success: true, data: { data: expect.arrayContaining([ expect.objectContaining({ uuid: 'test-123' }) ]), meta: expect.objectContaining({ found: 1, returned: 1 }) } }); }); test('returns 500 when service fails', async () => { // Arrange - mock a service error mockGetTopNews.mockRejectedValueOnce(new Error('API error')); // Act await controller.getTopNews(req as Request, res as Response); // Assert expect(res.status).toHaveBeenCalledWith(500); expect(res.json).toHaveBeenCalledWith({ success: false, error: expect.stringContaining('API error') }); }); test('passes query parameters correctly', async () => { // Arrange - set up request params req.query = { ...req.query, categories: 'technology', limit: '10' }; mockGetTopNews.mockResolvedValueOnce({ data: [], meta: { found: 0, returned: 0 } }); // Act await controller.getTopNews(req as Request, res as Response); // Assert - verify params passed correctly expect(mockGetTopNews).toHaveBeenCalledWith( expect.objectContaining({ categories: 'technology', limit: 10 // Number conversion by controller }) ); }); }); describe('getNewsByUuid', () => { test('returns 200 and article when found', async () => { // Arrange const uuid = 'test-uuid-123'; req.params = { uuid }; mockGetNewsByUuid.mockResolvedValueOnce({ data: { uuid, title: 'Test Article' } }); // Act await controller.getNewsByUuid(req as Request, res as Response); // Assert expect(mockGetNewsByUuid).toHaveBeenCalledWith(uuid); expect(res.status).toHaveBeenCalledWith(200); expect(res.json).toHaveBeenCalledWith({ success: true, data: { data: expect.objectContaining({ uuid }) } }); }); test('returns 500 for error, including not found', async () => { // Arrange const uuid = 'non-existent'; req.params = { uuid }; mockGetNewsByUuid.mockRejectedValueOnce(new Error('Article not found')); // Act await controller.getNewsByUuid(req as Request, res as Response); // Assert - Note: controller returns 500 for all errors expect(mockGetNewsByUuid).toHaveBeenCalledWith(uuid); expect(res.status).toHaveBeenCalledWith(500); expect(res.json).toHaveBeenCalledWith({ success: false, error: expect.stringContaining('not found') }); }); }); describe('getAllNews', () => { test('returns paginated results with proper structure', async () => { // Arrange req.query = { ...req.query, page: '2', limit: '10' }; const mockResults = { data: [{ uuid: 'page2-1', title: 'Page 2 Article 1' }], meta: { found: 25, returned: 1, page: 2, limit: 10 } }; mockGetAllNews.mockResolvedValueOnce(mockResults); // Act await controller.getAllNews(req as Request, res as Response); // Assert expect(res.status).toHaveBeenCalledWith(200); expect(res.json).toHaveBeenCalledWith({ success: true, data: mockResults }); }); }); });

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