import React from 'react';
import { render } from '@testing-library/react';
import StringDateTimePickerGroup from './StringDateTimePickerGroup';
import FormTestBase, { PersonDto } from '../__Tests__/FormTestBase';
//hack so the datetimepicker internals don't complain about this not existing in the context of jest
HTMLCanvasElement.prototype.getContext = () => null;
describe('StringDateTimePickerGroup', () => {
it('renders without crashing', () => {
render(
{({ Field }) => (
)}
);
});
it('has matching snapshot', () => {
const renderResult = render(
{({ Field }) => (
)}
);
expect(renderResult.asFragment()).toMatchSnapshot();
});
it('does not render with initial date-only string and throws exception', () => {
const dateOnlyString = '2024-09-04';
const personDtoWithDateOnlyString: PersonDto = {
createdDateTime: dateOnlyString,
};
try {
render(
{({ Field }) => (
)}
);
fail('Expected an exception to be thrown for date-only string');
} catch (error: any) {
// Assert that the error message matches the expected message
expect(error.message).toEqual(
`Invalid "date time" value of ${dateOnlyString} provided to DateTimePickerGroup component. Please provide ISO 8601 string that includes the time zone designator. Sample strings: 2022-09-24T:08:54:12+00:00, 2022-09-24T:08:54:12Z, 2022-09-24T:08:54:12.123-05:00`
);
}
});
it('renders with ISO UTC date time string taking browser timezone into account', () => {
const isoUTCDateTimeString = '2024-04-09T21:00:24.670Z';
const personDtoWithDateTimeString: PersonDto = {
createdDateTime: isoUTCDateTimeString,
};
render(
{({ Field }) => (
)}
);
const dateTimePickerInputComponent = document.querySelector(
'input[name="datetime"][type="datetime-local"]'
);
const utcDate = new Date(isoUTCDateTimeString);
const localDateTimeString =
convertToDateTimePickerComponentValueString(utcDate);
// Assert that no exception is thrown during rendering
expect(true).toBe(true);
// Assert the value of the component
expect(dateTimePickerInputComponent).toHaveValue(localDateTimeString);
});
it('does not render with invalid datetime ISO string and throws exception', () => {
const invalidISODateTimeString = '2024-04-11T01:00:00.000-5:00';
const personDtoWithDateOnlyString: PersonDto = {
createdDateTime: invalidISODateTimeString,
};
try {
render(
{({ Field }) => (
)}
);
fail('Expected an exception to be thrown for invalid datetime string');
} catch (error: any) {
// Assert that the error message matches the expected message
expect(error.message).toEqual(
`Invalid "date time" value of ${invalidISODateTimeString} provided to DateTimePickerGroup component. Please provide ISO 8601 string that includes the time zone designator. Sample strings: 2022-09-24T:08:54:12+00:00, 2022-09-24T:08:54:12Z, 2022-09-24T:08:54:12.123-05:00`
);
}
});
it('renders with ISO date time string with different offset than browser taking browser timezone into account', () => {
const isoDateTimeString = '2024-04-09T21:00:24.670-01:00';
const personDtoWithDateTimeString: PersonDto = {
createdDateTime: isoDateTimeString,
};
render(
{({ Field }) => (
)}
);
const dateTimePickerInputComponent = document.querySelector(
'input[name="datetime"][type="datetime-local"]'
);
const utcDate = new Date(isoDateTimeString);
const localDateTimeString =
convertToDateTimePickerComponentValueString(utcDate);
// Assert that no exception is thrown during rendering
expect(true).toBe(true);
// Assert the value of the component
expect(dateTimePickerInputComponent).toHaveValue(localDateTimeString);
});
it('renders with ISO date time string with same offset as the browser taking browser timezone into account', () => {
const isoDateTimeString = '2024-04-09T21:00:24.670-05:00';
const personDtoWithDateTimeString: PersonDto = {
createdDateTime: isoDateTimeString,
};
render(
{({ Field }) => (
)}
);
const dateTimePickerInputComponent = document.querySelector(
'input[name="datetime"][type="datetime-local"]'
);
const utcDate = new Date(isoDateTimeString);
const localDateTimeString =
convertToDateTimePickerComponentValueString(utcDate);
// Assert that no exception is thrown during rendering
expect(true).toBe(true);
// Assert the value of the component
expect(dateTimePickerInputComponent).toHaveValue(localDateTimeString);
});
});
function convertToDateTimePickerComponentValueString(date: Date): string {
// Format the date in the required format using `intl.DateTimeFormat`
const year = new Intl.DateTimeFormat('en', { year: 'numeric' })
.format(date)
.padStart(4, '0');
const month = new Intl.DateTimeFormat('en', { month: '2-digit' }).format(
date
);
const day = new Intl.DateTimeFormat('en', { day: '2-digit' }).format(date);
const hour = new Intl.DateTimeFormat('en', {
hour: '2-digit',
hourCycle: 'h23',
}).format(date);
const minute = new Intl.DateTimeFormat('en', { minute: '2-digit' })
.format(date)
.padStart(2, '0');
return `${year}-${month}-${day}T${hour}:${minute}`;
}