Skip to content

Commit 6fac8fc

Browse files
committed
Add expiration date format tests
Add test coverage to verify expiration dates are sent as YYYY-MM-DD date-only strings to prevent timezone conversion bugs.
1 parent a362b6b commit 6fac8fc

File tree

1 file changed

+101
-2
lines changed

1 file changed

+101
-2
lines changed

packages/esm-patient-immunizations-app/src/immunizations/immunizations-form.test.tsx

Lines changed: 101 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,11 @@ describe('Immunizations Form', () => {
114114
mockToDateObjectStrict.mockImplementation((dateString) => dayjs(dateString, isoFormat).toDate());
115115
});
116116

117-
it('should render ImmunizationsForm component', () => {
117+
it('should render ImmunizationsForm component', async () => {
118118
render(<ImmunizationsForm {...testProps} />);
119119

120-
expect(screen.getByLabelText(/vaccination date/i)).toBeInTheDocument();
120+
await screen.findByLabelText(/vaccination date/i);
121+
121122
expect(screen.getByRole('combobox', { name: /Immunization/i })).toBeInTheDocument();
122123
expect(screen.getByRole('textbox', { name: /note/i })).toBeInTheDocument();
123124
expect(screen.getByText(/Vaccine Batch Information/i)).toBeInTheDocument();
@@ -317,9 +318,61 @@ describe('Immunizations Form', () => {
317318
});
318319
});
319320

321+
it('should save new immunization with expiration date in correct format', async () => {
322+
const user = userEvent.setup();
323+
324+
// Pre-populate form with expiration date using the form subscription (same pattern as edit tests)
325+
const immunizationWithExpiration = {
326+
vaccineUuid: '782AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
327+
vaccinationDate: new Date('2024-06-15').toISOString(),
328+
doseNumber: 1,
329+
expirationDate: new Date('2025-12-31').toISOString(),
330+
manufacturer: 'Pfizer',
331+
lotNumber: 'LOT123',
332+
note: '',
333+
nextDoseDate: null,
334+
};
335+
336+
immunizationFormSub.next(immunizationWithExpiration);
337+
338+
mockSavePatientImmunization.mockResolvedValue({
339+
status: 201,
340+
ok: true,
341+
data: {
342+
id: 'new-immunization-id',
343+
},
344+
});
345+
346+
render(<ImmunizationsForm {...testProps} />);
347+
348+
// Verify the form is populated
349+
const expirationDateField = screen.getByRole('textbox', { name: /Expiration date/i });
350+
expect(expirationDateField).toHaveValue('31/12/2025');
351+
352+
// Submit without making changes
353+
const saveButton = screen.getByRole('button', { name: /Save/i });
354+
await user.click(saveButton);
355+
356+
// Verify that expirationDate is formatted as YYYY-MM-DD without timezone
357+
expect(mockSavePatientImmunization).toHaveBeenCalledWith(
358+
expect.objectContaining({
359+
expirationDate: '2025-12-31', // Date-only format, not ISO string with time/timezone
360+
lotNumber: 'LOT123',
361+
manufacturer: { display: 'Pfizer' },
362+
}),
363+
undefined,
364+
expect.any(AbortController),
365+
);
366+
});
367+
320368
it('should format expiration date as date-only string without timezone', async () => {
321369
const user = userEvent.setup();
322370

371+
// Regression test for O3-4970:
372+
// Previously, expiration dates were converted to ISO strings with timezone (e.g., "2025-12-31T00:00:00.000Z"),
373+
// causing a one-day shift for users in timezones ahead of UTC. This test ensures dates are sent as
374+
// date-only strings (e.g., "2025-12-31") per FHIR date type specification, preventing timezone conversion.
375+
323376
// Setup immunization with expiration date
324377
const immunizationWithExpiration = {
325378
vaccineUuid: '782AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
@@ -362,6 +415,52 @@ describe('Immunizations Form', () => {
362415
expect.any(AbortController),
363416
);
364417
});
418+
419+
it('should preserve date format when submitting immunization with different expiration date', async () => {
420+
const user = userEvent.setup();
421+
422+
// Load existing immunization with a different expiration date
423+
const immunizationToEdit = {
424+
vaccineUuid: '782AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
425+
immunizationId: 'existing-immunization-id',
426+
vaccinationDate: new Date('2024-06-15').toISOString(),
427+
doseNumber: 1,
428+
expirationDate: new Date('2026-06-15').toISOString(),
429+
manufacturer: 'Moderna',
430+
lotNumber: 'ABC123',
431+
note: 'Initial note',
432+
nextDoseDate: null,
433+
};
434+
435+
immunizationFormSub.next(immunizationToEdit);
436+
437+
mockSavePatientImmunization.mockResolvedValue({
438+
status: 201,
439+
ok: true,
440+
data: {
441+
id: immunizationToEdit.immunizationId,
442+
},
443+
});
444+
445+
render(<ImmunizationsForm {...testProps} />);
446+
447+
// Verify expiration date is displayed
448+
const expirationDateField = screen.getByRole('textbox', { name: /Expiration date/i });
449+
expect(expirationDateField).toHaveValue('15/06/2026');
450+
451+
// Submit the form
452+
const saveButton = screen.getByRole('button', { name: /Save/i });
453+
await user.click(saveButton);
454+
455+
// Verify the date is sent in correct format (YYYY-MM-DD, not ISO string)
456+
expect(mockSavePatientImmunization).toHaveBeenCalledWith(
457+
expect.objectContaining({
458+
expirationDate: '2026-06-15', // Date-only format, not ISO string with time/timezone
459+
}),
460+
immunizationToEdit.immunizationId,
461+
expect.any(AbortController),
462+
);
463+
});
365464
});
366465

367466
async function selectOption(dropdown: HTMLElement, optionLabel: string) {

0 commit comments

Comments
 (0)