Skip to main content
Glama
TimingInput.test.tsx8.26 kB
// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors // SPDX-License-Identifier: Apache-2.0 import type { Timing } from '@medplum/fhirtypes'; import { act, fireEvent, render, screen } from '../test-utils/render'; import type { TimingInputProps } from './TimingInput'; import { TimingInput } from './TimingInput'; describe('TimingInput', () => { const defaultProps: Pick<TimingInputProps, 'path' | 'name'> = { name: 'example', path: 'Extension.value[x]' }; test('Renders', async () => { render(<TimingInput {...defaultProps} />); expect(screen.getByText('No repeat')).toBeDefined(); expect(screen.getByText('Edit')).toBeDefined(); }); test('Open dialog', async () => { render(<TimingInput {...defaultProps} />); expect(screen.getByText('Edit')).toBeDefined(); await act(async () => { fireEvent.click(screen.getByText('Edit')); }); expect(await screen.findByText('Timing')).toBeDefined(); }); test('Cancel', async () => { const onChange = jest.fn(); render(<TimingInput {...defaultProps} onChange={onChange} />); expect(screen.getByText('Edit')).toBeDefined(); await act(async () => { fireEvent.click(screen.getByText('Edit')); }); const closeButton = await screen.findByLabelText('Close'); await act(async () => { fireEvent.click(closeButton); }); expect(onChange).not.toHaveBeenCalled(); }); test('Add repeat', async () => { const onChange = jest.fn(); render(<TimingInput {...defaultProps} defaultValue={{}} onChange={onChange} />); expect(screen.getByText('Edit')).toBeDefined(); await act(async () => { fireEvent.click(screen.getByText('Edit')); }); expect(await screen.findByText('Timing')).toBeDefined(); await act(async () => { fireEvent.click(screen.getByLabelText('Repeat')); }); await act(async () => { fireEvent.click(screen.getByText('OK')); }); expect(onChange).toHaveBeenCalledWith({ repeat: { period: 1, periodUnit: 'd' } }); }); test('Remove repeat', async () => { const onChange = jest.fn(); render( <TimingInput {...defaultProps} defaultValue={{ repeat: { period: 1, periodUnit: 'd' } }} onChange={onChange} /> ); expect(screen.getByText('Edit')).toBeDefined(); await act(async () => { fireEvent.click(screen.getByText('Edit')); }); expect(await screen.findByText('Timing')).toBeDefined(); await act(async () => { fireEvent.click(screen.getByLabelText('Repeat')); }); await act(async () => { fireEvent.click(screen.getByText('OK')); }); expect(onChange).toHaveBeenCalledWith({}); }); test('Change start', async () => { const onChange = jest.fn(); render(<TimingInput {...defaultProps} onChange={onChange} />); expect(screen.getByText('Edit')).toBeDefined(); await act(async () => { fireEvent.click(screen.getByText('Edit')); }); expect(await screen.findByText('Timing')).toBeDefined(); await act(async () => { fireEvent.change(screen.getByLabelText('Starts on'), { target: { value: '2022' } }); }); await act(async () => { fireEvent.click(screen.getByText('OK')); }); expect(onChange).toHaveBeenCalled(); }); test('Change period', async () => { const onChange = jest.fn(); render(<TimingInput {...defaultProps} onChange={onChange} />); expect(screen.getByText('Edit')).toBeDefined(); await act(async () => { fireEvent.click(screen.getByText('Edit')); }); expect(await screen.findByText('Timing')).toBeDefined(); await act(async () => { fireEvent.change(screen.getByDisplayValue('1'), { target: { value: '2' } }); }); await act(async () => { fireEvent.change(screen.getByDisplayValue('day'), { target: { value: 'mo' } }); }); await act(async () => { fireEvent.click(screen.getByText('OK')); }); expect(onChange).toHaveBeenCalledWith({ repeat: { period: 2, periodUnit: 'mo' } }); }); test('Change day of week', async () => { const onChange = jest.fn(); render(<TimingInput {...defaultProps} onChange={onChange} />); expect(screen.getByText('Edit')).toBeDefined(); await act(async () => { fireEvent.click(screen.getByText('Edit')); }); expect(await screen.findByText('Timing')).toBeDefined(); await act(async () => { fireEvent.change(screen.getByLabelText('Repeat every'), { target: { value: '1' } }); }); await act(async () => { fireEvent.change(screen.getByDisplayValue('day'), { target: { value: 'wk' } }); }); // Add Monday await act(async () => { fireEvent.click(screen.getByLabelText('M')); }); // Remove Monday await act(async () => { fireEvent.click(screen.getByLabelText('M')); }); // Add Wednesday await act(async () => { fireEvent.click(screen.getByLabelText('W')); }); await act(async () => { fireEvent.click(screen.getByText('OK')); }); expect(onChange).toHaveBeenCalledWith({ repeat: { period: 1, periodUnit: 'wk', dayOfWeek: ['wed'] } }); // re-opening the modal should display the selected dayOfWeek await act(async () => { fireEvent.click(screen.getByText('Edit')); }); const node = await screen.getByLabelText('W'); expect(node).toHaveProperty('checked', true); }); test('Change repeat.timeOfDay', async () => { const onChange = jest.fn(); render(<TimingInput {...defaultProps} onChange={onChange} />); expect(screen.getByText('Edit')).toBeDefined(); await act(async () => { fireEvent.click(screen.getByText('Edit')); }); expect(await screen.findByText('Timing')).toBeDefined(); await act(async () => { fireEvent.change(screen.getByLabelText('Repeat every'), { target: { value: '1' } }); fireEvent.change(screen.getByDisplayValue('day'), { target: { value: 'wk' } }); }); // Add 3x Time of Day await act(async () => { fireEvent.click(screen.getByText('Add Time of Day')); fireEvent.click(screen.getByText('Add Time of Day')); fireEvent.click(screen.getByText('Add Time of Day')); }); expect(await screen.getByTestId('timing-repeat-timeOfDay-input-0')).toBeDefined(); expect(await screen.getByTestId('timing-repeat-timeOfDay-input-1')).toBeDefined(); expect(await screen.getByTestId('timing-repeat-timeOfDay-input-2')).toBeDefined(); await act(async () => { fireEvent.change(screen.getByTestId('timing-repeat-timeOfDay-input-0'), { target: { value: '10:00' } }); fireEvent.change(screen.getByTestId('timing-repeat-timeOfDay-input-1'), { target: { value: '12:00' } }); fireEvent.change(screen.getByTestId('timing-repeat-timeOfDay-input-2'), { target: { value: '14:00' } }); }); // Remove middle item await act(async () => { fireEvent.click(screen.getByTestId('timing-repeat-timeOfDay-remove-1')); }); // Close modal and trigger `onChange` await act(async () => { fireEvent.click(screen.getByText('OK')); }); expect(onChange).toHaveBeenCalledWith({ repeat: { period: 1, periodUnit: 'wk', timeOfDay: ['10:00:00', '14:00:00'] }, }); }); test('Loading a complex timing into the editor', async () => { const timing: Timing = { repeat: { period: 1, periodUnit: 'wk', dayOfWeek: ['mon', 'wed'], timeOfDay: ['08:00:00', '14:30:55'], }, }; render(<TimingInput {...defaultProps} defaultValue={timing} />); expect(screen.getByTestId('timinginput-display')).toHaveTextContent('Weekly on Mon, Wed at 8:00 AM, 2:30:55 PM'); expect(screen.getByText('Edit')).toBeDefined(); await act(async () => { fireEvent.click(screen.getByText('Edit')); }); expect(await screen.findByText('Timing')).toBeDefined(); const checkboxes = await screen.getAllByRole('checkbox', { checked: true }); expect(checkboxes.map((cb) => cb.getAttribute('value'))).toEqual(['mon', 'wed']); const timeOfDay = await screen.getAllByTestId(/timing-repeat-timeOfDay-input/); expect(timeOfDay.map((i) => i.getAttribute('value'))).toEqual(['08:00', '14:30']); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/medplum/medplum'

If you have feedback or need assistance with the MCP directory API, please join our Discord server