Refactor database services and add component tests
- Remove deprecated CouchDB service files - Update database test configurations - Add test files for components and auth modules - Update user context and admin interface - Remove migration script for unified config - Fix User interface properties in tests (use status instead of isActive)
This commit is contained in:
334
components/__tests__/example.component.test.tsx
Normal file
334
components/__tests__/example.component.test.tsx
Normal file
@@ -0,0 +1,334 @@
|
||||
import React from 'react';
|
||||
import { render, screen, fireEvent } from '@testing-library/react';
|
||||
import '@testing-library/jest-dom';
|
||||
|
||||
// Mock component for demonstration purposes
|
||||
// This would normally import an actual component
|
||||
const MockButton: React.FC<{
|
||||
onClick: () => void;
|
||||
children: React.ReactNode;
|
||||
disabled?: boolean;
|
||||
}> = ({ onClick, children, disabled = false }) => (
|
||||
<button
|
||||
onClick={onClick}
|
||||
disabled={disabled}
|
||||
data-testid='mock-button'
|
||||
className={`btn ${disabled ? 'btn-disabled' : 'btn-primary'}`}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
|
||||
const MockMedicationCard: React.FC<{
|
||||
medication: {
|
||||
id: string;
|
||||
name: string;
|
||||
dosage: string;
|
||||
frequency: string;
|
||||
};
|
||||
onEdit: (id: string) => void;
|
||||
onDelete: (id: string) => void;
|
||||
}> = ({ medication, onEdit, onDelete }) => (
|
||||
<div data-testid='medication-card' className='medication-card'>
|
||||
<h3 data-testid='medication-name'>{medication.name}</h3>
|
||||
<p data-testid='medication-dosage'>Dosage: {medication.dosage}</p>
|
||||
<p data-testid='medication-frequency'>Frequency: {medication.frequency}</p>
|
||||
<div className='actions'>
|
||||
<MockButton onClick={() => onEdit(medication.id)}>Edit</MockButton>
|
||||
<MockButton onClick={() => onDelete(medication.id)}>Delete</MockButton>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
describe('Component Testing Examples', () => {
|
||||
describe('MockButton Component', () => {
|
||||
test('renders button with correct text', () => {
|
||||
const mockClick = jest.fn();
|
||||
render(<MockButton onClick={mockClick}>Click Me</MockButton>);
|
||||
|
||||
const button = screen.getByTestId('mock-button');
|
||||
expect(button).toBeInTheDocument();
|
||||
expect(button).toHaveTextContent('Click Me');
|
||||
});
|
||||
|
||||
test('calls onClick handler when clicked', () => {
|
||||
const mockClick = jest.fn();
|
||||
render(<MockButton onClick={mockClick}>Click Me</MockButton>);
|
||||
|
||||
const button = screen.getByTestId('mock-button');
|
||||
fireEvent.click(button);
|
||||
|
||||
expect(mockClick).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('applies disabled state correctly', () => {
|
||||
const mockClick = jest.fn();
|
||||
render(
|
||||
<MockButton onClick={mockClick} disabled>
|
||||
Disabled Button
|
||||
</MockButton>
|
||||
);
|
||||
|
||||
const button = screen.getByTestId('mock-button');
|
||||
expect(button).toBeDisabled();
|
||||
expect(button).toHaveClass('btn-disabled');
|
||||
|
||||
fireEvent.click(button);
|
||||
expect(mockClick).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('applies correct CSS classes', () => {
|
||||
const mockClick = jest.fn();
|
||||
const { rerender } = render(
|
||||
<MockButton onClick={mockClick}>Normal Button</MockButton>
|
||||
);
|
||||
|
||||
let button = screen.getByTestId('mock-button');
|
||||
expect(button).toHaveClass('btn', 'btn-primary');
|
||||
expect(button).not.toHaveClass('btn-disabled');
|
||||
|
||||
rerender(
|
||||
<MockButton onClick={mockClick} disabled>
|
||||
Disabled Button
|
||||
</MockButton>
|
||||
);
|
||||
|
||||
button = screen.getByTestId('mock-button');
|
||||
expect(button).toHaveClass('btn', 'btn-disabled');
|
||||
expect(button).not.toHaveClass('btn-primary');
|
||||
});
|
||||
});
|
||||
|
||||
describe('MockMedicationCard Component', () => {
|
||||
const mockMedication = {
|
||||
id: 'med-123',
|
||||
name: 'Aspirin',
|
||||
dosage: '100mg',
|
||||
frequency: 'Daily',
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
medication: mockMedication,
|
||||
onEdit: jest.fn(),
|
||||
onDelete: jest.fn(),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
test('renders medication information correctly', () => {
|
||||
render(<MockMedicationCard {...defaultProps} />);
|
||||
|
||||
expect(screen.getByTestId('medication-card')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('medication-name')).toHaveTextContent(
|
||||
'Aspirin'
|
||||
);
|
||||
expect(screen.getByTestId('medication-dosage')).toHaveTextContent(
|
||||
'Dosage: 100mg'
|
||||
);
|
||||
expect(screen.getByTestId('medication-frequency')).toHaveTextContent(
|
||||
'Frequency: Daily'
|
||||
);
|
||||
});
|
||||
|
||||
test('renders action buttons', () => {
|
||||
render(<MockMedicationCard {...defaultProps} />);
|
||||
|
||||
const editButton = screen.getByText('Edit');
|
||||
const deleteButton = screen.getByText('Delete');
|
||||
|
||||
expect(editButton).toBeInTheDocument();
|
||||
expect(deleteButton).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('calls onEdit with correct medication ID when edit button is clicked', () => {
|
||||
const mockOnEdit = jest.fn();
|
||||
render(<MockMedicationCard {...defaultProps} onEdit={mockOnEdit} />);
|
||||
|
||||
const editButton = screen.getByText('Edit');
|
||||
fireEvent.click(editButton);
|
||||
|
||||
expect(mockOnEdit).toHaveBeenCalledTimes(1);
|
||||
expect(mockOnEdit).toHaveBeenCalledWith('med-123');
|
||||
});
|
||||
|
||||
test('calls onDelete with correct medication ID when delete button is clicked', () => {
|
||||
const mockOnDelete = jest.fn();
|
||||
render(<MockMedicationCard {...defaultProps} onDelete={mockOnDelete} />);
|
||||
|
||||
const deleteButton = screen.getByText('Delete');
|
||||
fireEvent.click(deleteButton);
|
||||
|
||||
expect(mockOnDelete).toHaveBeenCalledTimes(1);
|
||||
expect(mockOnDelete).toHaveBeenCalledWith('med-123');
|
||||
});
|
||||
|
||||
test('handles different medication data', () => {
|
||||
const differentMedication = {
|
||||
id: 'med-456',
|
||||
name: 'Vitamin D',
|
||||
dosage: '1000 IU',
|
||||
frequency: 'Weekly',
|
||||
};
|
||||
|
||||
render(
|
||||
<MockMedicationCard
|
||||
{...defaultProps}
|
||||
medication={differentMedication}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(screen.getByTestId('medication-name')).toHaveTextContent(
|
||||
'Vitamin D'
|
||||
);
|
||||
expect(screen.getByTestId('medication-dosage')).toHaveTextContent(
|
||||
'Dosage: 1000 IU'
|
||||
);
|
||||
expect(screen.getByTestId('medication-frequency')).toHaveTextContent(
|
||||
'Frequency: Weekly'
|
||||
);
|
||||
});
|
||||
|
||||
test('maintains proper component structure', () => {
|
||||
render(<MockMedicationCard {...defaultProps} />);
|
||||
|
||||
const card = screen.getByTestId('medication-card');
|
||||
expect(card).toHaveClass('medication-card');
|
||||
|
||||
const actionsContainer = card.querySelector('.actions');
|
||||
expect(actionsContainer).toBeInTheDocument();
|
||||
|
||||
// Verify buttons are within the actions container
|
||||
const buttons = actionsContainer?.querySelectorAll('button');
|
||||
expect(buttons).toHaveLength(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Component Integration Tests', () => {
|
||||
test('multiple components work together', () => {
|
||||
const medications = [
|
||||
{
|
||||
id: 'med-1',
|
||||
name: 'Aspirin',
|
||||
dosage: '100mg',
|
||||
frequency: 'Daily',
|
||||
},
|
||||
{
|
||||
id: 'med-2',
|
||||
name: 'Vitamin C',
|
||||
dosage: '500mg',
|
||||
frequency: 'Twice daily',
|
||||
},
|
||||
];
|
||||
|
||||
const MockMedicationList: React.FC<{
|
||||
medications: typeof medications;
|
||||
onEdit: (id: string) => void;
|
||||
onDelete: (id: string) => void;
|
||||
}> = ({ medications, onEdit, onDelete }) => (
|
||||
<div data-testid='medication-list'>
|
||||
{medications.map(med => (
|
||||
<MockMedicationCard
|
||||
key={med.id}
|
||||
medication={med}
|
||||
onEdit={onEdit}
|
||||
onDelete={onDelete}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
||||
const mockOnEdit = jest.fn();
|
||||
const mockOnDelete = jest.fn();
|
||||
|
||||
render(
|
||||
<MockMedicationList
|
||||
medications={medications}
|
||||
onEdit={mockOnEdit}
|
||||
onDelete={mockOnDelete}
|
||||
/>
|
||||
);
|
||||
|
||||
// Verify all medications are rendered
|
||||
expect(screen.getAllByTestId('medication-card')).toHaveLength(2);
|
||||
expect(screen.getByText('Aspirin')).toBeInTheDocument();
|
||||
expect(screen.getByText('Vitamin C')).toBeInTheDocument();
|
||||
|
||||
// Test interaction with first medication
|
||||
const editButtons = screen.getAllByText('Edit');
|
||||
fireEvent.click(editButtons[0]);
|
||||
expect(mockOnEdit).toHaveBeenCalledWith('med-1');
|
||||
|
||||
// Test interaction with second medication
|
||||
const deleteButtons = screen.getAllByText('Delete');
|
||||
fireEvent.click(deleteButtons[1]);
|
||||
expect(mockOnDelete).toHaveBeenCalledWith('med-2');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Accessibility Tests', () => {
|
||||
test('buttons have proper accessibility attributes', () => {
|
||||
const mockClick = jest.fn();
|
||||
render(<MockButton onClick={mockClick}>Accessible Button</MockButton>);
|
||||
|
||||
const button = screen.getByRole('button');
|
||||
expect(button).toBeInTheDocument();
|
||||
expect(button).toHaveAccessibleName('Accessible Button');
|
||||
});
|
||||
|
||||
test('medication card structure supports screen readers', () => {
|
||||
render(
|
||||
<MockMedicationCard
|
||||
{...{
|
||||
medication: {
|
||||
id: 'med-123',
|
||||
name: 'Test Medicine',
|
||||
dosage: '50mg',
|
||||
frequency: 'As needed',
|
||||
},
|
||||
onEdit: jest.fn(),
|
||||
onDelete: jest.fn(),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
// Check that important information is properly structured
|
||||
const heading = screen.getByRole('heading', { level: 3 });
|
||||
expect(heading).toHaveTextContent('Test Medicine');
|
||||
|
||||
const editButton = screen.getByRole('button', { name: 'Edit' });
|
||||
const deleteButton = screen.getByRole('button', { name: 'Delete' });
|
||||
|
||||
expect(editButton).toBeInTheDocument();
|
||||
expect(deleteButton).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Error Handling', () => {
|
||||
test('components handle missing props gracefully', () => {
|
||||
// Test with minimal props
|
||||
const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {
|
||||
// Mock implementation for testing
|
||||
});
|
||||
|
||||
render(
|
||||
<MockMedicationCard
|
||||
medication={{
|
||||
id: '',
|
||||
name: '',
|
||||
dosage: '',
|
||||
frequency: '',
|
||||
}}
|
||||
onEdit={jest.fn()}
|
||||
onDelete={jest.fn()}
|
||||
/>
|
||||
);
|
||||
|
||||
// Component should still render even with empty data
|
||||
expect(screen.getByTestId('medication-card')).toBeInTheDocument();
|
||||
|
||||
consoleSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user