A try of overhauling the frontend tests, bailed after 24h+
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import DailySummary from '../../../../src/components/stats/DailySummary';
|
||||
import { useStats } from '../../../../src/hooks/useStats';
|
||||
import { XAxis, Tooltip } from 'recharts';
|
||||
import { formatMinutes } from '../../../../src/utils/time';
|
||||
|
||||
vi.mock('../../../../src/hooks/useStats', () => ({
|
||||
useStats: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('recharts', async () => {
|
||||
const actual = await vi.importActual<typeof import('recharts')>('recharts');
|
||||
return {
|
||||
...actual,
|
||||
ResponsiveContainer: ({ children }: any) => <div data-testid="responsive-container">{children}</div>,
|
||||
BarChart: ({ children }: any) => <div data-testid="bar-chart">{children}</div>,
|
||||
XAxis: vi.fn(({ tickFormatter }) => <div data-testid="x-axis" data-tick-formatter={String(tickFormatter)} />),
|
||||
YAxis: vi.fn(() => <div data-testid="y-axis" />),
|
||||
CartesianGrid: vi.fn(),
|
||||
Tooltip: vi.fn(({ formatter }) => <div data-testid="tooltip" />),
|
||||
Bar: vi.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
describe('DailySummary', () => {
|
||||
const props = {
|
||||
from_date: '2024-01-01',
|
||||
to_date: '2024-01-02',
|
||||
day_start: '07:00',
|
||||
day_end: '20:00',
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('renders loading state', () => {
|
||||
vi.mocked(useStats).mockReturnValue({
|
||||
dailySummary: undefined,
|
||||
isLoading: true,
|
||||
} as any);
|
||||
|
||||
render(<DailySummary {...props} />);
|
||||
expect(screen.getByText(/Loading summary.../i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders empty state when dailySummary.days is undefined', () => {
|
||||
vi.mocked(useStats).mockReturnValue({
|
||||
dailySummary: undefined,
|
||||
isLoading: false,
|
||||
} as any);
|
||||
|
||||
render(<DailySummary {...props} />);
|
||||
expect(screen.getByText(/No data available for this period./i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders empty state when dailySummary.days is an empty array', () => {
|
||||
vi.mocked(useStats).mockReturnValue({
|
||||
dailySummary: { days: [] },
|
||||
isLoading: false,
|
||||
} as any);
|
||||
|
||||
render(<DailySummary {...props} />);
|
||||
expect(screen.getByText(/No data available for this period./i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders chart and average stats correctly with multiple days', () => {
|
||||
vi.mocked(useStats).mockReturnValue({
|
||||
dailySummary: {
|
||||
days: [
|
||||
{ date: '2024-01-01', total_minutes: 480, day_minutes: 240, night_minutes: 240 },
|
||||
{ date: '2024-01-02', total_minutes: 540, day_minutes: 300, night_minutes: 240 },
|
||||
],
|
||||
},
|
||||
isLoading: false,
|
||||
} as any);
|
||||
|
||||
render(<DailySummary {...props} />);
|
||||
|
||||
expect(screen.getByText(/Daily Summary/i)).toBeInTheDocument();
|
||||
|
||||
// Totals: (480 + 540) / 2 = 510 mins -> 8h 30m
|
||||
// Day: (240 + 300) / 2 = 270 mins -> 4h 30m
|
||||
// Night: (240 + 240) / 2 = 240 mins -> 4h 0m
|
||||
expect(screen.getByText(/8h 30m/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/4h 30m/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/4h 0m/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('handles single day data correctly', () => {
|
||||
vi.mocked(useStats).mockReturnValue({
|
||||
dailySummary: {
|
||||
days: [
|
||||
{ date: '2024-01-01', total_minutes: 600, day_minutes: 300, night_minutes: 300 },
|
||||
],
|
||||
},
|
||||
isLoading: false,
|
||||
} as any);
|
||||
|
||||
render(<DailySummary {...props} />);
|
||||
|
||||
expect(screen.getByText(/10h 0m/i)).toBeInTheDocument();
|
||||
const avgTimes = screen.getAllByText(/5h 0m/i);
|
||||
expect(avgTimes).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('uses correct formatters for XAxis and Tooltip', () => {
|
||||
vi.mocked(useStats).mockReturnValue({
|
||||
dailySummary: {
|
||||
days: [
|
||||
{ date: '2024-01-01', total_minutes: 480, day_minutes: 240, night_minutes: 240 },
|
||||
],
|
||||
},
|
||||
isLoading: false,
|
||||
} as any);
|
||||
|
||||
render(<DailySummary {...props} />);
|
||||
|
||||
// Check XAxis tickFormatter
|
||||
const xAxisCall = vi.mocked(XAxis).mock.calls[0][0];
|
||||
expect(xAxisCall.tickFormatter).toBeDefined();
|
||||
expect(xAxisCall.tickFormatter(10)).toBe('10h');
|
||||
expect(xAxisCall.tickFormatter(5.5)).toBe('6h');
|
||||
|
||||
// Check Tooltip formatter
|
||||
const tooltipCall = vi.mocked(Tooltip).mock.calls[0][0];
|
||||
expect(tooltipCall.formatter).toBeDefined();
|
||||
|
||||
// Test Tooltip formatter with a single number (e.g., daySleep)
|
||||
const [val1, name1] = tooltipCall.formatter(8, 'daySleep');
|
||||
expect(val1).toBe('8h 0m');
|
||||
expect(name1).toBe('Day');
|
||||
|
||||
const [val2, name2] = tooltipCall.formatter(7, 'nightSleep');
|
||||
expect(val2).toBe('7h 0m');
|
||||
expect(name2).toBe('Night');
|
||||
|
||||
// Test Tooltip formatter with an array
|
||||
const [val3, name3] = tooltipCall.formatter([10], 'daySleep');
|
||||
expect(val3).toBe('10h 0m');
|
||||
expect(name3).toBe('Day');
|
||||
|
||||
// Test Tooltip formatter with undefined/null
|
||||
const [val4, name4] = tooltipCall.formatter(undefined, 'daySleep');
|
||||
expect(val4).toBe('0m');
|
||||
expect(name4).toBe('Day');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user