/* eslint-disable @typescript-eslint/no-var-requires */
/* eslint-disable @typescript-eslint/no-explicit-any */
import path from 'path';
import AdmZip from 'adm-zip';
import { showError, showInfo, showWarning } from '../common/message-helper.js';
import { readMultiYaml } from '../common/yaml-helper.js';
import { readFile } from '../common/fs-helper.js';
import {
    getAPIRefToBuild,
    processEndpointFromResponse,
    addEndpointToZip,
    testAssets,
    combineTestAsset,
    testProjects,
    createJSONBuffer,
    APIEndpoints,
    updateEndpointZip,
    findProjectForApi,
	constructKey,
	buildAndDeployAssets,
	formattedEndpoints
} from './test-helper.js';
import {
    INVALID_OR_EMPTY_DEPLOYMENT_RESPONSES,
    NO_VALID_API_ASSET_FOUND,
    ADDING_ENDPOINT_FILE_FAILED,
    ERROR_IN_COMBINING_TEST_ASSET,
    JSON_FILE_MISSING,
    UPDATE_ENDPOINT_FAILED,
	APIENDPOINTS
} from '../../constants/message-constants.js';
import { BuildTestAssetsResult, executeBuildTestAssets } from '../../testers/project/projects-asset-testers.js';
import { GatewayResponseAPI } from '../../model/studio/deploy-response-model.js';
import { ENDPOINT_FILE } from '../../constants/app-constants.js';
import { KindEnums } from '@apic/api-model/common/StudioEnums.js';
import { getAllProjectNames } from './root-dir-helper.js';
import { searchAssetByKind } from './asset-searchByKind-helper.js';
import { executeDeployment } from '../../deployers/project/projects-deployer.js';
import { buildAssets } from '../../actions/helpers/build-action-helper.js';
import { GatewaysJson } from '@apic/studio-shared';
import Table from 'cli-table3';


jest.mock('path');

jest.mock('cli-table3', () => {
	const mockTableInstance = {
	push: jest.fn(),
	toString: jest.fn().mockReturnValue('mocked table output'),
	};
	return jest.fn(() => mockTableInstance);
});

jest.mock('../../actions/helpers/build-action-helper',() => ({
	buildAssets: jest.fn()
}));

jest.mock('../../deployers/project/projects-deployer',() => ({
	executeDeployment: jest.fn()
}))
jest.mock('adm-zip', () => {
	return jest.fn().mockImplementation(() => ({
		addFile: jest.fn(),
		toBuffer: jest.fn(),
		getEntries: jest.fn(),
		getEntry: jest.fn(),
		updateFile: jest.fn()
	}));
});

jest.mock('../common/message-helper', () => ({
	showError: jest.fn(),
	showInfo: jest.fn(),
	showWarning: jest.fn()
}));

jest.mock('./root-dir-helper', ()=>({
	getAllProjectNames: jest.fn()
}));

jest.mock('./asset-searchByKind-helper',() =>({
	searchAssetByKind: jest.fn()
}));

jest.mock('@apic/studio-build', () => ({
	processProjectBuild: jest.fn(),
}));


jest.mock('@apic/studio-deploy', () => ({
	processDeployment: jest.fn(),
}));

jest.mock('../../testers/project/projects-asset-testers');
jest.mock('../common/yaml-helper.js');
jest.mock('../common/fs-helper.js');

jest.mock('env-paths', () => {
	return jest.fn((name: string) => ({
		data: `/mock/path/${name}-data`,
		config: `/mock/path/${name}-config`,
		cache: `/mock/path/${name}-cache`,
		log: `/mock/path/${name}-log`,
		temp: `/mock/path/${name}-temp`,
	}));
});

jest.mock('../../debug/debug-manager.js', () => ({
	DebugManager: {
		getInstance: jest.fn(() => ({
			setDebugEnabled: jest.fn(),
			isDebugEnabled: jest.fn()
		})),
	},
}));

