Skip to main content
Glama
project-issues.test.ts5.43 kB
/** * @vitest-environment node */ import { vi } from 'vitest'; import type { DeepSourceIssue } from '../models/issues'; import type { PaginatedResult } from '../utils/pagination/types'; // Create mock logger const mockLogger = { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn(), }; // Mock modules before importing the implementation vi.mock('../utils/logging/logger', () => ({ createLogger: vi.fn(() => mockLogger), })); // Mock the DeepSource client const mockGetIssues = vi.fn(); vi.mock('../deepsource', () => ({ DeepSourceClient: vi.fn().mockImplementation(() => ({ getIssues: mockGetIssues, })), ReportType: { OWASP_TOP_10: 'OWASP_TOP_10', SANS_TOP_25: 'SANS_TOP_25', MISRA_C: 'MISRA_C', CODE_COVERAGE: 'CODE_COVERAGE', CODE_HEALTH_TREND: 'CODE_HEALTH_TREND', ISSUE_DISTRIBUTION: 'ISSUE_DISTRIBUTION', ISSUES_PREVENTED: 'ISSUES_PREVENTED', ISSUES_AUTOFIXED: 'ISSUES_AUTOFIXED', }, ReportStatus: { PASSING: 'PASSING', FAILING: 'FAILING', NOOP: 'NOOP', }, })); // Import the modules under test AFTER mocking const { handleDeepsourceProjectIssues } = await import('../handlers/project-issues'); describe('Project Issues Handler', () => { // Environment backup let originalEnv: Record<string, string | undefined>; beforeEach(() => { // Backup environment originalEnv = { ...process.env }; process.env.DEEPSOURCE_API_KEY = 'test-api-key'; // Reset mocks vi.clearAllMocks(); }); afterEach(() => { // Restore environment process.env = originalEnv; }); describe('handleDeepsourceProjectIssues', () => { it('should fetch project issues successfully', async () => { // Mock response data const mockIssues: PaginatedResult<DeepSourceIssue> = { items: [ { id: 'issue-1', title: 'Test Issue 1', shortcode: 'TEST-001', category: 'BUG', severity: 'CRITICAL', status: 'OPEN', issue_text: 'This is a test issue', file_path: 'src/test.ts', line_number: 42, tags: ['javascript'], }, ], pageInfo: { hasNextPage: false, hasPreviousPage: false, startCursor: 'cursor-1', endCursor: 'cursor-2', }, totalCount: 1, }; // Set up the mock implementation mockGetIssues.mockResolvedValue(mockIssues); // Call the handler const result = await handleDeepsourceProjectIssues({ projectKey: 'test-project', }); // Verify the result expect(result).toBeDefined(); expect(result.content).toHaveLength(1); expect(result.content[0].type).toBe('text'); // Parse the response and verify structure const parsedContent = JSON.parse(result.content[0].text); expect(parsedContent).toHaveProperty('issues'); expect(parsedContent.issues).toHaveLength(1); expect(parsedContent.issues[0]).toMatchObject({ id: 'issue-1', title: 'Test Issue 1', shortcode: 'TEST-001', category: 'BUG', severity: 'CRITICAL', status: 'OPEN', }); }); it('should throw error when API key is not set', async () => { // Remove API key from environment delete process.env.DEEPSOURCE_API_KEY; // Call the handler and expect it to throw await expect( handleDeepsourceProjectIssues({ projectKey: 'test-project', }) ).rejects.toThrow('Configuration error: DeepSource API key is required but not configured'); }); it('should handle errors from the client', async () => { // Set up the mock to throw an error const testError = new Error('API client error'); mockGetIssues.mockRejectedValue(testError); // Call the handler and expect it to throw await expect( handleDeepsourceProjectIssues({ projectKey: 'test-project', }) ).rejects.toThrow('API client error'); }); it('should handle max_pages parameter with multi-page fetching message', async () => { // Mock response data const mockIssues: PaginatedResult<DeepSourceIssue> = { items: [ { id: 'issue-1', title: 'Test Issue 1', shortcode: 'TEST-001', category: 'BUG', severity: 'CRITICAL', status: 'OPEN', issue_text: 'Test issue message', file_path: 'src/test.ts', line_number: 10, tags: ['test'], }, ], totalCount: 1, pageInfo: { hasNextPage: false, hasPreviousPage: false, }, pagination: { has_more_pages: false, page_size: 1, }, }; mockGetIssues.mockResolvedValue(mockIssues); const result = await handleDeepsourceProjectIssues({ projectKey: 'test-project', max_pages: 5, }); // Parse the response content const parsedContent = JSON.parse(result.content[0].text); expect(parsedContent.issues).toEqual(mockIssues.items); expect(parsedContent.usage_examples.pagination.next_page).toBe( 'Multi-page fetching enabled with max_pages parameter' ); expect(mockGetIssues).toHaveBeenCalledWith('test-project', { max_pages: 5 }); }); }); });

Latest Blog Posts

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/sapientpants/deepsource-mcp-server'

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