NeoScan_Physician/app/modules/AIPrediction/__tests__/aiPredictionAPI.test.ts
2025-08-20 20:42:33 +05:30

362 lines
10 KiB
TypeScript

/*
* 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.
*/