import { QueryClientProvider } from "@tanstack/react-query";
import { fireEvent, render, screen, waitFor, within } from '@testing-library/react';
import userEvent from "@testing-library/user-event";
import { WeightForm } from "@/components/Weight/forms/WeightForm";
import { WeightEntry } from "@/components/Weight/models/WeightEntry";
import { useAddWeightEntryQuery, useBodyWeightQuery, useEditWeightEntryQuery } from "@/components/Weight/queries";
import React from 'react';
import { testQueryClient } from "@/tests/queryClient";
import { testWeightEntries } from "@/tests/weight/testData";
import type { Mock } from 'vitest';
vi.mock("@/components/Weight/queries");
describe("Test WeightForm component", () => {
beforeEach(() => {
(useBodyWeightQuery as Mock).mockImplementation(() => ({ isSuccess: true, data: testWeightEntries }));
});
test('Passing an existing entry renders its values in the form', () => {
// Arrange
const weightEntry = new WeightEntry(
new Date('2021-12-10 17:00'),
80,
1,
);
// Act
render(
);
// Assert
expect(screen.getByDisplayValue('12/10/2021 05:00 PM')).toBeInTheDocument();
expect(screen.getByDisplayValue('80')).toBeInTheDocument();
expect(screen.getAllByLabelText('date').length).toBeGreaterThan(0);
expect(screen.getByLabelText('weight')).toBeInTheDocument();
expect(screen.getByText('submit')).toBeInTheDocument();
});
test('Editing an existing entry', async () => {
// Arrange
const weightEntry = new WeightEntry(
new Date('2022-02-28'),
80,
1
);
// Act
render(
);
const submitButton = screen.getByRole('button', { name: 'submit' });
// Assert
expect(submitButton).toBeInTheDocument();
fireEvent.click(submitButton);
await waitFor(() => {
expect(useEditWeightEntryQuery).toHaveBeenCalled();
});
});
test('Creating a new weight entry', async () => {
// Arrange
const user = userEvent.setup();
render(
);
const group = screen.getByRole('group', { name: /date/i });
const dateInput = within(group).getByRole('textbox', { hidden: true });
const weightInput = await screen.findByLabelText('weight');
const submitButton = screen.getByRole('button', { name: 'submit' });
// Act
user.type(dateInput, '2022-02-28');
user.type(weightInput, '80');
// Assert
expect(dateInput).toBeInTheDocument();
expect(weightInput).toBeInTheDocument();
expect(submitButton).toBeInTheDocument();
await user.click(submitButton);
await waitFor(() => {
expect(useAddWeightEntryQuery).toHaveBeenCalled();
});
});
test('The weight field error state follows validity, not just touched', async () => {
// Arrange
const user = userEvent.setup();
render(
);
const weightInput = await screen.findByLabelText('weight');
// Act + Assert: an invalid value marks the touched field as error
await user.clear(weightInput);
await user.type(weightInput, '10'); // below the min of 30 kg
await user.tab();
await waitFor(() => expect(weightInput).toHaveAttribute('aria-invalid', 'true'));
// Act + Assert: correcting it to a valid value must clear the error state
await user.clear(weightInput);
await user.type(weightInput, '80');
await waitFor(() => expect(weightInput).not.toHaveAttribute('aria-invalid', 'true'));
});
});