import { render, screen, waitFor, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { WorkoutSession } from "@/components/Routines/models/WorkoutSession";
import { useAddSessionQuery, useEditSessionQuery, useFindSessionQuery } from "@/components/Routines/queries";
import { DateTime } from 'luxon';
import { BrowserRouter } from "react-router-dom";
import { SessionForm } from './SessionForm';
import type { Mock } from 'vitest';
vi.mock("@/components/Routines/queries");
const mockUseFindSessionQuery = useFindSessionQuery as Mock;
const mockUseAddSessionQuery = useAddSessionQuery as Mock;
const mockUseEditSessionQuery = useEditSessionQuery as Mock;
describe('SessionForm', () => {
const routineId = 1;
const dayId = 2;
beforeEach(() => {
mockUseFindSessionQuery.mockClear();
mockUseAddSessionQuery.mockReturnValue({
data: null,
isPending: false,
});
mockUseEditSessionQuery.mockReturnValue({
data: null,
isPending: false,
});
});
test('calls useFindSessionQuery with the correct parameters when the date changes', async () => {
// Arrange
const user = userEvent.setup();
const mockSession = new WorkoutSession({
id: 'bbbbbbbb-bbbb-bbbb-bbbb-000000000000',
dayId: 0,
routineId: 0,
date: new Date(),
notes: '',
impression: "1",
timeStart: null,
timeEnd: null
});
mockUseFindSessionQuery.mockReturnValue({
data: mockSession,
isLoading: false,
isSuccess: true
});
// Act
render(
{
}} />
);
// Assert
const datePicker = screen.getByRole('group', { name: /date/i });
const newDate = DateTime.now();
await user.type(datePicker, newDate.toFormat('yyyy-MM-dd'));
await user.tab();
expect(mockUseFindSessionQuery).toHaveBeenCalledWith(
1,
{
routine: routineId,
date: newDate.toFormat('yyyy-MM-dd'),
day: 2
}
);
});
test('updates the form values when a session is found', async () => {
// Arrange
const date = DateTime.now();
const formattedDate = new Date().toLocaleDateString(
'en-us',
{ year: 'numeric', month: '2-digit', day: '2-digit' }
);
const timeStart = DateTime.now().set({ hour: 10, minute: 30 });
const timeStartFormatted = timeStart.toLocaleString(DateTime.TIME_SIMPLE, { locale: 'en-us' });
const timeEnd = DateTime.now().set({ hour: 11, minute: 0 });
const timeEndFormatted = timeEnd.toLocaleString(DateTime.TIME_SIMPLE, { locale: 'en-us' });
const mockSession = new WorkoutSession({
id: 'bbbbbbbb-bbbb-bbbb-bbbb-000000000001',
dayId: dayId,
routineId: routineId,
date: date.toJSDate(),
notes: 'Test notes',
impression: '3',
timeStart: timeStart.toJSDate(),
timeEnd: timeEnd.toJSDate()
});
mockUseFindSessionQuery.mockReturnValue({
data: mockSession,
isLoading: false,
isSuccess: true
});
// Act
render(
{
}} />
);
// Assert
await waitFor(() => {
// screen.logTestingPlaygroundURL();
expect((screen.getByRole('textbox', { name: /notes/i }) as HTMLTextAreaElement).value).toBe('Test notes');
// The date and time pickers are localized
const dateGroup = screen.getByRole('group', { name: /date/i });
expect(within(dateGroup).getByRole('textbox', { hidden: true })).toHaveValue(formattedDate);
const startGroup = screen.getByRole('group', { name: /start/i });
expect(within(startGroup).getByRole('textbox', { hidden: true })).toHaveValue(timeStartFormatted);
const endGroup = screen.getByRole('group', { name: /end/i });
expect(within(endGroup).getByRole('textbox', { hidden: true })).toHaveValue(timeEndFormatted);
});
});
test('sets default values when no session is found', async () => {
mockUseFindSessionQuery.mockReturnValue({
data: null,
isLoading: false,
isSuccess: true,
});
render(
{
}} />
);
await waitFor(() => {
expect((screen.getByRole('textbox', { name: /notes/i }) as HTMLTextAreaElement).value).toBe('');
});
});
});