250 lines
7.8 KiB
TypeScript
250 lines
7.8 KiB
TypeScript
/*
|
|
* File: AIPredictionCard.test.tsx
|
|
* Description: Unit tests for AI Prediction Card component
|
|
* Design & Developed by Tech4Biz Solutions
|
|
* Copyright (c) Spurrin Innovations. All rights reserved.
|
|
*/
|
|
|
|
import React from 'react';
|
|
import { render, fireEvent } from '@testing-library/react-native';
|
|
import AIPredictionCard from '../components/AIPredictionCard';
|
|
import type { AIPredictionCase } from '../types';
|
|
|
|
// ============================================================================
|
|
// MOCK DATA
|
|
// ============================================================================
|
|
|
|
const mockPredictionCase: AIPredictionCase = {
|
|
patid: 'test-patient-001',
|
|
hospital_id: 'hospital-123',
|
|
prediction: {
|
|
label: 'midline shift',
|
|
finding_type: 'pathology',
|
|
clinical_urgency: 'urgent',
|
|
confidence_score: 0.96,
|
|
finding_category: 'abnormal',
|
|
primary_severity: 'high',
|
|
anatomical_location: 'brain',
|
|
},
|
|
created_at: '2024-01-15T10:30:00Z',
|
|
updated_at: '2024-01-15T10:30:00Z',
|
|
review_status: 'pending',
|
|
priority: 'critical',
|
|
};
|
|
|
|
const mockProps = {
|
|
predictionCase: mockPredictionCase,
|
|
onPress: jest.fn(),
|
|
onReview: jest.fn(),
|
|
onToggleSelect: jest.fn(),
|
|
isSelected: false,
|
|
showReviewButton: true,
|
|
};
|
|
|
|
// ============================================================================
|
|
// UNIT TESTS
|
|
// ============================================================================
|
|
|
|
describe('AIPredictionCard', () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
// ============================================================================
|
|
// RENDERING TESTS
|
|
// ============================================================================
|
|
|
|
describe('Rendering', () => {
|
|
it('should render correctly with required props', () => {
|
|
const { getByText } = render(
|
|
<AIPredictionCard
|
|
predictionCase={mockPredictionCase}
|
|
onPress={mockProps.onPress}
|
|
/>
|
|
);
|
|
|
|
expect(getByText('test-patient-001')).toBeTruthy();
|
|
expect(getByText('Midline Shift')).toBeTruthy();
|
|
expect(getByText('96%')).toBeTruthy();
|
|
expect(getByText('Urgent')).toBeTruthy();
|
|
});
|
|
|
|
it('should render review button when showReviewButton is true', () => {
|
|
const { getByText } = render(<AIPredictionCard {...mockProps} />);
|
|
expect(getByText('Review')).toBeTruthy();
|
|
});
|
|
|
|
it('should not render review button when showReviewButton is false', () => {
|
|
const { queryByText } = render(
|
|
<AIPredictionCard {...mockProps} showReviewButton={false} />
|
|
);
|
|
expect(queryByText('Review')).toBeNull();
|
|
});
|
|
|
|
it('should not render review button when status is not pending', () => {
|
|
const reviewedCase = {
|
|
...mockPredictionCase,
|
|
review_status: 'reviewed' as const,
|
|
};
|
|
|
|
const { queryByText } = render(
|
|
<AIPredictionCard
|
|
{...mockProps}
|
|
predictionCase={reviewedCase}
|
|
/>
|
|
);
|
|
expect(queryByText('Review')).toBeNull();
|
|
});
|
|
|
|
it('should render selection checkbox when onToggleSelect is provided', () => {
|
|
const { getByRole } = render(<AIPredictionCard {...mockProps} />);
|
|
expect(getByRole('checkbox')).toBeTruthy();
|
|
});
|
|
|
|
it('should show selected state correctly', () => {
|
|
const { getByRole } = render(
|
|
<AIPredictionCard {...mockProps} isSelected={true} />
|
|
);
|
|
|
|
const checkbox = getByRole('checkbox');
|
|
expect(checkbox.props.accessibilityState.checked).toBe(true);
|
|
});
|
|
});
|
|
|
|
// ============================================================================
|
|
// INTERACTION TESTS
|
|
// ============================================================================
|
|
|
|
describe('Interactions', () => {
|
|
it('should call onPress when card is pressed', () => {
|
|
const { getByRole } = render(<AIPredictionCard {...mockProps} />);
|
|
|
|
fireEvent.press(getByRole('button'));
|
|
expect(mockProps.onPress).toHaveBeenCalledWith(mockPredictionCase);
|
|
});
|
|
|
|
it('should call onReview when review button is pressed', () => {
|
|
const { getByText } = render(<AIPredictionCard {...mockProps} />);
|
|
|
|
fireEvent.press(getByText('Review'));
|
|
expect(mockProps.onReview).toHaveBeenCalledWith('test-patient-001');
|
|
});
|
|
|
|
it('should call onToggleSelect when checkbox is pressed', () => {
|
|
const { getByRole } = render(<AIPredictionCard {...mockProps} />);
|
|
|
|
fireEvent.press(getByRole('checkbox'));
|
|
expect(mockProps.onToggleSelect).toHaveBeenCalledWith('test-patient-001');
|
|
});
|
|
});
|
|
|
|
// ============================================================================
|
|
// DATA FORMATTING TESTS
|
|
// ============================================================================
|
|
|
|
describe('Data formatting', () => {
|
|
it('should format confidence score as percentage', () => {
|
|
const { getByText } = render(<AIPredictionCard {...mockProps} />);
|
|
expect(getByText('96%')).toBeTruthy();
|
|
});
|
|
|
|
it('should capitalize text correctly', () => {
|
|
const { getByText } = render(<AIPredictionCard {...mockProps} />);
|
|
expect(getByText('Midline Shift')).toBeTruthy();
|
|
expect(getByText('Pathology')).toBeTruthy();
|
|
expect(getByText('Abnormal')).toBeTruthy();
|
|
});
|
|
|
|
it('should handle missing anatomical location', () => {
|
|
const caseWithoutLocation = {
|
|
...mockPredictionCase,
|
|
prediction: {
|
|
...mockPredictionCase.prediction,
|
|
anatomical_location: 'not_applicable',
|
|
},
|
|
};
|
|
|
|
const { queryByText } = render(
|
|
<AIPredictionCard
|
|
{...mockProps}
|
|
predictionCase={caseWithoutLocation}
|
|
/>
|
|
);
|
|
|
|
// Should not render location when it's 'not_applicable'
|
|
expect(queryByText('Not Applicable')).toBeNull();
|
|
});
|
|
});
|
|
|
|
// ============================================================================
|
|
// ACCESSIBILITY TESTS
|
|
// ============================================================================
|
|
|
|
describe('Accessibility', () => {
|
|
it('should have proper accessibility labels', () => {
|
|
const { getByLabelText } = render(<AIPredictionCard {...mockProps} />);
|
|
|
|
expect(
|
|
getByLabelText('AI Prediction case for patient test-patient-001')
|
|
).toBeTruthy();
|
|
});
|
|
|
|
it('should have proper accessibility hints', () => {
|
|
const { getByRole } = render(<AIPredictionCard {...mockProps} />);
|
|
|
|
const cardButton = getByRole('button');
|
|
expect(cardButton.props.accessibilityHint).toBe(
|
|
'Tap to view detailed prediction information'
|
|
);
|
|
});
|
|
});
|
|
|
|
// ============================================================================
|
|
// EDGE CASES TESTS
|
|
// ============================================================================
|
|
|
|
describe('Edge cases', () => {
|
|
it('should handle missing dates gracefully', () => {
|
|
const caseWithoutDates = {
|
|
...mockPredictionCase,
|
|
created_at: undefined,
|
|
updated_at: undefined,
|
|
};
|
|
|
|
const { getByText } = render(
|
|
<AIPredictionCard
|
|
{...mockProps}
|
|
predictionCase={caseWithoutDates}
|
|
/>
|
|
);
|
|
|
|
expect(getByText('N/A')).toBeTruthy();
|
|
});
|
|
|
|
it('should handle emergency urgency with special styling', () => {
|
|
const emergencyCase = {
|
|
...mockPredictionCase,
|
|
prediction: {
|
|
...mockPredictionCase.prediction,
|
|
clinical_urgency: 'emergency' as const,
|
|
},
|
|
};
|
|
|
|
const { getByText } = render(
|
|
<AIPredictionCard
|
|
{...mockProps}
|
|
predictionCase={emergencyCase}
|
|
/>
|
|
);
|
|
|
|
expect(getByText('Emergency')).toBeTruthy();
|
|
});
|
|
});
|
|
});
|
|
|
|
/*
|
|
* End of File: AIPredictionCard.test.tsx
|
|
* Design & Developed by Tech4Biz Solutions
|
|
* Copyright (c) Spurrin Innovations. All rights reserved.
|
|
*/
|