362 lines
10 KiB
TypeScript
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.
|
|
*/
|