UNPKG

@apistudio/apim-cli

Version:

CLI for API Management Products

257 lines (231 loc) 8.14 kB
/** * Copyright IBM Corp. 2024, 2025 */ import axios from 'axios'; import FormData from 'form-data'; import { sendToGateway, validationManager, ParseAndFindResponse, } from '../../src/service/gateway-service.js'; jest.mock('axios'); const mockAppend = jest.fn(); const mockGetHeaders = jest.fn().mockReturnValue({}); jest.mock('form-data', () => { return jest.fn().mockImplementation(() => ({ append: mockAppend, getHeaders: mockGetHeaders, })); }); jest.mock('@apic/studio-shared', () => { return { Logger: { debug: jest.fn(), info: jest.fn(), warn: jest.fn(), error: jest.fn(), log: jest.fn(), }, IpcError: class IpcError extends Error { status: number; data: any; constructor(message: string, status: number, data?: any) { super(message); this.name = 'IpcError'; this.status = status; this.data = data; } }, GatewaysJson: { gateways: [], overwrite: true, skip: false, }, }; }); describe('gateway-service', () => { const zipBuffer = Buffer.from('mock'); const gatewayJson = { overwrite: true } as any; describe('sendToGateway', () => { beforeEach(() => { jest.clearAllMocks(); (FormData as any).mockImplementation(() => ({ append: jest.fn(), getHeaders: jest.fn().mockReturnValue({}), })); }); it('should send successfully with basic auth', async () => { (axios.post as jest.Mock).mockResolvedValue({ status: 200, data: {} }); await expect( sendToGateway('http://example.com', 'user', 'pass', false, zipBuffer, gatewayJson) ).resolves.toMatchObject({ success: true, statusCode: 200, message: 'Api deployment Successful', }); }); it('should send successfully with bearer token and failed APIs in response', async () => { (axios.post as jest.Mock).mockResolvedValue({ status: 200, data: { StudioResult: [ { API: { status: 'Failed', explanation: 'Something bad happened' }, }, ], }, }); await expect( sendToGateway('http://example.com', '', 'token', true, zipBuffer, gatewayJson) ).resolves.toMatchObject({ success: false, errors: expect.arrayContaining(['Something bad happened']), message: 'Api deployment Failed', }); }); it('should handle axios post failure without status (fallback to 404)', async () => { (axios.post as jest.Mock).mockRejectedValue({ message: 'Post failed' }); await expect( sendToGateway('http://example.com', 'user', 'pass', false, zipBuffer, gatewayJson) ).resolves.toMatchObject({ success: false, statusCode: 404 }); }); it('should handle 401 response and provide error message in sendToGateway', async () => { (axios.post as jest.Mock).mockRejectedValue({ message: 'Unauthorized', response: { status: 401 }, }); await expect( sendToGateway('http://example.com', 'user', 'wrongpass', false, zipBuffer, gatewayJson) ).resolves.toMatchObject({ statusCode: 401, errors: expect.arrayContaining([ 'Unauthorized access: Please check your authentication details.', ]), }); }); it('should handle error with errorDetails in response', async () => { (axios.post as jest.Mock).mockRejectedValue({ message: 'Post failed', response: { status: 500, data: { errorDetails: 'Detailed error message from gateway', }, }, }); await expect( sendToGateway('http://example.com', 'user', 'pass', false, zipBuffer, gatewayJson) ).resolves.toMatchObject({ success: false, statusCode: 500, message: 'Detailed error message from gateway', errors: ['Detailed error message from gateway'], }); }); it('should fallback to error.message when errorDetails is not present', async () => { (axios.post as jest.Mock).mockRejectedValue({ message: 'Generic failure', response: { status: 500, data: {}, }, }); await expect( sendToGateway('http://example.com', 'user', 'pass', false, zipBuffer, gatewayJson) ).resolves.toMatchObject({ success: false, statusCode: 500, message: expect.stringContaining('Response sending to http://example.com: Generic failure'), }); }); }); describe('validationManager', () => { const url = 'https://example.com'; const authorizationHeader = 'Bearer token'; it('should return { data: "OK", status: 200 } for a successful request', async () => { (axios.get as jest.Mock).mockResolvedValue({ status: 200, data: 'Success', }); await expect(validationManager(url, authorizationHeader)).resolves.toEqual({ data: 'OK', status: 200, }); }); it('should throw an error for a 401 Unauthorized response', async () => { (axios.get as jest.Mock).mockRejectedValue({ response: { status: 401, data: 'Unauthorized' }, }); await expect(validationManager(url, authorizationHeader)).rejects.toThrow( 'The user name or password did not match' ); }); it('should throw an error for a 502 Bad Gateway response', async () => { (axios.get as jest.Mock).mockRejectedValue({ response: { status: 502, data: 'Bad Gateway' }, }); await expect(validationManager(url, authorizationHeader)).rejects.toThrow('Bad Gateway'); }); it('should throw an error for a 404 Not Found response', async () => { (axios.get as jest.Mock).mockRejectedValue({ response: { status: 404, data: 'Not Found' }, }); await expect(validationManager(url, authorizationHeader)).rejects.toThrow( 'Gateway not found' ); }); it('should throw an error for a timeout', async () => { (axios.get as jest.Mock).mockRejectedValue({ code: 'ECONNABORTED' }); await expect(validationManager(url, authorizationHeader)).rejects.toThrow( 'Request timed out' ); }); it('should throw an error for an unknown error', async () => { (axios.get as jest.Mock).mockRejectedValue(new Error('Unknown error')); await expect(validationManager(url, authorizationHeader)).rejects.toThrow( 'Something went wrong while validating the gateway.' ); }); it('should throw an error for an unexpected status code', async () => { (axios.get as jest.Mock).mockResolvedValue({ status: 418, data: 'I’m a teapot', }); await expect(validationManager(url, authorizationHeader)).rejects.toThrow( 'Something went wrong while validating the gateway.' ); }); it('should throw an error for unexpected status code', async () => { (axios.get as jest.Mock).mockRejectedValue({ response: { status: 409, data: 'Conflict occurred' }, }); await expect(validationManager('http://example.com', 'token')).rejects.toThrow( 'Conflict occurred' ); }); }); describe('ParseAndFindResponse', () => { it('should return failed explanations', () => { const result = ParseAndFindResponse({ data: { StudioResult: [ { API: { status: 'Failed', explanation: 'Failed 1' } }, { API: { status: 'Success' } }, { API: { status: 'Failed', explanation: 'Failed 2' } }, ], }, }); expect(result).toEqual(['Failed 1', 'Failed 2']); }); it('should return empty array for no failures', () => { const result = ParseAndFindResponse({ data: { StudioResult: [{ API: { status: 'Success' } }] }, }); expect(result).toEqual([]); }); it('should return empty array for invalid input', () => { expect(ParseAndFindResponse(null)).toEqual([]); expect(ParseAndFindResponse({ data: {} })).toEqual([]); }); }); });