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}`; }