describe ('Test-helper test Suite', () => {
	describe('getAPIRefToBuild', () => {
		beforeEach(() => {
			jest.clearAllMocks();
		});

		it('should return the API reference if present in the YAML file', () => {
			const testFilePath = 'some/test/file.yaml';
			const parentDirPath = 'some/test';
			const testFileName = 'file.yaml';
			const yamlContent = 'yaml content';
			const parsedYaml = [{
				kind: 'test',
				spec: {
					api: { $ref: 'api-ref' },
				},
			}];

			(path.dirname as jest.Mock).mockReturnValue(parentDirPath);
			(path.basename as jest.Mock).mockReturnValue(testFileName);
			(readFile as jest.Mock).mockReturnValue(yamlContent);
			(readMultiYaml as jest.Mock).mockReturnValue(parsedYaml);

			const result = getAPIRefToBuild(testFilePath);

			expect(path.dirname).toHaveBeenCalledWith(testFilePath);
			expect(path.basename).toHaveBeenCalledWith(testFilePath);
			expect(readFile).toHaveBeenCalledWith(parentDirPath, testFileName);
			expect(readMultiYaml).toHaveBeenCalledWith(testFileName, yamlContent);
			expect(result).toEqual(['api-ref']);
		});

		it('should show an error and return null if API reference is not found', () => {
			const testFilePath = 'some/test/file.yaml';
			const parentDirPath = 'some/test';
			const testFileName = 'file.yaml';
			const yamlContent = 'yaml content';
			const parsedYaml = [{
				spec: {
					api: {},
				},
			}];

			(path.dirname as jest.Mock).mockReturnValue(parentDirPath);
			(path.basename as jest.Mock).mockReturnValue(testFileName);
			(readFile as jest.Mock).mockReturnValue(yamlContent);
			(readMultiYaml as jest.Mock).mockReturnValue(parsedYaml);

			const result = getAPIRefToBuild(testFilePath);

			// expect(showError).toHaveBeenCalledWith(NO_VALID_API_ASSET_FOUND);
			expect(result).toHaveLength(0);
		});
	});

	describe('processEndpointFromResponse', () => {
		it('should process and return endpoint JSON from response', () => {
			const responses: GatewayResponseAPI[] = [
				{
					namespace: 'namespace1',
					assetName: 'asset1',
					version: '1.0',
					gatewayEndpoints: ['endpoint1', 'endpoint2'],
					name: 'api1',
					kind: 'someKind',
				},
				{
					namespace: 'namespace1',
					assetName: 'asset1',
					version: '1.0',
					gatewayEndpoints: ['endpoint3'],
					name: 'api1',
					kind: 'someKind',
				},
			];
    
			const result = processEndpointFromResponse(responses);
    
			const expectedJSON = JSON.stringify({
				'namespace1:asset1:1.0': ['endpoint1', 'endpoint2', 'endpoint3'],
			}, null, 2);
    
			expect(result).toEqual(Buffer.from(expectedJSON, 'utf-8'));
		});
    
		it('should throw an error if responses are invalid or empty', () => {
			expect(() => processEndpointFromResponse([] as GatewayResponseAPI[])).toThrowError(INVALID_OR_EMPTY_DEPLOYMENT_RESPONSES);
			expect(() => processEndpointFromResponse(null as unknown as GatewayResponseAPI[])).toThrowError(INVALID_OR_EMPTY_DEPLOYMENT_RESPONSES);
			expect(() => processEndpointFromResponse(undefined as unknown as GatewayResponseAPI[])).toThrowError(INVALID_OR_EMPTY_DEPLOYMENT_RESPONSES);
		});
    
	});
	describe('addEndpointToZip', () => {
		let mockAddFile: jest.Mock;
		let mockToBuffer: jest.Mock;
		let admZipInstance: AdmZip;
	
		beforeEach(() => {
			admZipInstance = new AdmZip() as jest.Mocked<AdmZip>;
			mockAddFile = admZipInstance.addFile as jest.Mock;
			mockToBuffer = admZipInstance.toBuffer as jest.Mock;
			(AdmZip as jest.Mock).mockImplementation(() => admZipInstance);
		});
	
		afterEach(() => {
			jest.clearAllMocks();
		});
	
		it('should add the endpoint file to the zip and return the updated buffer', () => {

			const testZipBuffer = Buffer.from('test zip content');
			const endpointFile = Buffer.from('endpoint content');
			const updatedBuffer = Buffer.from('updated zip content');
			mockToBuffer.mockReturnValue(updatedBuffer);

			const result = addEndpointToZip(testZipBuffer, endpointFile);

			expect(AdmZip).toHaveBeenCalledWith(testZipBuffer);
			expect(mockAddFile).toHaveBeenCalledWith(ENDPOINT_FILE, endpointFile);
			expect(result).toBe(updatedBuffer);
		});
	
		it('should throw an error if adding the endpoint file fails', () => {
			// Arrange
			const testZipBuffer = Buffer.from('test zip content');
			const endpointFile = Buffer.from('endpoint content');
			const errorMessage = 'mock error';
			mockAddFile.mockImplementation(() => { throw new Error(errorMessage); });
			expect(() => addEndpointToZip(testZipBuffer, endpointFile))
				.toThrow(`${ADDING_ENDPOINT_FILE_FAILED} ${errorMessage}`);
		});
	});
	describe('testAssets', () => {
		const rootDir = 'C:/Users/Downloads/CLI_DEMO_ASSETS';
		const projects = 'projectA';
		const assets = 'dev:test:1.0';
	
		beforeEach(() => {
			jest.clearAllMocks();
		});
	
		it('should call showInfo with correct messages and executeBuildTestAssets with correct arguments', async () => {
			const mockResult: BuildTestAssetsResult = {
				zipBuffer: Buffer.from('test buffer'),
				apiReference: 'testApiReference'
			};
			(executeBuildTestAssets as jest.Mock).mockResolvedValue(mockResult);

			const result = await testAssets(rootDir, projects, assets);

			expect(showInfo).toHaveBeenCalledWith('--------------------------');
			expect(showInfo).toHaveBeenCalledWith('Test Started');
			expect(showInfo).toHaveBeenCalledTimes(3);
			expect(executeBuildTestAssets).toHaveBeenCalledWith(rootDir, projects, assets);
			expect(result).toBe(mockResult);
		});
		it('should handle errors thrown by executeBuildTestAssets', async () => {
			const errorMessage = 'Failed to build test assets';
			(executeBuildTestAssets as jest.Mock).mockRejectedValue(new Error(errorMessage));
			await expect(testAssets(rootDir, projects, assets)).rejects.toThrow(errorMessage);
			expect(showInfo).toHaveBeenCalledWith('--------------------------');
			expect(showInfo).toHaveBeenCalledWith('Test Started');
			expect(showInfo).toHaveBeenCalledTimes(3); // Two lines and one "Test Started"
			expect(executeBuildTestAssets).toHaveBeenCalledWith(rootDir, projects, assets);
		});
	
	});

	describe('combineTestAsset', () => {
		const rootDir = 'C:/Users/Downloads/CLI_DEMO_ASSETS';
		const assetsToTest = {
			projectA: 'metadataA',
			projectB: 'metadataB',
		};
		let mockResult: BuildTestAssetsResult;
		let mockCombinedZip: AdmZip;
	
		beforeEach(() => {
			mockResult = {
				zipBuffer: Buffer.from('project zip buffer'),
				apiReference: 'api-ref',
			};
			mockCombinedZip = new AdmZip() as jest.Mocked<AdmZip>;
			(AdmZip as jest.Mock).mockImplementation(() => mockCombinedZip);
			mockCombinedZip.addFile = jest.fn();
			mockCombinedZip.toBuffer = jest.fn().mockReturnValue(Buffer.from('final zip content'));
			mockCombinedZip.getEntries = jest.fn();
			mockCombinedZip.getEntry = jest.fn();
			jest.clearAllMocks();
		});
		it('should successfully combine test assets into one zip', async () => {
			const testAssetsSpy = jest.spyOn(require('./test-helper'), 'testAssets');
			testAssetsSpy.mockResolvedValue(mockResult);
		
			const mockProjectZip = new AdmZip() as jest.Mocked<AdmZip>;
			(AdmZip as jest.Mock).mockReturnValue(mockProjectZip);
		
			const mockEntry = {
				entryName: 'testEntry',
				getData: jest.fn().mockReturnValue(Buffer.from('data')),
			} as unknown as AdmZip.IZipEntry;
		
			mockProjectZip.getEntries = jest.fn().mockReturnValue([mockEntry]);
		
			const result = await combineTestAsset(rootDir, assetsToTest);
		
			expect(mockCombinedZip.addFile).toHaveBeenCalledWith(mockEntry.entryName, Buffer.from('data'));
		
			expect(result).toEqual({
				zipBuffer: mockCombinedZip.toBuffer(),
				apiReference: {
					projectA: 'api-ref',
					projectB: 'api-ref',
				}
			});
		
			testAssetsSpy.mockRestore();
		});
		
	
		it('should throw an error when combining fails', async () => {
			const testAssetsSpy = jest.spyOn(require('./test-helper'), 'testAssets');
			const errorMessage = 'Failed to build test assets';
			testAssetsSpy.mockRejectedValue(new Error(errorMessage));
	
			await expect(combineTestAsset(rootDir, assetsToTest)).rejects.toThrow(errorMessage);
			expect(showError).toHaveBeenCalledWith(`${ERROR_IN_COMBINING_TEST_ASSET} ${errorMessage}`);
			testAssetsSpy.mockRestore();
		});
	});

	describe('testProjects', () => {
		const rootDir = 'C:/Users/Downloads/CLI_DEMO_ASSETS';
		const projects = 'projectA';
	
		beforeEach(() => {
			jest.clearAllMocks();
		});
	
		it('should test specific projects when all is false', async () => {
			const mockAssetResults = { projectA: 'metadataA' };
			(searchAssetByKind as jest.Mock).mockResolvedValue(mockAssetResults);
	
			const result = await testProjects(false, rootDir, projects);
	
			expect(searchAssetByKind).toHaveBeenCalledWith(KindEnums.Test, rootDir, projects);
			expect(result).toEqual(mockAssetResults);
		});
	
		it('should test all projects when all is true', async () => {
			const mockAllProjects = 'projectA,projectB';
			const mockAssetResults = { projectA: 'metadataA', projectB: 'metadataB' };
			(getAllProjectNames as jest.Mock).mockReturnValue(mockAllProjects);
			(searchAssetByKind as jest.Mock).mockResolvedValue(mockAssetResults);
	
			const result = await testProjects(true, rootDir, '');
	
			expect(getAllProjectNames).toHaveBeenCalledWith(rootDir);
			expect(searchAssetByKind).toHaveBeenCalledWith(KindEnums.Test, rootDir, mockAllProjects);
			expect(result).toEqual(mockAssetResults);
		});
	});

	describe('createJSONBuffer', () => {
		it('should create a JSON buffer from API endpoints', () => {
			const jsonObject: APIEndpoints = {
				'namespace1:asset1:1.0': ['endpoint1', 'endpoint2']
			};
	
			const result = createJSONBuffer(jsonObject);
	
			const expectedJSON = JSON.stringify(jsonObject, null, 2);
			expect(result).toEqual(Buffer.from(expectedJSON, 'utf-8'));
		});
	});

	describe('updateEndpointZip', () => {
	
		let mockGetEntry: jest.Mock;
		let admZipInstance: AdmZip;

		beforeEach(() => {
			admZipInstance = new AdmZip() as jest.Mocked<AdmZip>;
			mockGetEntry =admZipInstance.getEntry as jest.Mock;
			(AdmZip as jest.Mock).mockImplementation(() => admZipInstance);
		});

		afterEach(() => {
			jest.clearAllMocks();
		});

		it('should throw an error if JSON parsing fails', async () => {
			const testZipBuffer = Buffer.from('test zip content');
			const newEndpoints = Buffer.from('invalid json');
		
			const jsonEntry = {
				getData: jest.fn().mockReturnValue(Buffer.from('{')),
			} as unknown as AdmZip.IZipEntry;
		
			mockGetEntry.mockReturnValue(jsonEntry);
		
			await expect(updateEndpointZip(testZipBuffer, newEndpoints))
				.rejects.toThrowError(new RegExp(`${UPDATE_ENDPOINT_FAILED} .*`));
		});
		it('should throw an error if the entry is not found', async () => {
			const testZipBuffer = Buffer.from('test zip content');
			const newEndpoints = Buffer.from(JSON.stringify({ key: ['new-endpoint'] }));
	
			mockGetEntry.mockReturnValue(null);
	
			await expect(updateEndpointZip(testZipBuffer, newEndpoints))
				.rejects.toThrowError(`${UPDATE_ENDPOINT_FAILED} ${JSON_FILE_MISSING}`);
		});
	});

	describe('findProjectForApi', () => {
		it('should correctly map APIs found in the apiReference', () => {
			const apiReference: Record<string, string> = {
				'Project1': 'api1, api2',
				'Project2': 'api3, api4',
			};
			const notFoundApisList: string[] = ['api1', 'api3'];
	
			const expected: Record<string, string> = {
				'Project1': 'api1',
				'Project2': 'api3',
			};
	
			const result = findProjectForApi(apiReference, notFoundApisList);
	
			expect(result).toEqual(expected);
		});
	
		it('should return an empty object if apiReference is empty', () => {
			const apiReference: Record<string, string> = {};
			const notFoundApisList: string[] = ['api1', 'api2'];
	
			const expected: Record<string, string> = {};
	
			const result = findProjectForApi(apiReference, notFoundApisList);
	
			expect(result).toEqual(expected);
		});
	
		it('should return an empty object if notFoundApisList is empty', () => {
			const apiReference: Record<string, string> = {
				'Project1': 'api1, api2',
				'Project2': 'api3, api4',
			};
			const notFoundApisList: string[] = [];
	
			const expected: Record<string, string> = {};
	
			const result = findProjectForApi(apiReference, notFoundApisList);
	
			expect(result).toEqual(expected);
		});
	
		it('should return an empty object if no APIs from notFoundApisList are found in apiReference', () => {
			const apiReference: Record<string, string> = {
				'Project1': 'api1, api2',
				'Project2': 'api3, api4',
			};
			const notFoundApisList: string[] = ['api5', 'api6'];
	
			const expected: Record<string, string> = {};
	
			const result = findProjectForApi(apiReference, notFoundApisList);
	
			expect(result).toEqual(expected);
		});
	
		it('should aggregate multiple matching APIs in the result for a single project', () => {
			const apiReference: Record<string, string> = {
				'Project1': 'api1, api2, api3',
				'Project2': 'api4, api5',
			};
			const notFoundApisList: string[] = ['api1', 'api2', 'api3'];
	
			const expected: Record<string, string> = {
				'Project1': 'api1,api2,api3',
			};
	
			const result = findProjectForApi(apiReference, notFoundApisList);
	
			expect(result).toEqual(expected);
		});
	});

	describe('constructKey', () => {
		it('should return the correct key for a valid response', () => {
			const response = {
				namespace: 'testNamespace',
				assetName: 'testAsset',
				version: '1.0.0',
				gatewayEndpoints: [],
			} as unknown as  GatewayResponseAPI;
	
			const result = constructKey(response);
	
			expect(result).toBe('testNamespace:testAsset:1.0.0');
		});
	
		it('should handle empty strings in the response', () => {
			const response = {
				namespace: '',
				assetName: 'testAsset',
				version: '1.0.0',
				gatewayEndpoints: [],
			}  as unknown as  GatewayResponseAPI;
	
			const result = constructKey(response);
	
			expect(result).toBe(':testAsset:1.0.0');
		});
	
		it('should handle missing asset name', () => {
			const response = {
				namespace: 'testNamespace',
				assetName: '',
				version: '1.0.0',
				gatewayEndpoints: [],
			} as unknown as  GatewayResponseAPI;
	
			const result = constructKey(response);
	
			expect(result).toBe('testNamespace::1.0.0');
		});
	
		it('should handle missing version', () => {
			const response = {
				namespace: 'testNamespace',
				assetName: 'testAsset',
				version: '',
				gatewayEndpoints: [],
			} as unknown as  GatewayResponseAPI;
	
			const result = constructKey(response);
	
			expect(result).toBe('testNamespace:testAsset:');
		});
	
		it('should handle all fields as empty strings', () => {
			const response = {
				namespace: '',
				assetName: '',
				version: '',
				gatewayEndpoints: [],
			}  as unknown as  GatewayResponseAPI;
	
			const result = constructKey(response);
	
			expect(result).toBe('::');
		});
	
		it('should handle numeric version values', () => {
			const response = {
				namespace: 'testNamespace',
				assetName: 'testAsset',
				version: '2',
				gatewayEndpoints: [],
			} as unknown as  GatewayResponseAPI;
	
			const result = constructKey(response);
	
			expect(result).toBe('testNamespace:testAsset:2');
		});
	});
	describe('buildAndDeployAssets', () => {
		const mockBuildAssets = buildAssets as jest.MockedFunction<typeof buildAssets>;
		const mockExecuteDeployment = executeDeployment as jest.MockedFunction<typeof executeDeployment>;
		const mockShowError = showError as jest.MockedFunction<typeof showError>;
	
		beforeEach(() => {
		jest.clearAllMocks();
		});

		it('should build and combine assets into a single zip and deploy', async () => {
			const mockZipBuffer = Buffer.from('mock-zip-data');
			const mockCombinedZip = {
				addFile: jest.fn(),
				toBuffer: jest.fn().mockReturnValue(mockZipBuffer)
			};
	
			const mockProjectZip = {
				getEntries: jest.fn().mockReturnValue([
					{
						entryName: 'file1.txt',
						getData: jest.fn().mockReturnValue(Buffer.from('file-data'))
					}
				] as any)
			};
	
			(AdmZip as jest.Mock).mockImplementation((buffer?: Buffer) =>
				buffer ? (mockProjectZip as any) : (mockCombinedZip as any)
			);
	
			mockBuildAssets.mockResolvedValue(Buffer.from('mock-project-zip-data'));
			const mockDeploymentResult: GatewayResponseAPI[] = [];
			mockExecuteDeployment.mockResolvedValue(mockDeploymentResult);
	
			const localDir = 'mock-local-dir';
			const assetsToBuildAndDeploy = {
				project1: 'metadata1',
				project2: 'metadata2'
			};
			const gatewayJson: GatewaysJson = {
				gateways: [],
				overwrite: 'ALL',
				skip: 'NONE'
			};
	
			const result = await buildAndDeployAssets(localDir, assetsToBuildAndDeploy, gatewayJson);
	
			expect(AdmZip).toHaveBeenCalledTimes(3);
			expect(mockCombinedZip.addFile).toHaveBeenCalledTimes(2);
			expect(mockCombinedZip.toBuffer).toHaveBeenCalled();
	
			expect(mockExecuteDeployment).toHaveBeenCalledWith(gatewayJson, mockZipBuffer);
			expect(result).toEqual({
				buildBuffer: mockZipBuffer,
				deploymentResult: mockDeploymentResult
			});
			expect(mockShowError).not.toHaveBeenCalled();
		});
		
		it('should handle errors during asset building', async () => {
		mockBuildAssets.mockRejectedValue(new Error('Build failed'));
	
		const localDir = 'mock-local-dir';
		const assetsToBuildAndDeploy = {
			'project1': 'metadata1'
		};
		const gatewayJson = { gateways: [], overwrite: 'ALL', skip: 'NONE' } as GatewaysJson;
	
		await buildAndDeployAssets(localDir, assetsToBuildAndDeploy, gatewayJson);
		expect(mockShowError).toHaveBeenCalledWith('Failed to build assets for project: project1: Build failed');
		});
	
		it('should handle errors during deployment', async () => {
		const mockZipBuffer = Buffer.from('mock-zip-data');
		const mockCombinedZip = {
			addFile: jest.fn(),
			toBuffer: jest.fn().mockReturnValue(mockZipBuffer)
		};
	
		(AdmZip as jest.Mock).mockImplementation(() => mockCombinedZip as any);
		mockBuildAssets.mockResolvedValue(Buffer.from('mock-project-zip-data'));
		mockExecuteDeployment.mockRejectedValue(new Error('Deployment failed'));
	
		const localDir = 'mock-local-dir';
		const assetsToBuildAndDeploy = {
			'project1': 'metadata1'
		};
		const gatewayJson = { gateways: [], overwrite: 'ALL', skip: 'NONE' } as GatewaysJson;
	
		await expect(buildAndDeployAssets(localDir, assetsToBuildAndDeploy, gatewayJson))
			.rejects
			.toThrow('Deployment failed');
		});
	});

	describe('formattedEndpoints', () => {
		let consoleSpy: jest.SpyInstance;
	
		beforeEach(() => {
		jest.clearAllMocks();
		consoleSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
		});

		afterEach(() => {
		consoleSpy.mockRestore();
		});
	
		it('should format endpoints into a table and log it', () => {
			const endpoints = {
			'User API': ['/users', '/users/:id'],
			'Product API': ['/products', '/products/:id'],
			};
			formattedEndpoints(endpoints);
			expect(showInfo).toHaveBeenCalledWith(APIENDPOINTS);
			const mockTableInstance = (Table as jest.Mock).mock.results[0].value;
			expect(mockTableInstance.push).toHaveBeenCalledTimes(2);
			expect(mockTableInstance.push).toHaveBeenCalledWith(['User API', '/users\n/users/:id']);
			expect(mockTableInstance.push).toHaveBeenCalledWith(['Product API', '/products\n/products/:id']);
			expect(consoleSpy).toHaveBeenCalledWith('mocked table output');
		});
	
		it('should handle empty endpoints without error', () => {
		const endpoints = {};
	
		formattedEndpoints(endpoints);
		expect(showInfo).toHaveBeenCalledWith(APIENDPOINTS);
		expect(consoleSpy).toHaveBeenCalledWith('mocked table output');
		expect(jest.mocked(Table)).toHaveBeenCalledWith({
			head: ['APIs', 'Gateway Endpoints'],
			style: {
			head: ['blue'],
			border: ['yellow'],
			},
		});
		});
	});

});