Files
maternal-app/maternal-web/__tests__/components/analytics/WeeklySleepChart.test.tsx
2025-10-01 19:01:52 +00:00

162 lines
4.0 KiB
TypeScript

import { render, screen, waitFor } from '@testing-library/react';
import WeeklySleepChart from '@/components/analytics/WeeklySleepChart';
import apiClient from '@/lib/api/client';
jest.mock('@/lib/api/client');
const mockApiClient = apiClient as jest.Mocked<typeof apiClient>;
describe('WeeklySleepChart', () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('should render loading state initially', () => {
mockApiClient.get.mockImplementation(() => new Promise(() => {}));
render(<WeeklySleepChart />);
expect(screen.getByRole('progressbar')).toBeInTheDocument();
});
it('should render sleep data successfully', async () => {
const mockSleepData = [
{
id: 'slp_1',
startTime: new Date('2024-01-01T20:00:00Z').toISOString(),
endTime: new Date('2024-01-02T06:00:00Z').toISOString(),
duration: 600, // 10 hours
quality: 4,
},
{
id: 'slp_2',
startTime: new Date('2024-01-02T20:00:00Z').toISOString(),
endTime: new Date('2024-01-03T07:00:00Z').toISOString(),
duration: 660, // 11 hours
quality: 5,
},
];
mockApiClient.get.mockResolvedValueOnce({
data: {
data: mockSleepData,
},
});
render(<WeeklySleepChart />);
await waitFor(() => {
expect(screen.getByText('Weekly Sleep Patterns')).toBeInTheDocument();
});
expect(screen.getByText('Total Sleep Hours')).toBeInTheDocument();
expect(screen.getByText('Sleep Quality Trend')).toBeInTheDocument();
});
it('should handle API error gracefully', async () => {
mockApiClient.get.mockRejectedValueOnce({
response: {
data: {
message: 'Failed to fetch sleep data',
},
},
});
render(<WeeklySleepChart />);
await waitFor(() => {
expect(screen.getByRole('alert')).toBeInTheDocument();
expect(screen.getByText('Failed to fetch sleep data')).toBeInTheDocument();
});
});
it('should aggregate sleep data by day', async () => {
const mockSleepData = [
{
id: 'slp_1',
startTime: new Date('2024-01-01T20:00:00Z').toISOString(),
duration: 600, // Night sleep
quality: 4,
},
{
id: 'slp_2',
startTime: new Date('2024-01-01T14:00:00Z').toISOString(),
duration: 120, // Nap
quality: 3,
},
];
mockApiClient.get.mockResolvedValueOnce({
data: {
data: mockSleepData,
},
});
render(<WeeklySleepChart />);
await waitFor(() => {
expect(mockApiClient.get).toHaveBeenCalledWith(
'/api/v1/activities/sleep',
expect.objectContaining({
params: expect.objectContaining({
startDate: expect.any(String),
endDate: expect.any(String),
}),
})
);
});
});
it('should display 7 days of data', async () => {
mockApiClient.get.mockResolvedValueOnce({
data: {
data: [],
},
});
render(<WeeklySleepChart />);
await waitFor(() => {
expect(screen.getByText('Weekly Sleep Patterns')).toBeInTheDocument();
});
// Chart should request exactly 7 days of data
expect(mockApiClient.get).toHaveBeenCalledWith(
'/api/v1/activities/sleep',
expect.objectContaining({
params: expect.any(Object),
})
);
});
it('should calculate quality average correctly', async () => {
const mockSleepData = [
{
id: 'slp_1',
startTime: new Date('2024-01-01T20:00:00Z').toISOString(),
duration: 600,
quality: 4,
},
{
id: 'slp_2',
startTime: new Date('2024-01-01T14:00:00Z').toISOString(),
duration: 120,
quality: 2,
},
];
mockApiClient.get.mockResolvedValueOnce({
data: {
data: mockSleepData,
},
});
render(<WeeklySleepChart />);
await waitFor(() => {
expect(screen.getByText('Sleep Quality Trend')).toBeInTheDocument();
});
// Average quality should be (4 + 2) / 2 = 3
});
});