Files
babymonitor/frontend/tests/unit/SleepButton.test.tsx
T

151 lines
5.3 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest';
import { screen, fireEvent, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom';
import SleepButton from '../../src/components/tracker/SleepButton';
import { useSleepSession } from '../../src/hooks/useSleepSession';
import { renderWithProviders } from '../test-utils';
vi.mock('../../src/hooks/useSleepSession', () => ({
useSleepSession: vi.fn(),
}));
describe('SleepButton', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('renders "Start Sleep" when no active session', async () => {
vi.mocked(useSleepSession).mockReturnValue({
activeSession: null,
isCreating: false,
isEnding: false,
} as any);
renderWithProviders(<SleepButton time="2024-01-01T12:00" />);
expect(screen.getByRole('button', { name: /Start Sleep/i })).toBeInTheDocument();
});
it('renders "Stop Sleep" when session is active', async () => {
vi.mocked(useSleepSession).mockReturnValue({
activeSession: { id: 1, start_time: '2024-01-01T12:00' },
isCreating: false,
isEnding: false,
} as any);
renderWithProviders(<SleepButton time="2024-01-01T12:00" />);
expect(screen.getByRole('button', { name: /Stop Sleep/i })).toBeInTheDocument();
});
it('calls createSession when no active session and button is clicked', async () => {
const createSessionMock = vi.fn();
vi.mocked(useSleepSession).mockReturnValue({
activeSession: null,
isCreating: false,
isEnding: false,
createSession: createSessionMock,
} as any);
renderWithProviders(<SleepButton time="2024-01-01T12:00" />);
const button = screen.getByRole('button', { name: /Start Sleep/i });
fireEvent.click(button);
await waitFor(() => expect(createSessionMock).toHaveBeenCalledWith({ start_time: '2024-01-01T12:00' }));
});
it('calls endSession when session is active and button is clicked', async () => {
const endSessionMock = vi.fn();
vi.mocked(useSleepSession).mockReturnValue({
activeSession: { id: 1, start_time: '2024-01-01T12:00' },
isCreating: false,
isEnding: false,
endSession: endSessionMock,
} as any);
renderWithProviders(<SleepButton time="2024-01-01T14:00" />);
const button = screen.getByRole('button', { name: /Stop Sleep/i });
fireEvent.click(button);
await waitFor(() => expect(endSessionMock).toHaveBeenCalledWith({ sessionId: 1, endTime: '2024-01-01T14:00' }));
});
it('handles endSession error gracefully', async () => {
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
const endSessionMock = vi.fn().mockRejectedValue(new Error('Failed to stop'));
vi.mocked(useSleepSession).mockReturnValue({
activeSession: { id: 1, start_time: '2024-01-01T12:00' },
isCreating: false,
isEnding: false,
endSession: endSessionMock,
} as any);
renderWithProviders(<SleepButton time="2024-01-01T14:00" />);
const button = screen.getByRole('button', { name: /Stop Sleep/i });
fireEvent.click(button);
await waitFor(() => expect(consoleSpy).toHaveBeenCalledWith('Failed to update sleep session:', 'Failed to stop'));
consoleSpy.mockRestore();
});
it('handles createSession error gracefully', async () => {
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
const createSessionMock = vi.fn().mockRejectedValue(new Error('Failed to start'));
vi.mocked(useSleepSession).mockReturnValue({
activeSession: null,
isCreating: false,
isEnding: false,
createSession: createSessionMock,
} as any);
renderWithProviders(<SleepButton time="2024-01-01T14:00" />);
const button = screen.getByRole('button', { name: /Start Sleep/i });
fireEvent.click(button);
await waitFor(() => expect(consoleSpy).toHaveBeenCalledWith('Failed to update sleep session:', 'Failed to start'));
consoleSpy.mockRestore();
});
it('shows alert when time is invalid', async () => {
const alertSpy = vi.spyOn(window, 'alert').mockImplementation(() => {});
vi.mocked(useSleepSession).mockReturnValue({
activeSession: null,
isCreating: false,
isEnding: false,
} as any);
renderWithProviders(<SleepButton time="" />);
const button = screen.getByRole('button', { name: /Start Sleep/i });
fireEvent.click(button);
expect(alertSpy).toHaveBeenCalledWith('Please select a valid time.');
alertSpy.mockRestore();
});
it('renders "Processing..." and disables button when isCreating is true', async () => {
vi.mocked(useSleepSession).mockReturnValue({
activeSession: null,
isCreating: true,
isEnding: false,
} as any);
renderWithProviders(<SleepButton time="2024-01-01T12:00" />);
const button = screen.getByRole('button');
expect(button).toBeDisabled();
expect(screen.getByText(/Processing.../i)).toBeInTheDocument();
});
it('renders "Processing..." and disables button when isEnding is true', async () => {
vi.mocked(useSleepSession).mockReturnValue({
activeSession: { id: 1, start_time: '2024-01-01T12:00' },
isCreating: false,
isEnding: true,
} as any);
renderWithProviders(<SleepButton time="2024-01-01T14:00" />);
const button = screen.getByRole('button');
expect(button).toBeDisabled();
expect(screen.getByText(/Processing.../i)).toBeInTheDocument();
});
});