UNPKG

@apistudio/apim-cli

Version:

CLI for API Management Products

314 lines (267 loc) 9.21 kB
/** * Copyright IBM Corp. 2024, 2025 */ import axios from 'axios'; import https from 'https'; import { fetchCaptureId, fetchTraceAndCatalogData, } from '../../src/helpers/trace-helper.js'; // Mock axios jest.mock('axios'); const mockedAxios = axios as jest.Mocked<typeof axios>; // Mock https jest.mock('https', () => ({ Agent: jest.fn().mockImplementation(() => ({})), })); describe('trace-helper', () => { beforeEach(() => { jest.clearAllMocks(); // Mock axios.create to return an object with post and get methods mockedAxios.create.mockReturnValue({ post: jest.fn(), get: jest.fn(), } as any); }); describe('fetchCaptureId', () => { const mockReqBody = JSON.stringify({ url: 'https://api.example.com', apiName: 'test-api', orgName: 'test-org', catalogName: 'test-catalog', gatewayName: 'test-gateway', }); const mockHeaders = { 'authorization': 'Bearer test-token', }; it('should fetch capture ID successfully', async () => { // Mock response data const mockResponseData = { captureId: 'test-capture-id', status: 'success', }; // Setup axios post mock const mockPost = jest.fn().mockResolvedValue({ data: mockResponseData, }); mockedAxios.create.mockReturnValue({ post: mockPost, } as any); // Call the function const result = await fetchCaptureId(mockReqBody, mockHeaders); // Assertions expect(https.Agent).toHaveBeenCalledWith({ rejectUnauthorized: false, }); expect(mockedAxios.create).toHaveBeenCalledWith({ httpsAgent: expect.any(Object), baseURL: 'https://api.example.com', }); // Verify the post call expect(mockPost).toHaveBeenCalledWith( 'https://api.example.com/api/catalogs/test-org/test-catalog/configured-gateway-services/test-gateway/assembly-debug', { FilterByAPI: 'test-api' }, { headers: { Authorization: 'Bearer test-token', Accept: 'application/json', 'Content-Type': 'application/json', }, }, ); // Verify the result expect(result).toEqual(mockResponseData); }); it('should return null when token is not provided', async () => { // Call the function without token const result = await fetchCaptureId(mockReqBody, {}); // Assertions expect(mockedAxios.create).not.toHaveBeenCalled(); expect(result).toBeNull(); }); it('should handle errors and return null', async () => { // Setup axios post mock to throw error const mockPost = jest.fn().mockRejectedValue(new Error('Network error')); mockedAxios.create.mockReturnValue({ post: mockPost, } as any); // Mock console.error console.error = jest.fn(); // Call the function const result = await fetchCaptureId(mockReqBody, mockHeaders); // Assertions expect(console.error).toHaveBeenCalledWith('err ==> ', expect.any(Error)); expect(result).toBeNull(); }); }); describe('fetchTraceAndCatalogData', () => { const mockReqBody = JSON.stringify({ url: 'https://api.example.com', orgName: 'test-org', catalogName: 'test-catalog', gatewayName: 'test-gateway', captureId: 'test-capture-id', transactionId: 'test-transaction-id', orgId: 'test-org-id', apiName: 'test-api', apiVersion: '1.0.0', }); const mockHeaders = { 'authorization': 'Bearer test-token', }; it('should fetch trace and catalog data successfully', async () => { // Mock response data const mockTraceData = { id: 'trace-123', details: 'Sample trace data', }; const mockCatalogData = { id: 'catalog-456', name: 'Test API', version: '1.0.0', }; // Setup axios get mock for trace data const mockGet = jest .fn() .mockResolvedValueOnce({ data: mockTraceData }) // First call for trace data .mockResolvedValueOnce({ data: { catalog_api: mockCatalogData } }); // Second call for catalog data mockedAxios.create.mockReturnValue({ get: mockGet, } as any); // Call the function const result = await fetchTraceAndCatalogData(mockReqBody, mockHeaders); // Assertions expect(https.Agent).toHaveBeenCalledWith({ rejectUnauthorized: false, }); // Verify the get calls expect(mockGet).toHaveBeenCalledWith( 'https://api.example.com/api/catalogs/test-org/test-catalog/configured-gateway-services/test-gateway/assembly-debug/test-capture-id/transaction/test-transaction-id', { headers: { Authorization: 'Bearer test-token', Accept: 'application/json', 'Content-Type': 'application/json', }, }, ); expect(mockGet).toHaveBeenCalledWith( "https://api.example.com/api/catalogs/test-org-id/test-catalog/apis/test-api/1.0.0?fields=add(catalog_api,product_urls)'", { headers: { Authorization: 'Bearer test-token', Accept: 'application/json', 'Content-Type': 'application/json', }, }, ); // Verify the result expect(result).toEqual({ traceData: mockTraceData, catalogData: mockCatalogData, }); }); it('should handle missing transaction ID and fetch it', async () => { // Mock request body without transaction ID const reqBodyWithoutTransId = JSON.stringify({ url: 'https://api.example.com', orgName: 'test-org', catalogName: 'test-catalog', gatewayName: 'test-gateway', captureId: 'test-capture-id', orgId: 'test-org-id', apiName: 'test-api', apiVersion: '1.0.0', }); // Mock response data const mockTransactionId = 'fetched-transaction-id'; const mockTraceData = { id: 'trace-123', details: 'Sample trace data', }; const mockCatalogData = { id: 'catalog-456', name: 'Test API', version: '1.0.0', }; // Setup axios get mock const mockGet = jest .fn() .mockResolvedValueOnce({ Probe: { ProbeID: mockTransactionId } }) // First call to fetch transaction ID (no data wrapper) .mockResolvedValueOnce({ data: mockTraceData }) // Second call for trace data .mockResolvedValueOnce({ data: { catalog_api: mockCatalogData } }); // Third call for catalog data mockedAxios.create.mockReturnValue({ get: mockGet, } as any); // Call the function const result = await fetchTraceAndCatalogData( reqBodyWithoutTransId, mockHeaders, ); // Assertions for transaction ID fetch expect(mockGet).toHaveBeenCalledWith( 'https://api.example.com/api/catalogs/test-org/test-catalog/configured-gateway-services/test-gateway/assembly-debug/test-capture-id/transaction', { headers: { Authorization: 'Bearer test-token', Accept: 'application/json', 'Content-Type': 'application/json', }, }, ); // Verify the result expect(result).toEqual({ traceData: mockTraceData, catalogData: mockCatalogData, }); }); it('should handle errors in fetchTraceData and return null', async () => { // Setup axios get mock to throw error for trace data const mockGet = jest .fn() .mockRejectedValueOnce(new Error('Network error')) // Error for trace data .mockResolvedValueOnce({ data: { catalog_api: { id: 'catalog-456' } }, }); // Success for catalog data mockedAxios.create.mockReturnValue({ get: mockGet, } as any); // Mock console.error console.error = jest.fn(); // Call the function const result = await fetchTraceAndCatalogData(mockReqBody, mockHeaders); // Assertions expect(console.error).toHaveBeenCalledWith( 'fetch trace error', expect.any(Error), ); expect(result).toEqual({ traceData: null, catalogData: { id: 'catalog-456' }, }); }); it('should handle errors in fetchCatalogData and return null', async () => { // Setup axios get mock const mockGet = jest .fn() .mockResolvedValueOnce({ data: { id: 'trace-123' } }) // Success for trace data .mockRejectedValueOnce(new Error('Catalog error')); // Error for catalog data mockedAxios.create.mockReturnValue({ get: mockGet, } as any); // Mock console.error console.error = jest.fn(); // Call the function const result = await fetchTraceAndCatalogData(mockReqBody, mockHeaders); // Assertions expect(console.error).toHaveBeenCalledWith( 'catalog error ==>', expect.any(Error), ); expect(result).toEqual({ traceData: { id: 'trace-123' }, catalogData: null, }); }); }); });