Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ describe("Test the MeasurementCategoryDetail component", () => {
expect(screen.getByText('Biceps')).toBeInTheDocument();

expect(screen.getByRole('gridcell', { name: /10cm/i })).toBeInTheDocument();
expect(screen.getByText(/Feb 1, 2023/i)).toBeInTheDocument();
expect(screen.getAllByText(/Feb 1, 2023/i).length).toBeGreaterThanOrEqual(1);
expect(screen.getByText('test note')).toBeInTheDocument();

expect(screen.getByRole('gridcell', { name: /20cm/i })).toBeInTheDocument();
Expand Down
74 changes: 50 additions & 24 deletions src/components/Measurements/widgets/EntryForm.test.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { render, screen, within } from '@testing-library/react';
import { render, screen } from '@testing-library/react';
import userEvent from "@testing-library/user-event";
import { MeasurementEntry } from "components/Measurements/models/Entry";
import {
useAddMeasurementEntryQuery,
useEditMeasurementEntryQuery,
useMeasurementsQuery
} from "components/Measurements/queries";
import { EntryForm } from "components/Measurements/widgets/EntryForm";
import i18n from "i18next";
import { TEST_MEASUREMENT_CATEGORY_1, TEST_MEASUREMENT_ENTRIES_1 } from "tests/measurementsTestData";

jest.mock("services/weight");
Expand All @@ -18,6 +20,14 @@ describe("Test the EntryForm component", () => {
const queryClient = new QueryClient();
let mutate = jest.fn();

const renderComponent = (props: { entry?: MeasurementEntry, categoryId: number }) => {
return render(
<QueryClientProvider client={queryClient}>
<EntryForm {...props} />
</QueryClientProvider>
);
};

beforeEach(() => {
(useMeasurementsQuery as jest.Mock).mockImplementation(() => ({
isSuccess: true,
Expand All @@ -41,14 +51,9 @@ describe("Test the EntryForm component", () => {
const entry = TEST_MEASUREMENT_ENTRIES_1[0];

// Act
render(
<QueryClientProvider client={queryClient}>
<EntryForm entry={entry} categoryId={1} />
</QueryClientProvider>
);
renderComponent({ entry, categoryId: 1 });

// Assert
expect(screen.getByDisplayValue('2023-02-01')).toBeInTheDocument();
expect(screen.getByDisplayValue('10')).toBeInTheDocument();
expect(screen.getByDisplayValue('test note')).toBeInTheDocument();
expect(screen.getAllByLabelText('date').length).toBeGreaterThan(0);
Expand All @@ -64,11 +69,7 @@ describe("Test the EntryForm component", () => {
const user = userEvent.setup();

// Act
render(
<QueryClientProvider client={queryClient}>
<EntryForm entry={entry} categoryId={1} />
</QueryClientProvider>
);
renderComponent({ entry, categoryId: 1 });
const submitButton = screen.getByRole('button', { name: 'submit' });
await user.clear(screen.getByLabelText('value'));
await user.type(screen.getByLabelText('value'), '25');
Expand All @@ -77,7 +78,7 @@ describe("Test the EntryForm component", () => {
expect(submitButton).toBeInTheDocument();
await user.click(submitButton);
expect(mutate).toHaveBeenCalledWith({
date: expect.anything(), // timezones... new Date("2023-01-31T23:00:00.000Z"),
date: expect.anything(),
id: 1,
notes: "test note",
value: 25,
Expand All @@ -86,22 +87,16 @@ describe("Test the EntryForm component", () => {

test('Creating a new entry', async () => {
// Arrange
const user = userEvent.setup();
const fakeNow = new Date(2023, 5, 18, 14, 30);
jest.useFakeTimers({ now: fakeNow.getTime() });
const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });

// Act
render(
<QueryClientProvider client={queryClient}>
<EntryForm categoryId={11} />
</QueryClientProvider>
);
const group = screen.getByRole('group', { name: /date/i });
const dateInput = within(group).getByRole('textbox', { hidden: true });
renderComponent({ categoryId: 11 });
const valueInput = await screen.findByLabelText('value');
const notesInput = await screen.findByLabelText('notes');
const submitButton = screen.getByRole('button', { name: 'submit' });

// Act
await user.type(dateInput, '2023-06-18');
await user.clear(valueInput);
await user.type(valueInput, '42.42');
await user.clear(notesInput);
Expand All @@ -112,9 +107,40 @@ describe("Test the EntryForm component", () => {
await user.click(submitButton);
expect(mutate).toHaveBeenCalledWith({
categoryId: 11,
date: expect.anything(), // timezones... new Date('2023-06-17T22:00:00.000Z')
date: fakeNow,
notes: 'The Shiba Inu is a breed of hunting dog from Japan.',
value: 42.42,
});

jest.useRealTimers();
});

describe('Localization', () => {
afterEach(() => {
i18n.changeLanguage('en');
});

test('renders date in English format', () => {
i18n.changeLanguage('en');
const entry = TEST_MEASUREMENT_ENTRIES_1[0];

const { container } = renderComponent({ entry, categoryId: 1 });

const picker = container.querySelector('.MuiPickersInputBase-root');
expect(picker?.textContent).toContain('02/01/2023');
// expect(picker?.textContent).toContain('08:00 AM');
});

test('renders date in German format', () => {
i18n.changeLanguage('de');
const entry = TEST_MEASUREMENT_ENTRIES_1[0];

const { container } = renderComponent({ entry, categoryId: 1 });

const picker = container.querySelector('.MuiPickersInputBase-root');
expect(picker?.textContent).toContain('01.02.2023');
// expect(picker?.textContent).toContain('08:00');
expect(picker?.textContent).not.toContain('AM');
});
});
});
24 changes: 4 additions & 20 deletions src/components/Measurements/widgets/EntryForm.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Button, Stack, TextField } from "@mui/material";
import { DatePicker, LocalizationProvider } from "@mui/x-date-pickers";
import { DateTimePicker, LocalizationProvider } from "@mui/x-date-pickers";
import { AdapterLuxon } from "@mui/x-date-pickers/AdapterLuxon";
import { LoadingPlaceholder } from "components/Core/LoadingWidget/LoadingWidget";
import { MeasurementEntry } from "components/Measurements/models/Entry";
Expand All @@ -13,7 +13,6 @@ import { DateTime, Settings } from "luxon";
import React from 'react';
import { useTranslation } from "react-i18next";
import { TIMEZONE } from "utils/consts";
import { dateToYYYYMMDD } from "utils/date";
import * as yup from 'yup';

Settings.defaultZone = TIMEZONE;
Expand Down Expand Up @@ -87,32 +86,17 @@ export const EntryForm = ({ entry, closeFn, categoryId }: EntryFormProps) => {
{categoryQuery.isLoading
? <LoadingPlaceholder />
: <LocalizationProvider dateAdapter={AdapterLuxon} adapterLocale={i18n.language}>
<DatePicker
format="yyyy-MM-dd"
<DateTimePicker
label={t('date')}
value={dateValue}
slotProps={{ textField: { variant: 'outlined' } }}
disableFuture={true}

onChange={(newValue) => {
if (newValue) {
formik.setFieldValue('date', newValue.toJSDate());
}
setDateValue(newValue);
}}
shouldDisableDate={(date) => {
// Allow the date of the current weight entry, since we are editing it
if (entry && dateToYYYYMMDD(entry.date) === dateToYYYYMMDD(date.toJSDate())) {
return false;
}

// if date is in list of existing entries, disable it
if (date) {
return categoryQuery.data!.entries.some(entry => dateToYYYYMMDD(entry.date) === dateToYYYYMMDD(date.toJSDate()));
}

// all other dates are allowed
return false;
}}
/>
</LocalizationProvider>}

Expand All @@ -136,4 +120,4 @@ export const EntryForm = ({ entry, closeFn, categoryId }: EntryFormProps) => {
)}
</Formik>)
);
};
};
32 changes: 16 additions & 16 deletions src/tests/measurementsTestData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,25 @@ import { MeasurementCategory } from "components/Measurements/models/Category";
import { MeasurementEntry } from "components/Measurements/models/Entry";

export const TEST_MEASUREMENT_ENTRIES_1 = [
new MeasurementEntry(1, 1, new Date(2023, 1, 1), 10, "test note"),
new MeasurementEntry(2, 1, new Date(2023, 1, 2), 20, ""),
new MeasurementEntry(3, 1, new Date(2023, 1, 3), 30, "important note"),
new MeasurementEntry(4, 1, new Date(2023, 1, 4), 40, "this day was good"),
new MeasurementEntry(5, 1, new Date(2023, 1, 5), 50, ""),
new MeasurementEntry(6, 1, new Date(2023, 1, 6), 60, ""),
new MeasurementEntry(7, 1, new Date(2023, 1, 7), 70, ""),
new MeasurementEntry(8, 1, new Date(2023, 1, 8), 80, ""),
new MeasurementEntry(1, 1, new Date(2023, 1, 1, 8, 0), 10, "test note"),
new MeasurementEntry(2, 1, new Date(2023, 1, 1, 18, 30), 12, "evening measurement"),
new MeasurementEntry(3, 1, new Date(2023, 1, 2, 7, 45), 20, ""),
new MeasurementEntry(4, 1, new Date(2023, 1, 3, 9, 15), 30, "important note"),
new MeasurementEntry(5, 1, new Date(2023, 1, 4, 12, 0), 40, "this day was good"),
new MeasurementEntry(6, 1, new Date(2023, 1, 5, 8, 0), 50, ""),
new MeasurementEntry(7, 1, new Date(2023, 1, 6, 8, 0), 60, ""),
new MeasurementEntry(8, 1, new Date(2023, 1, 7, 8, 0), 70, ""),
];

export const TEST_MEASUREMENT_ENTRIES_2 = [
new MeasurementEntry(1, 2, new Date(2023, 3, 1), 11, ""),
new MeasurementEntry(2, 2, new Date(2023, 3, 2), 22, ""),
new MeasurementEntry(3, 2, new Date(2023, 3, 3), 33, ""),
new MeasurementEntry(4, 2, new Date(2023, 3, 4), 44, ""),
new MeasurementEntry(5, 2, new Date(2023, 3, 5), 55, ""),
new MeasurementEntry(6, 2, new Date(2023, 3, 6), 66, ""),
new MeasurementEntry(7, 2, new Date(2023, 3, 7), 77, ""),
new MeasurementEntry(8, 2, new Date(2023, 3, 8), 88, ""),
new MeasurementEntry(1, 2, new Date(2023, 3, 1, 7, 0), 11, ""),
new MeasurementEntry(2, 2, new Date(2023, 3, 1, 19, 0), 13, ""),
new MeasurementEntry(3, 2, new Date(2023, 3, 2, 8, 30), 22, ""),
new MeasurementEntry(4, 2, new Date(2023, 3, 3, 9, 0), 33, ""),
new MeasurementEntry(5, 2, new Date(2023, 3, 4, 10, 15), 44, ""),
new MeasurementEntry(6, 2, new Date(2023, 3, 5, 7, 45), 55, ""),
new MeasurementEntry(7, 2, new Date(2023, 3, 6, 8, 0), 66, ""),
new MeasurementEntry(8, 2, new Date(2023, 3, 7, 8, 0), 77, ""),
];


Expand Down
Loading