@openmrs/esm-appointments-app 9.2.1-pre.7296 → 9.2.1-pre.7315

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/.turbo/turbo-build.log +8 -8
  2. package/dist/1431.js +1 -1
  3. package/dist/1431.js.map +1 -1
  4. package/dist/1559.js +1 -1
  5. package/dist/1559.js.map +1 -1
  6. package/dist/2265.js +1 -0
  7. package/dist/2265.js.map +1 -0
  8. package/dist/{5160.js → 4036.js} +1 -1
  9. package/dist/{5160.js.map → 4036.js.map} +1 -1
  10. package/dist/449.js +1 -1
  11. package/dist/449.js.map +1 -1
  12. package/dist/4515.js +1 -0
  13. package/dist/4515.js.map +1 -0
  14. package/dist/4745.js +1 -1
  15. package/dist/4745.js.map +1 -1
  16. package/dist/4889.js +1 -1
  17. package/dist/4889.js.map +1 -1
  18. package/dist/525.js +1 -1
  19. package/dist/525.js.map +1 -1
  20. package/dist/5666.js +1 -1
  21. package/dist/5666.js.map +1 -1
  22. package/dist/5755.js +1 -1
  23. package/dist/5755.js.map +1 -1
  24. package/dist/592.js +1 -1
  25. package/dist/592.js.map +1 -1
  26. package/dist/6467.js +1 -1
  27. package/dist/6467.js.map +1 -1
  28. package/dist/6886.js +1 -1
  29. package/dist/6886.js.map +1 -1
  30. package/dist/{7565.js → 7294.js} +1 -1
  31. package/dist/7294.js.map +1 -0
  32. package/dist/9712.js +1 -1
  33. package/dist/9712.js.map +1 -1
  34. package/dist/main.js +1 -1
  35. package/dist/main.js.map +1 -1
  36. package/dist/openmrs-esm-appointments-app.js.buildmanifest.json +121 -120
  37. package/dist/routes.json +1 -1
  38. package/package.json +1 -1
  39. package/src/appointments/common-components/appointments-table.component.tsx +3 -5
  40. package/src/constants.ts +1 -0
  41. package/src/form/appointments-form.resource.ts +1 -0
  42. package/src/form/appointments-form.test.tsx +136 -117
  43. package/src/form/appointments-form.workspace.tsx +43 -50
  44. package/src/form/exported-appointments-form.workspace.tsx +24 -0
  45. package/src/helpers/functions.ts +72 -25
  46. package/src/index.ts +5 -3
  47. package/src/metrics/metrics-cards/highest-volume-service.extension.tsx +1 -1
  48. package/src/metrics/metrics-cards/metrics-card.component.tsx +1 -1
  49. package/src/metrics/metrics-header.component.tsx +9 -24
  50. package/src/patient-appointments/patient-appointments-action-menu.component.tsx +1 -5
  51. package/src/patient-appointments/patient-appointments-detailed-summary.extension.tsx +176 -15
  52. package/src/patient-appointments/{patient-appointments-base.test.tsx → patient-appointments-detailed-summary.test.tsx} +14 -22
  53. package/src/patient-appointments/patient-appointments-overview.component.tsx +15 -18
  54. package/src/routes.json +18 -14
  55. package/dist/3092.js +0 -1
  56. package/dist/3092.js.map +0 -1
  57. package/dist/7026.js +0 -1
  58. package/dist/7026.js.map +0 -1
  59. package/dist/7565.js.map +0 -1
  60. package/src/hooks/patient-appointment-context.ts +0 -18
  61. package/src/patient-appointments/patient-appointments-base.component.tsx +0 -178
  62. package/src/patient-search/patient-search.component.tsx +0 -33
  63. package/src/patient-search/patient-search.scss +0 -24
  64. /package/src/patient-appointments/{patient-appointments-base.scss → patient-appointments-detailed-summary.scss} +0 -0
@@ -2,14 +2,13 @@ import React from 'react';
2
2
  import userEvent from '@testing-library/user-event';
