/* * File: aiPredictionAPI.test.ts * Description: Unit tests for AI Prediction API service * Design & Developed by Tech4Biz Solutions * Copyright (c) Spurrin Innovations. All rights reserved. */ import { aiPredictionAPI } from '../services/aiPredictionAPI'; // Mock apisauce jest.mock('apisauce', () => ({ create: jest.fn(() => ({ get: jest.fn(), post: jest.fn(), put: jest.fn(), delete: jest.fn(), })), })); // Mock API utilities jest.mock('../../../shared/utils', () => ({ API_CONFIG: { BASE_URL: 'https://test-api.com', }, buildHeaders: jest.fn((options = {}) => ({ headers: { 'Content-Type': 'application/json', ...(options.token && { Authorization: `Bearer ${options.token}` }), }, })), })); // ============================================================================ // MOCK DATA // ============================================================================ const mockToken = 'test-token-123'; const mockResponse = { ok: true, data: { success: true, data: [ { patid: 'test-001', hospital_id: 'hospital-001', prediction: { label: 'test finding', finding_type: 'pathology', clinical_urgency: 'urgent', confidence_score: 0.95, finding_category: 'abnormal', primary_severity: 'high', anatomical_location: 'brain', }, }, ], }, }; // ============================================================================ // UNIT TESTS // ============================================================================ describe('AI Prediction API', () => { let mockApi: any; beforeEach(() => { // Reset mocks jest.clearAllMocks(); // Get the mocked API instance const { create } = require('apisauce'); mockApi = create(); }); // ============================================================================ // GET ALL PREDICTIONS TESTS // ============================================================================ describe('getAllPredictions', () => { it('should call GET endpoint with correct parameters', async () => { mockApi.get.mockResolvedValue(mockResponse); const params = { page: 1, limit: 20, urgency: 'urgent', search: 'test', }; await aiPredictionAPI.getAllPredictions(mockToken, params); expect(mockApi.get).toHaveBeenCalledWith( '/api/ai-cases/all-prediction-results', params, expect.objectContaining({ headers: expect.objectContaining({ Authorization: `Bearer ${mockToken}`, }), }) ); }); it('should call GET endpoint without parameters', async () => { mockApi.get.mockResolvedValue(mockResponse); await aiPredictionAPI.getAllPredictions(mockToken); expect(mockApi.get).toHaveBeenCalledWith( '/api/ai-cases/all-prediction-results', {}, expect.objectContaining({ headers: expect.objectContaining({ Authorization: `Bearer ${mockToken}`, }), }) ); }); }); // ============================================================================ // GET CASE DETAILS TESTS // ============================================================================ describe('getCaseDetails', () => { it('should call GET endpoint with correct case ID', async () => { const caseId = 'test-case-001'; mockApi.get.mockResolvedValue(mockResponse); await aiPredictionAPI.getCaseDetails(caseId, mockToken); expect(mockApi.get).toHaveBeenCalledWith( `/api/ai-cases/prediction-details/${caseId}`, {}, expect.objectContaining({ headers: expect.objectContaining({ Authorization: `Bearer ${mockToken}`, }), }) ); }); }); // ============================================================================ // UPDATE CASE REVIEW TESTS // ============================================================================ describe('updateCaseReview', () => { it('should call PUT endpoint with correct data', async () => { const caseId = 'test-case-001'; const reviewData = { review_status: 'reviewed' as const, reviewed_by: 'Dr. Test', review_notes: 'Test notes', priority: 'high' as const, }; mockApi.put.mockResolvedValue(mockResponse); await aiPredictionAPI.updateCaseReview(caseId, reviewData, mockToken); expect(mockApi.put).toHaveBeenCalledWith( `/api/ai-cases/review/${caseId}`, reviewData, expect.objectContaining({ headers: expect.objectContaining({ Authorization: `Bearer ${mockToken}`, }), }) ); }); }); // ============================================================================ // GET STATISTICS TESTS // ============================================================================ describe('getPredictionStats', () => { it('should call GET endpoint with time range parameter', async () => { mockApi.get.mockResolvedValue(mockResponse); await aiPredictionAPI.getPredictionStats(mockToken, 'week'); expect(mockApi.get).toHaveBeenCalledWith( '/api/ai-cases/statistics', { timeRange: 'week' }, expect.objectContaining({ headers: expect.objectContaining({ Authorization: `Bearer ${mockToken}`, }), }) ); }); it('should call GET endpoint without time range parameter', async () => { mockApi.get.mockResolvedValue(mockResponse); await aiPredictionAPI.getPredictionStats(mockToken); expect(mockApi.get).toHaveBeenCalledWith( '/api/ai-cases/statistics', {}, expect.objectContaining({ headers: expect.objectContaining({ Authorization: `Bearer ${mockToken}`, }), }) ); }); }); // ============================================================================ // SEARCH PREDICTIONS TESTS // ============================================================================ describe('searchPredictions', () => { it('should call GET endpoint with search query and filters', async () => { const query = 'test search'; const filters = { urgency: ['urgent', 'emergency'], severity: ['high'], dateRange: { start: '2024-01-01', end: '2024-01-31' }, }; mockApi.get.mockResolvedValue(mockResponse); await aiPredictionAPI.searchPredictions(query, mockToken, filters); expect(mockApi.get).toHaveBeenCalledWith( '/api/ai-cases/search', { q: query, filters: JSON.stringify(filters), }, expect.objectContaining({ headers: expect.objectContaining({ Authorization: `Bearer ${mockToken}`, }), }) ); }); it('should call GET endpoint with only search query', async () => { const query = 'test search'; mockApi.get.mockResolvedValue(mockResponse); await aiPredictionAPI.searchPredictions(query, mockToken); expect(mockApi.get).toHaveBeenCalledWith( '/api/ai-cases/search', { q: query }, expect.objectContaining({ headers: expect.objectContaining({ Authorization: `Bearer ${mockToken}`, }), }) ); }); }); // ============================================================================ // BULK OPERATIONS TESTS // ============================================================================ describe('bulkUpdateReviews', () => { it('should call PUT endpoint with case IDs and review data', async () => { const caseIds = ['case-001', 'case-002', 'case-003']; const reviewData = { review_status: 'reviewed' as const, reviewed_by: 'Dr. Test', review_notes: 'Bulk review', }; mockApi.put.mockResolvedValue(mockResponse); await aiPredictionAPI.bulkUpdateReviews(caseIds, reviewData, mockToken); expect(mockApi.put).toHaveBeenCalledWith( '/api/ai-cases/bulk-review', { caseIds, reviewData }, expect.objectContaining({ headers: expect.objectContaining({ Authorization: `Bearer ${mockToken}`, }), }) ); }); }); // ============================================================================ // SUBMIT FEEDBACK TESTS // ============================================================================ describe('submitPredictionFeedback', () => { it('should call POST endpoint with feedback data', async () => { const caseId = 'test-case-001'; const feedbackData = { accuracy_rating: 4 as const, is_accurate: true, physician_diagnosis: 'Confirmed midline shift', feedback_notes: 'Accurate prediction', improvement_suggestions: 'None', }; mockApi.post.mockResolvedValue(mockResponse); await aiPredictionAPI.submitPredictionFeedback(caseId, feedbackData, mockToken); expect(mockApi.post).toHaveBeenCalledWith( `/api/ai-cases/feedback/${caseId}`, feedbackData, expect.objectContaining({ headers: expect.objectContaining({ Authorization: `Bearer ${mockToken}`, }), }) ); }); }); // ============================================================================ // ERROR HANDLING TESTS // ============================================================================ describe('Error handling', () => { it('should handle API errors gracefully', async () => { const errorResponse = { ok: false, problem: 'NETWORK_ERROR', data: null, }; mockApi.get.mockResolvedValue(errorResponse); const result = await aiPredictionAPI.getAllPredictions(mockToken); expect(result).toEqual(errorResponse); }); it('should handle missing token', async () => { mockApi.get.mockResolvedValue(mockResponse); await aiPredictionAPI.getAllPredictions(''); expect(mockApi.get).toHaveBeenCalledWith( '/api/ai-cases/all-prediction-results', {}, expect.objectContaining({ headers: expect.objectContaining({ 'Content-Type': 'application/json', }), }) ); }); }); }); /* * End of File: aiPredictionAPI.test.ts * Design & Developed by Tech4Biz Solutions * Copyright (c) Spurrin Innovations. All rights reserved. */