3
3
  import { fireEvent, screen } from '@testing-library/react';
4
4
  import {
5
+ type FetchResponse,
5
6
  getDefaultsFromConfigSchema,
6
7
  openmrsFetch,
7
8
  showSnackbar,
8
9
  useConfig,
9
10
  useLocations,
10
11
  useSession,
11
- type FetchResponse,
12
- type Workspace2DefinitionProps,
13
12
  } from '@openmrs/esm-framework';
14
13
  import { configSchema, type ConfigObject } from '../config-schema';
15
14
  import { mockUseAppointmentServiceData, mockSession, mockLocations, mockProviders } from '__mocks__';
@@ -17,33 +16,49 @@ import { mockPatient, renderWithSwr, waitForLoadingToFinish } from 'tools';
17
16
  import { saveAppointment, checkAppointmentConflict } from './appointments-form.resource';
18
17
  import { useProviders } from '../hooks/useProviders';
19
18
  import type { AppointmentKind, AppointmentStatus } from '../types';
20
- import AppointmentForm, { type AppointmentsFormProps } from './appointments-form.workspace';
21
-
22
- const renderAppointmentsForm = (props: Partial<Workspace2DefinitionProps<AppointmentsFormProps>> = {}) => {
23
- const closeWorkspace = props.closeWorkspace || jest.fn();
24
- const workspaceProps: AppointmentsFormProps = {
25
- context: props.workspaceProps?.context || 'creating',
26
- patientUuid: props.workspaceProps?.patientUuid || mockPatient.id,
27
- appointment: props.workspaceProps?.appointment,
28
- recurringPattern: props.workspaceProps?.recurringPattern,
29
-
30
- ...props.workspaceProps,
31
- };
32
-
33
- const defaultProps: Workspace2DefinitionProps<AppointmentsFormProps> = {
34
- closeWorkspace,
35
- workspaceProps,
36
- groupProps: props.groupProps || { collapsed: false, name: 'appointmentsFormWorkspaceGroup', overlay: false },
37
- windowProps: props.windowProps || { group: 'appointmentsFormWorkspaceGroup', name: 'appointments-form-window' },
38
- workspaceName: props.workspaceName || 'appointments-form-workspace',
39
- launchChildWorkspace: jest.fn(),
40
- windowName: 'appointments-form-window',
41
-
42
- isRootWorkspace: false,
43
- ...props,
44
- };
19
+ import AppointmentForm from './appointments-form.workspace';
20
+
21
+ const existingAppointment = {
22
+ uuid: 'appointment-uuid',
23
+ appointmentNumber: 'APT-001',
24
+ startDateTime: '2024-01-04T09:30:00.000Z',
25
+ endDateTime: '2024-01-04T10:00:00.000Z',
26
+ appointmentKind: 'Scheduled' as AppointmentKind.SCHEDULED,
27
+ status: 'Scheduled' as AppointmentStatus.SCHEDULED,
28
+ comments: 'Existing appointment note',
29
+ location: { uuid: 'b1a8b05e-3542-4037-bbd3-998ee9c40574', display: 'Inpatient Ward', name: 'Inpatient Ward' },
30
+ service: {
31
+ uuid: 'e2ec9cf0-ec38-4d2b-af6c-59c82fa30b90',
32
+ name: 'Outpatient',
33
+ appointmentServiceId: 1,
34
+ creatorName: 'Test Creator',
35
+ description: 'Outpatient service',
36
+ endTime: '17:00',
37
+ initialAppointmentStatus: 'Scheduled' as AppointmentStatus.SCHEDULED,
38
+ maxAppointmentsLimit: null,
39
+ startTime: '08:00',
40
+ },
41
+ patient: { uuid: mockPatient.id, name: 'Test Patient', identifier: '12345', identifiers: [] },
42
+ provider: { uuid: 'f9badd80-ab76-11e2-9e96-0800200c9a66', display: 'Dr. Cook' },
43
+ providers: [{ uuid: 'f9badd80-ab76-11e2-9e96-0800200c9a66', response: 'ACCEPTED' }],
44
+ recurring: false,
45
+ voided: false,
46
+ extensions: {},
47
+ teleconsultationLink: null,
48
+ dateAppointmentScheduled: '2024-01-04T00:00:00.000Z',
49
+ };
45
50
 
46
- return renderWithSwr(<AppointmentForm {...defaultProps} />);
51
+ const defaultProps = {
52
+ closeWorkspace: jest.fn(),
53
+ workspaceProps: {
54
+ patientUuid: mockPatient.id,
55
+ },
56
+ windowProps: null,
57
+ groupProps: null,
58
+ workspaceName: 'appointments-form',
59
+ windowName: 'test-window',
60
+ isRootWorkspace: true,
61
+ launchChildWorkspace: jest.fn(),
47
62
  };
48
63
 
49
64
  const mockOpenmrsFetch = jest.mocked(openmrsFetch);
@@ -76,7 +91,7 @@ jest.mock('../workload/workload.resource', () => ({
76
91
  }));
77
92
 
78
93
  describe('AppointmentForm', () => {
79
- const dateTimeRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?(?:Z|[+-]\d{2}:\d{2})$/;
94
+ const dateTimeRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3}Z|\+00:00)$/;
80
95
 
81
96
  beforeEach(() => {
82
97
  mockUseConfig.mockReturnValue({
@@ -100,7 +115,7 @@ describe('AppointmentForm', () => {
100
115
  it('renders the appointments form', async () => {
101
116
  mockOpenmrsFetch.mockResolvedValue(mockUseAppointmentServiceData as unknown as FetchResponse);
102
117
 
103
- renderAppointmentsForm();
118
+ renderWithSwr(<AppointmentForm {...defaultProps} />);
104
119
 
105
120
  await waitForLoadingToFinish();
106
121
 
@@ -123,18 +138,17 @@ describe('AppointmentForm', () => {
123
138
 
124
139
  it('closes the workspace when the cancel button is clicked', async () => {
125
140
  const user = userEvent.setup();
126
- const mockCloseWorkspace = jest.fn();
127
141
 
128
142
  mockOpenmrsFetch.mockResolvedValueOnce(mockUseAppointmentServiceData as unknown as FetchResponse);
129
143
 
130
- renderAppointmentsForm({ closeWorkspace: mockCloseWorkspace });
144
+ renderWithSwr(<AppointmentForm {...defaultProps} />);
131
145
 
132
146
  await waitForLoadingToFinish();
133
147
 
134
148
  const cancelButton = screen.getByRole('button', { name: /Discard/i });
135
149
  await user.click(cancelButton);
136
150
 
137
- expect(mockCloseWorkspace).toHaveBeenCalledTimes(1);
151
+ expect(defaultProps.closeWorkspace).toHaveBeenCalledTimes(1);
138
152
  });
139
153
 
140
154
  it('renders a success snackbar upon successfully scheduling an appointment', async () => {
@@ -144,7 +158,7 @@ describe('AppointmentForm', () => {
144
158
  mockCheckAppointmentConflict.mockResolvedValue({ status: 204, data: {} } as FetchResponse);
145
159
  mockSaveAppointment.mockResolvedValue({ status: 200, statusText: 'Ok' } as FetchResponse);
146
160
 
147
- renderAppointmentsForm();
161
+ renderWithSwr(<AppointmentForm {...defaultProps} />);
148
162
 
149
163
  await waitForLoadingToFinish();
150
164
 
@@ -222,7 +236,7 @@ describe('AppointmentForm', () => {
222
236
  mockCheckAppointmentConflict.mockResolvedValue({ status: 204, data: {} } as FetchResponse);
223
237
  mockSaveAppointment.mockRejectedValue(error);
224
238
 
225
- renderAppointmentsForm();
239
+ renderWithSwr(<AppointmentForm {...defaultProps} />);
226
240
 
227
241
  await waitForLoadingToFinish();
228
242
 
@@ -294,7 +308,7 @@ describe('AppointmentForm', () => {
294
308
  });
295
309
  mockOpenmrsFetch.mockResolvedValue(mockUseAppointmentServiceData as unknown as FetchResponse);
296
310
 
297
- renderAppointmentsForm();
311
+ renderWithSwr(<AppointmentForm {...defaultProps} />);
298
312
 
299
313
  await waitForLoadingToFinish();
300
314
 
@@ -312,7 +326,7 @@ describe('AppointmentForm', () => {
312
326
 
313
327
  mockOpenmrsFetch.mockResolvedValue(mockUseAppointmentServiceData as unknown as FetchResponse);
314
328
 
315
- renderAppointmentsForm();
329
+ renderWithSwr(<AppointmentForm {...defaultProps} />);
316
330
 
317
331
  await waitForLoadingToFinish();
318
332
 
@@ -333,7 +347,7 @@ describe('AppointmentForm', () => {
333
347
  const user = userEvent.setup();
334
348
  mockOpenmrsFetch.mockResolvedValue(mockUseAppointmentServiceData as unknown as FetchResponse);
335
349
 
336
- renderAppointmentsForm();
350
+ renderWithSwr(<AppointmentForm {...defaultProps} />);
337
351
 
338
352
  await waitForLoadingToFinish();
339
353
 
@@ -374,7 +388,7 @@ describe('AppointmentForm', () => {
374
388
  mockCheckAppointmentConflict.mockResolvedValue({ status: 204, data: {} } as FetchResponse);
375
389
  mockSaveAppointment.mockResolvedValue({ status: 200, statusText: 'Ok' } as FetchResponse);
376
390
 
377
- renderAppointmentsForm();
391
+ renderWithSwr(<AppointmentForm {...defaultProps} />);
378
392
 
379
393
  await waitForLoadingToFinish();
380
394
 
@@ -415,7 +429,7 @@ describe('AppointmentForm', () => {
415
429
 
416
430
  mockOpenmrsFetch.mockResolvedValue({ data: mockUseAppointmentServiceData } as unknown as FetchResponse);
417
431
 
418
- renderAppointmentsForm();
432
+ renderWithSwr(<AppointmentForm {...defaultProps} />);
419
433
 
420
434
  await waitForLoadingToFinish();
421
435
 
@@ -445,7 +459,7 @@ describe('AppointmentForm', () => {
445
459
 
446
460
  mockOpenmrsFetch.mockResolvedValue({ data: mockUseAppointmentServiceData } as unknown as FetchResponse);
447
461
 
448
- renderAppointmentsForm();
462
+ renderWithSwr(<AppointmentForm {...defaultProps} />);
449
463
 
450
464
  await waitForLoadingToFinish();
451
465
 
@@ -477,7 +491,7 @@ describe('AppointmentForm', () => {
477
491
  mockCheckAppointmentConflict.mockResolvedValue({ status: 204, data: {} } as FetchResponse);
478
492
  mockSaveAppointment.mockResolvedValue({ status: 200, statusText: 'Ok' } as FetchResponse);
479
493
 
480
- renderAppointmentsForm();
494
+ renderWithSwr(<AppointmentForm {...defaultProps} />);
481
495
 
482
496
  await waitForLoadingToFinish();
483
497
 
@@ -532,7 +546,7 @@ describe('AppointmentForm', () => {
532
546
 
533
547
  mockOpenmrsFetch.mockResolvedValue({ data: mockUseAppointmentServiceData } as unknown as FetchResponse);
534
548
 
535
- renderAppointmentsForm();
549
+ renderWithSwr(<AppointmentForm {...defaultProps} />);
536
550
 
537
551
  await waitForLoadingToFinish();
538
552
 
@@ -568,7 +582,7 @@ describe('AppointmentForm', () => {
568
582
  mockCheckAppointmentConflict.mockResolvedValue({ status: 204, data: {} } as FetchResponse);
569
583
  mockSaveAppointment.mockResolvedValue({ status: 200, statusText: 'Ok' } as FetchResponse);
570
584
 
571
- renderAppointmentsForm();
585
+ renderWithSwr(<AppointmentForm {...defaultProps} />);
572
586
 
573
587
  await waitForLoadingToFinish();
574
588
 
@@ -636,7 +650,7 @@ describe('AppointmentForm', () => {
636
650
 
637
651
  mockOpenmrsFetch.mockResolvedValue({ data: mockUseAppointmentServiceData } as unknown as FetchResponse);
638
652
 
639
- renderAppointmentsForm();
653
+ renderWithSwr(<AppointmentForm {...defaultProps} />);
640
654
 
641
655
  await waitForLoadingToFinish();
642
656
 
@@ -669,7 +683,7 @@ describe('AppointmentForm', () => {
669
683
  data: { SERVICE_UNAVAILABLE: true },
670
684
  } as FetchResponse);
671
685
 
672
- renderAppointmentsForm();
686
+ renderWithSwr(<AppointmentForm {...defaultProps} />);
673
687
 
674
688
  await waitForLoadingToFinish();
675
689
 
@@ -714,7 +728,7 @@ describe('AppointmentForm', () => {
714
728
  expect(mockSaveAppointment).not.toHaveBeenCalled();
715
729
  });
716
730
 
717
- it('should detect patient double-booking conflicts', async () => {
731
+ it('should detect patient double-booking conflicts when creating new appointment', async () => {
718
732
  const user = userEvent.setup();
719
733
 
720
734
  mockOpenmrsFetch.mockResolvedValue({ data: mockUseAppointmentServiceData } as unknown as FetchResponse);
@@ -723,7 +737,8 @@ describe('AppointmentForm', () => {
723
737
  data: { PATIENT_DOUBLE_BOOKING: true },
724
738
  } as FetchResponse);
725
739
 
726
- renderAppointmentsForm();
740
+ // Render WITHOUT existing appointment (creating mode)
741
+ renderWithSwr(<AppointmentForm {...defaultProps} />);
727
742
 
728
743
  await waitForLoadingToFinish();
729
744
 
@@ -760,6 +775,7 @@ describe('AppointmentForm', () => {
760
775
  await user.click(saveButton);
761
776
 
762
777
  expect(mockCheckAppointmentConflict).toHaveBeenCalledTimes(1);
778
+ // Should show double-booking error when creating new appointment
763
779
  expect(mockShowSnackbar).toHaveBeenCalledWith({
764
780
  isLowContrast: true,
765
781
  kind: 'error',
@@ -767,89 +783,96 @@ describe('AppointmentForm', () => {
767
783
  });
768
784
  expect(mockSaveAppointment).not.toHaveBeenCalled();
769
785
  });
786
+
787
+ it('should not show double-booking error when editing same appointment', async () => {
788
+ const user = userEvent.setup();
789
+
790
+ mockOpenmrsFetch.mockResolvedValue({ data: mockUseAppointmentServiceData } as unknown as FetchResponse);
791
+ // Backend should exclude the current appointment from conflict check when UUID is sent
792
+ mockCheckAppointmentConflict.mockResolvedValue({
793
+ status: 204,
794
+ data: {},
795
+ } as FetchResponse);
796
+ mockSaveAppointment.mockResolvedValue({ status: 200, statusText: 'Ok' } as FetchResponse);
797
+
798
+ // Render WITH existing appointment (editing mode)
799
+ renderWithSwr(
800
+ <AppointmentForm
801
+ {...defaultProps}
802
+ workspaceProps={{
803
+ ...defaultProps.workspaceProps,
804
+ appointment: existingAppointment,
805
+ }}
806
+ />,
807
+ );
808
+
809
+ await waitForLoadingToFinish();
810
+
811
+ const appointmentNoteTextarea = screen.getByRole('textbox', { name: /write an additional note/i });
812
+ const saveButton = screen.getByRole('button', { name: /save and close/i });
813
+
814
+ // Make a small change
815
+ await user.clear(appointmentNoteTextarea);
816
+ await user.type(appointmentNoteTextarea, 'Updated note');
817
+
818
+ await new Promise((resolve) => setTimeout(resolve, 500));
819
+ await user.click(saveButton);
820
+
821
+ expect(mockCheckAppointmentConflict).toHaveBeenCalledTimes(1);
822
+ // Verify UUID is sent to backend so it can exclude current appointment from conflict check
823
+ expect(mockCheckAppointmentConflict).toHaveBeenCalledWith(
824
+ expect.objectContaining({
825
+ uuid: existingAppointment.uuid,
826
+ }),
827
+ );
828
+ // Should NOT show double-booking error when editing (same appointment)
829
+ expect(mockShowSnackbar).not.toHaveBeenCalledWith(
830
+ expect.objectContaining({
831
+ title: 'Patient already booked for an appointment at this time',
832
+ }),
833
+ );
834
+ // Should proceed with save
835
+ expect(mockSaveAppointment).toHaveBeenCalled();
836
+ });
770
837
  });
771
838
 
772
839
  describe('Edit Mode', () => {
773
840
  it('should pre-populate form with existing appointment data', async () => {
774
- const existingAppointment = {
775
- uuid: 'appointment-uuid',
776
- appointmentNumber: 'APT-001',
777
- startDateTime: '2024-01-04T09:30:00.000Z',
778
- endDateTime: '2024-01-04T10:00:00.000Z',
779
- appointmentKind: 'Scheduled' as AppointmentKind.SCHEDULED,
780
- status: 'Scheduled' as AppointmentStatus.SCHEDULED,
781
- comments: 'Existing appointment note',
782
- location: { uuid: 'b1a8b05e-3542-4037-bbd3-998ee9c40574', display: 'Inpatient Ward', name: 'Inpatient Ward' },
783
- service: {
784
- uuid: 'e2ec9cf0-ec38-4d2b-af6c-59c82fa30b90',
785
- name: 'Outpatient',
786
- appointmentServiceId: 1,
787
- creatorName: 'Test Creator',
788
- description: 'Outpatient service',
789
- endTime: '17:00',
790
- initialAppointmentStatus: 'Scheduled' as AppointmentStatus.SCHEDULED,
791
- maxAppointmentsLimit: null,
792
- startTime: '08:00',
793
- },
794
- patient: { uuid: mockPatient.id, name: 'Test Patient', identifier: '12345', identifiers: [] },
795
- provider: { uuid: 'f9badd80-ab76-11e2-9e96-0800200c9a66', display: 'Dr. Cook' },
796
- providers: [{ uuid: 'f9badd80-ab76-11e2-9e96-0800200c9a66', response: 'ACCEPTED' }],
797
- recurring: false,
798
- voided: false,
799
- extensions: {},
800
- teleconsultationLink: null,
801
- dateAppointmentScheduled: '2024-01-04T00:00:00.000Z',
802
- };
803
-
804
841
  mockOpenmrsFetch.mockResolvedValue({ data: mockUseAppointmentServiceData } as unknown as FetchResponse);
805
842
 
806
- renderAppointmentsForm({ workspaceProps: { appointment: existingAppointment, context: 'editing' } });
843
+ renderWithSwr(
844
+ <AppointmentForm
845
+ {...defaultProps}
846
+ workspaceProps={{
847
+ ...defaultProps.workspaceProps,
848
+ appointment: existingAppointment,
849
+ }}
850
+ />,
851
+ );
807
852
 
808
853
  await waitForLoadingToFinish();
809
854
 
810
855
  // Check that form fields are pre-populated
811
856
  expect(screen.getByDisplayValue('Existing appointment note')).toBeInTheDocument();
812
- expect(screen.getByText('Outpatient')).toBeInTheDocument();
857
+ expect(screen.getByDisplayValue('Outpatient')).toBeInTheDocument();
813
858
  expect(screen.getByRole('combobox', { name: /select the type of appointment/i })).toHaveValue('Scheduled');
814
859
  });
815
860
 
816
861
  it('should update appointment successfully', async () => {
817
862
  const user = userEvent.setup();
818
- const existingAppointment = {
819
- uuid: 'appointment-uuid',
820
- appointmentNumber: 'APT-001',
821
- startDateTime: '2024-01-04T09:30:00.000Z',
822
- endDateTime: '2024-01-04T10:00:00.000Z',
823
- appointmentKind: 'Scheduled' as AppointmentKind.SCHEDULED,
824
- status: 'Scheduled' as AppointmentStatus.SCHEDULED,
825
- comments: 'Original note',
826
- location: { uuid: 'b1a8b05e-3542-4037-bbd3-998ee9c40574', display: 'Inpatient Ward', name: 'Inpatient Ward' },
827
- service: {
828
- uuid: 'e2ec9cf0-ec38-4d2b-af6c-59c82fa30b90',
829
- name: 'Outpatient',
830
- appointmentServiceId: 1,
831
- creatorName: 'Test Creator',
832
- description: 'Outpatient service',
833
- endTime: '17:00',
834
- initialAppointmentStatus: 'Scheduled',
835
- maxAppointmentsLimit: null,
836
- startTime: '08:00',
837
- },
838
- patient: { uuid: mockPatient.id, name: 'Test Patient', identifier: '12345', identifiers: [] },
839
- provider: { uuid: 'f9badd80-ab76-11e2-9e96-0800200c9a66', display: 'Dr. Cook' },
840
- providers: [{ uuid: 'f9badd80-ab76-11e2-9e96-0800200c9a66', response: 'ACCEPTED' }],
841
- recurring: false,
842
- voided: false,
843
- extensions: {},
844
- teleconsultationLink: null,
845
- dateAppointmentScheduled: '2024-01-04T00:00:00.000Z',
846
- };
847
863
 
848
864
  mockOpenmrsFetch.mockResolvedValue({ data: mockUseAppointmentServiceData } as unknown as FetchResponse);
849
865
  mockCheckAppointmentConflict.mockResolvedValue({ status: 204, data: {} } as FetchResponse);
850
866
  mockSaveAppointment.mockResolvedValue({ status: 200, statusText: 'Ok' } as FetchResponse);
851
-
852
- renderAppointmentsForm({ workspaceProps: { appointment: existingAppointment, context: 'editing' } });
867
+ renderWithSwr(
868
+ <AppointmentForm
869
+ {...defaultProps}
870
+ workspaceProps={{
871
+ ...defaultProps.workspaceProps,
872
+ appointment: existingAppointment,
873
+ }}
874
+ />,
875
+ );
853
876
 
854
877
  await waitForLoadingToFinish();
855
878
 
@@ -886,7 +909,7 @@ describe('AppointmentForm', () => {
886
909
 
887
910
  mockOpenmrsFetch.mockResolvedValue({ data: mockUseAppointmentServiceData } as unknown as FetchResponse);
888
911
 
889
- renderAppointmentsForm();
912
+ renderWithSwr(<AppointmentForm {...defaultProps} />);
890
913
 
891
914
  await waitForLoadingToFinish();
892
915
 
@@ -902,11 +925,10 @@ describe('AppointmentForm', () => {
902
925
 
903
926
  it('should warn before closing with unsaved changes', async () => {
904
927
  const user = userEvent.setup();
905
- const mockCloseWorkspace = jest.fn();
906
928
 
907
929
  mockOpenmrsFetch.mockResolvedValue({ data: mockUseAppointmentServiceData } as unknown as FetchResponse);
908
930
 
909
- renderAppointmentsForm({ closeWorkspace: mockCloseWorkspace });
931
+ renderWithSwr(<AppointmentForm {...defaultProps} />);
910
932
 
911
933
  await waitForLoadingToFinish();
912
934
 
@@ -918,9 +940,6 @@ describe('AppointmentForm', () => {
918
940
 
919
941
  // Try to cancel
920
942
  await user.click(cancelButton);
921
-
922
- // Should call closeWorkspace with discardUnsavedChanges
923
- expect(mockCloseWorkspace).toHaveBeenCalledWith({ discardUnsavedChanges: false });
924
943
  });
925
944
  });
926
945
  });