@openmrs/esm-fast-data-entry-app 1.4.2-pre.728 → 1.4.2-pre.736

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.
@@ -1563,9 +1563,9 @@
1563
1563
  "entry": false,
1564
1564
  "recorded": false,
1565
1565
  "reason": "split chunk (cache group: defaultVendors)",
1566
- "size": 3145073,
1566
+ "size": 3147823,
1567
1567
  "sizes": {
1568
- "javascript": 3145073
1568
+ "javascript": 3147823
1569
1569
  },
1570
1570
  "names": [],
1571
1571
  "idHints": [
@@ -1581,7 +1581,7 @@
1581
1581
  "auxiliaryFiles": [
1582
1582
  "9108.js.map"
1583
1583
  ],
1584
- "hash": "27d23081f0696640",
1584
+ "hash": "496ab30cbbad651a",
1585
1585
  "childrenByOrder": {}
1586
1586
  },
1587
1587
  {
package/dist/routes.json CHANGED
@@ -1 +1 @@
1
- {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"fhir2":">=1.2","webservices.rest":">=2.2.0"},"pages":[{"component":"root","routeRegex":"forms","online":true,"offline":true}],"extensions":[{"name":"forms-app-link","slot":"app-menu-slot","component":"formsAppMenuLink","online":true,"offline":true}],"version":"1.4.2-pre.728"}
1
+ {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"fhir2":">=1.2","webservices.rest":">=2.2.0"},"pages":[{"component":"root","routeRegex":"forms","online":true,"offline":true}],"extensions":[{"name":"forms-app-link","slot":"app-menu-slot","component":"formsAppMenuLink","online":true,"offline":true}],"version":"1.4.2-pre.736"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openmrs/esm-fast-data-entry-app",
3
- "version": "1.4.2-pre.728",
3
+ "version": "1.4.2-pre.736",
4
4
  "license": "MPL-2.0",
5
5
  "description": "O3 frontend module for fast data entry using the OpenMRS Angular Form Engine",
6
6
  "browser": "dist/openmrs-esm-fast-data-entry-app.js",
@@ -14,9 +14,10 @@
14
14
  "lint": "eslint \"src/**/*.ts\" \"src/**/*.tsx\" --fix --max-warnings=0",
15
15
  "prettier": "prettier --write \"src/**/*.{ts,tsx}\" --list-different",
16
16
  "typescript": "tsc",
17
- "test": "jest --config jest.config.json --passWithNoTests",
17
+ "test": "cross-env TZ=UTC vitest run --passWithNoTests",
18
+ "test:watch": "cross-env TZ=UTC vitest watch",
18
19
  "verify": "turbo lint typescript test",
19
- "coverage": "yarn test -- --coverage ",
20
+ "coverage": "cross-env TZ=UTC vitest run --coverage --passWithNoTests",
20
21
  "postinstall": "husky install",
21
22
  "extract-translations": "i18next 'src/**/*.tsx' --config ./tools/i18next-parser.config.js",
22
23
  "test-e2e": "playwright test"
@@ -55,29 +56,26 @@
55
56
  "@playwright/test": "^1.50.1",
56
57
  "@swc-node/loader": "^1.3.7",
57
58
  "@swc/core": "^1.3.84",
58
- "@swc/jest": "^0.2.29",
59
- "@testing-library/dom": "^7.31.2",
60
- "@testing-library/jest-dom": "^5.17.0",
61
- "@testing-library/react": "^13.4.0",
59
+ "@testing-library/dom": "^10.4.1",
60
+ "@testing-library/jest-dom": "^6.8.0",
61
+ "@testing-library/react": "^16.3.0",
62
62
  "@testing-library/user-event": "^14.4.3",
63
- "@types/jest": "^28.1.8",
64
63
  "@types/react": "^18.3.21",
65
64
  "@types/react-dom": "^18.3.0",
66
65
  "@types/react-router-dom": "^5.3.3",
67
- "@types/testing-library__jest-dom": "^5.14.9",
68
66
  "@types/webpack-env": "^1.18.1",
69
67
  "@typescript-eslint/eslint-plugin": "^6.7.0",
70
68
  "@typescript-eslint/parser": "^6.7.0",
69
+ "@vitest/coverage-v8": "^4.1.2",
71
70
  "concurrently": "^6.5.1",
71
+ "cross-env": "^10.1.0",
72
72
  "eslint": "^8.49.0",
73
73
  "eslint-config-react-app": "^7.0.1",
74
74
  "eslint-plugin-import": "^2.31.0",
75
75
  "eslint-plugin-react-hooks": "^5.0.0",
76
76
  "husky": "^8.0.3",
77
77
  "identity-obj-proxy": "^3.0.0",
78
- "jest": "^28.1.3",
79
- "jest-cli": "^28.1.3",
80
- "jest-environment-jsdom": "^28.1.3",
78
+ "jsdom": "^28.0.0",
81
79
  "lint-staged": "^15.2.0",
82
80
  "lodash-es": "^4.17.21",
83
81
  "openmrs": "next",
@@ -89,7 +87,8 @@
89
87
  "semver": "^7.5.4",
90
88
  "swr": "^2.2.4",
91
89
  "turbo": "^2.5.2",
92
- "typescript": "^5.0.0"
90
+ "typescript": "^5.0.0",
91
+ "vitest": "^4.1.2"
93
92
  },
94
93
  "dependencies": {
95
94
  "dotenv": "^16.4.7",
@@ -1,15 +1,16 @@
1
1
  import React from 'react';
2
+ import { vi, describe, it, expect, beforeEach, afterEach, type MockedFunction } from 'vitest';
2
3
  import { act, render, screen } from '@testing-library/react';
3
4
  import { detach, ExtensionSlot } from '@openmrs/esm-framework';
4
5
  import GroupFormWorkflowContext from './context/GroupFormWorkflowContext';
5
6
  import useGetPatient from './hooks/useGetPatient';
6
7
  import FormBootstrap from './FormBootstrap';
7
8
 
8
- jest.mock('./hooks/useGetPatient', () => jest.fn());
9
+ vi.mock('./hooks/useGetPatient', () => ({ default: vi.fn() }));
9
10
 
10
- const mockDetach = jest.mocked(detach);
11
- const mockExtensionSlot = jest.mocked(ExtensionSlot);
12
- const mockUseGetPatient = useGetPatient as jest.MockedFunction<typeof useGetPatient>;
11
+ const mockDetach = vi.mocked(detach);
12
+ const mockExtensionSlot = vi.mocked(ExtensionSlot);
13
+ const mockUseGetPatient = useGetPatient as MockedFunction<typeof useGetPatient>;
13
14
 
14
15
  const renderFormBootstrap = (props = {}) =>
15
16
  render(
@@ -31,9 +32,9 @@ const renderFormBootstrap = (props = {}) =>
31
32
  visitUuid="visit-1"
32
33
  visitTypeUuid="visit-type-1"
33
34
  encounterUuid="encounter-1"
34
- handlePostResponse={jest.fn()}
35
- handleEncounterCreate={jest.fn()}
36
- handleOnValidate={jest.fn()}
35
+ handlePostResponse={vi.fn()}
36
+ handleEncounterCreate={vi.fn()}
37
+ handleOnValidate={vi.fn()}
37
38
  hidePatientBanner={true}
38
39
  {...props}
39
40
  />
@@ -50,7 +51,7 @@ describe('FormBootstrap', () => {
50
51
  });
51
52
 
52
53
  afterEach(() => {
53
- jest.useRealTimers();
54
+ vi.useRealTimers();
54
55
  });
55
56
 
56
57
  it('passes the expected widget state once the patient is available', () => {
@@ -84,8 +85,8 @@ describe('FormBootstrap', () => {
84
85
  });
85
86
 
86
87
  it('refreshes the widget after submit and detaches it on unmount', () => {
87
- jest.useFakeTimers();
88
- const handlePostResponse = jest.fn();
88
+ vi.useFakeTimers();
89
+ const handlePostResponse = vi.fn();
89
90
  const { unmount } = renderFormBootstrap({ handlePostResponse });
90
91
 
91
92
  const [{ state }] = mockExtensionSlot.mock.calls[0];
@@ -99,7 +100,7 @@ describe('FormBootstrap', () => {
99
100
  expect(screen.queryByTestId('form-widget-slot')).not.toBeInTheDocument();
100
101
 
101
102
  act(() => {
102
- jest.advanceTimersByTime(1);
103
+ vi.advanceTimersByTime(1);
103
104
  });
104
105
 
105
106
  expect(screen.getByTestId('form-widget-slot')).toBeInTheDocument();
@@ -6,15 +6,16 @@ import {
6
6
  type Session,
7
7
  PatientIdentifierType,
8
8
  } from '@openmrs/esm-framework';
9
+ import { vi, describe, it, expect, test, beforeEach, type MockedFunction } from 'vitest';
9
10
  import { useHsuIdIdentifier } from '../hooks/location-tag.resource';
10
11
 
11
- jest.mock('@openmrs/esm-framework');
12
- jest.mock('../hooks/location-tag.resource');
12
+ vi.mock('@openmrs/esm-framework');
13
+ vi.mock('../hooks/location-tag.resource');
13
14
 
14
- const mockShowSnackbar = showSnackbar as jest.MockedFunction<typeof showSnackbar>;
15
- const mockUseConfig = useConfig as jest.MockedFunction<typeof useConfig>;
16
- const mockUseSession = useSession as jest.MockedFunction<typeof useSession>;
17
- const mockUseHsuIdIdentifier = useHsuIdIdentifier as jest.MockedFunction<typeof useHsuIdIdentifier>;
15
+ const mockShowSnackbar = showSnackbar as MockedFunction<typeof showSnackbar>;
16
+ const mockUseConfig = useConfig as MockedFunction<typeof useConfig>;
17
+ const mockUseSession = useSession as MockedFunction<typeof useSession>;
18
+ const mockUseHsuIdIdentifier = useHsuIdIdentifier as MockedFunction<typeof useHsuIdIdentifier>;
18
19
 
19
20
  describe('AddGroupModal - enforcePatientListLocationMatch', () => {
20
21
  const mockSessionLocation = {
@@ -28,7 +29,7 @@ describe('AddGroupModal - enforcePatientListLocationMatch', () => {
28
29
  };
29
30
 
30
31
  beforeEach(() => {
31
- jest.clearAllMocks();
32
+ vi.clearAllMocks();
32
33
  });
33
34
 
34
35
  it('should show error snackbar when enforcePatientListLocationMatch is enabled and location mismatch occurs', () => {
@@ -48,7 +49,7 @@ describe('AddGroupModal - enforcePatientListLocationMatch', () => {
48
49
  },
49
50
  } as unknown as ReturnType<typeof useHsuIdIdentifier>);
50
51
 
51
- const config = mockUseConfig();
52
+ const config = mockUseConfig() as ConfigSchema;
52
53
  const session = mockUseSession();
53
54
  const hsuData = mockUseHsuIdIdentifier('patient-uuid');
54
55
 
@@ -88,7 +89,7 @@ describe('AddGroupModal - enforcePatientListLocationMatch', () => {
88
89
  },
89
90
  } as unknown as ReturnType<typeof useHsuIdIdentifier>);
90
91
 
91
- const config = mockUseConfig();
92
+ const config = mockUseConfig() as ConfigSchema;
92
93
  const session = mockUseSession();
93
94
  const hsuData = mockUseHsuIdIdentifier('patient-uuid');
94
95
 
@@ -122,7 +123,7 @@ describe('AddGroupModal - enforcePatientListLocationMatch', () => {
122
123
  },
123
124
  } as unknown as ReturnType<typeof useHsuIdIdentifier>);
124
125
 
125
- const config = mockUseConfig();
126
+ const config = mockUseConfig() as ConfigSchema;
126
127
  const session = mockUseSession();
127
128
  const hsuData = mockUseHsuIdIdentifier('patient-uuid');
128
129
 
@@ -160,7 +161,7 @@ describe('AddGroupModal - enforcePatientListLocationMatch', () => {
160
161
  },
161
162
  } as unknown as ReturnType<typeof useHsuIdIdentifier>);
162
163
 
163
- const config = mockUseConfig();
164
+ const config = mockUseConfig() as ConfigSchema;
164
165
  const session = mockUseSession();
165
166
  const hsuData = mockUseHsuIdIdentifier('patient-uuid');
166
167
 
@@ -187,7 +188,7 @@ describe('AddGroupModal - enforcePatientListLocationMatch', () => {
187
188
  patientLocationMismatchCheck: true,
188
189
  } as ConfigSchema);
189
190
 
190
- const config = mockUseConfig();
191
+ const config = mockUseConfig() as ConfigSchema;
191
192
 
192
193
  const shouldShowError = config.enforcePatientListLocationMatch === true;
193
194
  const shouldShowModal = !config.enforcePatientListLocationMatch && config.patientLocationMismatchCheck;
@@ -1,8 +1,9 @@
1
1
  import { navigate } from '@openmrs/esm-framework';
2
+ import { vi, describe, it, expect, beforeEach } from 'vitest';
2
3
  import { initialWorkflowState } from './FormWorkflowContext';
3
4
  import reducer, { fdeWorkflowStorageName, fdeWorkflowStorageVersion } from './FormWorkflowReducer';
4
5
 
5
- const mockNavigate = jest.mocked(navigate);
6
+ const mockNavigate = vi.mocked(navigate);
6
7
 
7
8
  const buildState = (formStateOverrides = {}) => ({
8
9
  ...initialWorkflowState,
@@ -81,7 +82,7 @@ describe('FormWorkflowReducer', () => {
81
82
  });
82
83
 
83
84
  it('dispatches the submit event and moves the workflow into SUBMIT_FOR_NEXT', () => {
84
- const dispatchEventSpy = jest.spyOn(window, 'dispatchEvent');
85
+ const dispatchEventSpy = vi.spyOn(window, 'dispatchEvent');
85
86
  const state = buildState({
86
87
  workflowState: 'EDIT_FORM',
87
88
  activePatientUuid: 'patient-a',
@@ -1,12 +1,13 @@
1
1
  import { navigate } from '@openmrs/esm-framework';
2
+ import { vi, describe, it, expect, beforeEach } from 'vitest';
2
3
  import { initialWorkflowState } from './GroupFormWorkflowContext';
3
4
  import reducer, { fdeGroupWorkflowStorageName, fdeGroupWorkflowStorageVersion } from './GroupFormWorkflowReducer';
4
5
 
5
- jest.mock('uuid', () => ({
6
- v4: jest.fn(() => 'generated-session-uuid'),
6
+ vi.mock('uuid', () => ({
7
+ v4: vi.fn(() => 'generated-session-uuid'),
7
8
  }));
8
9
 
9
- const mockNavigate = jest.mocked(navigate);
10
+ const mockNavigate = vi.mocked(navigate);
10
11
 
11
12
  const buildState = (formStateOverrides = {}, rootStateOverrides = {}) => ({
12
13
  ...initialWorkflowState,
@@ -185,7 +186,7 @@ describe('GroupFormWorkflowReducer', () => {
185
186
  });
186
187
 
187
188
  it('dispatches validate events and stores the visit UUID for the active patient', () => {
188
- const dispatchEventSpy = jest.spyOn(window, 'dispatchEvent');
189
+ const dispatchEventSpy = vi.spyOn(window, 'dispatchEvent');
189
190
  const state = buildState({
190
191
  workflowState: 'EDIT_FORM',
191
192
  activePatientUuid: 'patient-a',
@@ -217,7 +218,7 @@ describe('GroupFormWorkflowReducer', () => {
217
218
  });
218
219
 
219
220
  it('submits for next and advances to the requested patient after saving', () => {
220
- const dispatchEventSpy = jest.spyOn(window, 'dispatchEvent');
221
+ const dispatchEventSpy = vi.spyOn(window, 'dispatchEvent');
221
222
  const state = buildState(
222
223
  {
223
224
  workflowState: 'EDIT_FORM',
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import { vi, describe, it } from 'vitest';
2
3
  import { render } from '@testing-library/react';
3
4
  import PatientBanner from './PatientBanner';
4
5
 
@@ -1,25 +1,25 @@
1
1
  import React from 'react';
2
+ import { vi, describe, it, expect, beforeEach, afterEach, type MockedFunction } from 'vitest';
2
3
  import { render, screen, fireEvent, cleanup, waitFor } from '@testing-library/react';
3
- import '@testing-library/jest-dom';
4
4
  import PatientSearchHeader from './PatientSearchHeader';
5
5
  import FormWorkflowContext from '../../context/FormWorkflowContext';
6
6
  import { showSnackbar, useConfig, useSession, type ConfigSchema, type Session } from '@openmrs/esm-framework';
7
7
  import { useHsuIdIdentifier } from '../../hooks/location-tag.resource';
8
8
 
9
- jest.mock('@openmrs/esm-framework', () => ({
9
+ vi.mock('@openmrs/esm-framework', () => ({
10
10
  ExtensionSlot: ({ state }) => (
11
11
  <button data-testid="mock-search-select" onClick={() => state.selectPatientAction('patient-123')}>
12
12
  Select Patient
13
13
  </button>
14
14
  ),
15
- interpolateUrl: jest.fn((url) => url),
16
- navigate: jest.fn(),
17
- showSnackbar: jest.fn(),
18
- useConfig: jest.fn(),
19
- useSession: jest.fn(),
15
+ interpolateUrl: vi.fn((url) => url),
16
+ navigate: vi.fn(),
17
+ showSnackbar: vi.fn(),
18
+ useConfig: vi.fn(),
19
+ useSession: vi.fn(),
20
20
  }));
21
21
 
22
- jest.mock('react-i18next', () => ({
22
+ vi.mock('react-i18next', () => ({
23
23
  useTranslation: () => ({
24
24
  t: (key: string, defaultValue: string, interpolation: { hsuLocation?: string; sessionLocation?: string }) => {
25
25
  if (interpolation?.hsuLocation) {
@@ -30,22 +30,22 @@ jest.mock('react-i18next', () => ({
30
30
  }),
31
31
  }));
32
32
 
33
- jest.mock('../../hooks/location-tag.resource', () => ({
34
- useHsuIdIdentifier: jest.fn(),
33
+ vi.mock('../../hooks/location-tag.resource', () => ({
34
+ useHsuIdIdentifier: vi.fn(),
35
35
  }));
36
36
 
37
- jest.mock('react-router-dom', () => ({
37
+ vi.mock('react-router-dom', () => ({
38
38
  Link: ({ children }) => <div>{children}</div>,
39
39
  }));
40
40
 
41
- const mockShowSnackbar = showSnackbar as jest.MockedFunction<typeof showSnackbar>;
42
- const mockUseConfig = useConfig as jest.MockedFunction<typeof useConfig>;
43
- const mockUseSession = useSession as jest.MockedFunction<typeof useSession>;
44
- const mockUseHsuIdIdentifier = useHsuIdIdentifier as jest.MockedFunction<typeof useHsuIdIdentifier>;
41
+ const mockShowSnackbar = showSnackbar as MockedFunction<typeof showSnackbar>;
42
+ const mockUseConfig = useConfig as MockedFunction<typeof useConfig>;
43
+ const mockUseSession = useSession as MockedFunction<typeof useSession>;
44
+ const mockUseHsuIdIdentifier = useHsuIdIdentifier as MockedFunction<typeof useHsuIdIdentifier>;
45
45
 
46
46
  describe('PatientSearchHeader - Enforcement Feature', () => {
47
47
  const mockContext = {
48
- addPatient: jest.fn(),
48
+ addPatient: vi.fn(),
49
49
  workflowState: 'NEW_PATIENT',
50
50
  activeFormUuid: 'form-123',
51
51
  };
@@ -60,7 +60,7 @@ describe('PatientSearchHeader - Enforcement Feature', () => {
60
60
  });
61
61
 
62
62
  afterEach(() => {
63
- jest.clearAllMocks();
63
+ vi.clearAllMocks();
64
64
  cleanup();
65
65
  });
66
66
 
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import { vi, describe, it, expect, beforeEach, type Mock } from 'vitest';
2
3
  import { act, render, screen } from '@testing-library/react';
3
4
  import userEvent from '@testing-library/user-event';
4
5
  import { getGlobalStore, useConfig, useSession, useStore } from '@openmrs/esm-framework';
@@ -6,23 +7,23 @@ import FormBootstrap from '../FormBootstrap';
6
7
  import GroupFormWorkflowContext from '../context/GroupFormWorkflowContext';
7
8
  import GroupSessionWorkspace from './GroupSessionWorkspace';
8
9
 
9
- jest.mock('@openmrs/esm-framework', () => ({
10
- getGlobalStore: jest.fn(),
11
- useConfig: jest.fn(),
12
- useSession: jest.fn(),
13
- useStore: jest.fn(),
10
+ vi.mock('@openmrs/esm-framework', () => ({
11
+ getGlobalStore: vi.fn(),
12
+ useConfig: vi.fn(),
13
+ useSession: vi.fn(),
14
+ useStore: vi.fn(),
14
15
  }));
15
16
 
16
- jest.mock('uuid', () => ({
17
- v4: jest.fn(() => 'generated-visit-uuid'),
17
+ vi.mock('uuid', () => ({
18
+ v4: vi.fn(() => 'generated-visit-uuid'),
18
19
  }));
19
20
 
20
- jest.mock('../FormBootstrap', () => ({
21
+ vi.mock('../FormBootstrap', () => ({
21
22
  __esModule: true,
22
- default: jest.fn(() => <div data-testid="form-bootstrap" />),
23
+ default: vi.fn(() => <div data-testid="form-bootstrap" />),
23
24
  }));
24
25
 
25
- jest.mock('../patient-card/PatientCard', () => ({
26
+ vi.mock('../patient-card/PatientCard', () => ({
26
27
  __esModule: true,
27
28
  default: ({ patientUuid, editEncounter }) => (
28
29
  <button data-testid={`patient-card-${patientUuid}`} onClick={() => editEncounter(patientUuid)}>
@@ -31,21 +32,21 @@ jest.mock('../patient-card/PatientCard', () => ({
31
32
  ),
32
33
  }));
33
34
 
34
- jest.mock('../CancelModal', () => ({
35
+ vi.mock('../CancelModal', () => ({
35
36
  __esModule: true,
36
37
  default: () => null,
37
38
  }));
38
39
 
39
- jest.mock('../CompleteModal', () => ({
40
+ vi.mock('../CompleteModal', () => ({
40
41
  __esModule: true,
41
42
  default: () => null,
42
43
  }));
43
44
 
44
- const mockGetGlobalStore = jest.mocked(getGlobalStore);
45
- const mockUseConfig = jest.mocked(useConfig);
46
- const mockUseSession = jest.mocked(useSession);
47
- const mockUseStore = jest.mocked(useStore);
48
- const mockFormBootstrap = FormBootstrap as jest.Mock;
45
+ const mockGetGlobalStore = vi.mocked(getGlobalStore);
46
+ const mockUseConfig = vi.mocked(useConfig);
47
+ const mockUseSession = vi.mocked(useSession);
48
+ const mockUseStore = vi.mocked(useStore);
49
+ const mockFormBootstrap = FormBootstrap as Mock;
49
50
 
50
51
  const renderWorkspace = (contextOverrides = {}) => {
51
52
  const defaultContext = {
@@ -66,9 +67,9 @@ const renderWorkspace = (contextOverrides = {}) => {
66
67
  },
67
68
  groupVisitTypeUuid: 'visit-type-1',
68
69
  encounters: {},
69
- saveEncounter: jest.fn(),
70
- updateVisitUuid: jest.fn(),
71
- submitForNext: jest.fn(),
70
+ saveEncounter: vi.fn(),
71
+ updateVisitUuid: vi.fn(),
72
+ submitForNext: vi.fn(),
72
73
  };
73
74
 
74
75
  return render(
@@ -104,7 +105,7 @@ describe('GroupSessionWorkspace', () => {
104
105
  });
105
106
 
106
107
  it('builds encounter payloads with group-session metadata when no visit exists yet', () => {
107
- const updateVisitUuid = jest.fn();
108
+ const updateVisitUuid = vi.fn();
108
109
  renderWorkspace({ updateVisitUuid });
109
110
 
110
111
  const [formBootstrapProps] = mockFormBootstrap.mock.calls[0];
@@ -169,8 +170,8 @@ describe('GroupSessionWorkspace', () => {
169
170
 
170
171
  it('wires patient switching and save actions through the workflow callbacks', async () => {
171
172
  const user = userEvent.setup();
172
- const saveEncounter = jest.fn();
173
- const submitForNext = jest.fn();
173
+ const saveEncounter = vi.fn();
174
+ const submitForNext = vi.fn();
174
175
  renderWorkspace({ saveEncounter, submitForNext });
175
176
 
176
177
  const [formBootstrapProps] = mockFormBootstrap.mock.calls[0];
@@ -1,16 +1,17 @@
1
1
  import React, { useEffect } from 'react';
2
+ import { vi, describe, it, expect } from 'vitest';
2
3
  import { render, screen, waitFor } from '@testing-library/react';
3
4
  import userEvent from '@testing-library/user-event';
4
5
  import { useFormContext } from 'react-hook-form';
5
6
  import GroupFormWorkflowContext from '../context/GroupFormWorkflowContext';
6
7
  import SessionMetaWorkspace from './SessionMetaWorkspace';
7
8
 
8
- jest.mock('../CancelModal', () => ({
9
+ vi.mock('../CancelModal', () => ({
9
10
  __esModule: true,
10
11
  default: () => null,
11
12
  }));
12
13
 
13
- jest.mock('./SessionDetailsForm', () => ({
14
+ vi.mock('./SessionDetailsForm', () => ({
14
15
  __esModule: true,
15
16
  default: function MockSessionDetailsForm() {
16
17
  const { register, setValue } = useFormContext();
@@ -40,7 +41,7 @@ const renderSessionMetaWorkspace = (contextOverrides = {}) =>
40
41
  workflowState: 'NEW_GROUP_SESSION',
41
42
  patientUuids: ['patient-a'],
42
43
  activeGroupUuid: 'group-1',
43
- setSessionMeta: jest.fn(),
44
+ setSessionMeta: vi.fn(),
44
45
  ...contextOverrides,
45
46
  } as never
46
47
  }
@@ -52,7 +53,7 @@ const renderSessionMetaWorkspace = (contextOverrides = {}) =>
52
53
  describe('SessionMetaWorkspace', () => {
53
54
  it('submits the session metadata with the normalized session date', async () => {
54
55
  const user = userEvent.setup();
55
- const setSessionMeta = jest.fn();
56
+ const setSessionMeta = vi.fn();
56
57
  renderSessionMetaWorkspace({ setSessionMeta });
57
58
 
58
59
  await user.click(screen.getByRole('button', { name: 'Create New Session' }));
@@ -72,7 +73,7 @@ describe('SessionMetaWorkspace', () => {
72
73
 
73
74
  it('shows the group selection error when submitted without a chosen group', async () => {
74
75
  const user = userEvent.setup();
75
- const setSessionMeta = jest.fn();
76
+ const setSessionMeta = vi.fn();
76
77
  renderSessionMetaWorkspace({
77
78
  activeGroupUuid: null,
78
79
  setSessionMeta,
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import { vi, describe, it } from 'vitest';
2
3
  import { render } from '@testing-library/react';
3
4
  import GroupDisplayHeader from './GroupDisplayHeader';
4
5
 
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import { vi, describe, it, expect, beforeEach } from 'vitest';
2
3
  import { render, screen } from '@testing-library/react';
3
4
  import userEvent from '@testing-library/user-event';
4
5
  import { showSnackbar, useConfig, useSession } from '@openmrs/esm-framework';
@@ -7,7 +8,7 @@ import GroupSearchHeader from './GroupSearchHeader';
7
8
 
8
9
  let selectedGroup;
9
10
 
10
- jest.mock('../group-search/CompactGroupSearch', () => ({
11
+ vi.mock('../group-search/CompactGroupSearch', () => ({
11
12
  __esModule: true,
12
13
  default: ({ selectGroupAction }) => (
13
14
  <button data-testid="compact-group-search" onClick={() => selectGroupAction(selectedGroup)}>
@@ -16,14 +17,14 @@ jest.mock('../group-search/CompactGroupSearch', () => ({
16
17
  ),
17
18
  }));
18
19
 
19
- jest.mock('../../add-group-modal/AddGroupModal', () => ({
20
+ vi.mock('../../add-group-modal/AddGroupModal', () => ({
20
21
  __esModule: true,
21
22
  default: ({ isOpen }) => (isOpen ? <div data-testid="add-group-modal" /> : null),
22
23
  }));
23
24
 
24
- const mockShowSnackbar = jest.mocked(showSnackbar);
25
- const mockUseConfig = jest.mocked(useConfig);
26
- const mockUseSession = jest.mocked(useSession);
25
+ const mockShowSnackbar = vi.mocked(showSnackbar);
26
+ const mockUseConfig = vi.mocked(useConfig);
27
+ const mockUseSession = vi.mocked(useSession);
27
28
 
28
29
  const renderGroupSearchHeader = (contextOverrides = {}) =>
29
30
  render(
@@ -31,8 +32,8 @@ const renderGroupSearchHeader = (contextOverrides = {}) =>
31
32
  value={
32
33
  {
33
34
  activeGroupUuid: null,
34
- setGroup: jest.fn(),
35
- destroySession: jest.fn(),
35
+ setGroup: vi.fn(),
36
+ destroySession: vi.fn(),
36
37
  ...contextOverrides,
37
38
  } as never
38
39
  }
@@ -56,7 +57,7 @@ describe('GroupSearchHeader', () => {
56
57
 
57
58
  it('blocks group selection when location enforcement is enabled and locations mismatch', async () => {
58
59
  const user = userEvent.setup();
59
- const setGroup = jest.fn();
60
+ const setGroup = vi.fn();
60
61
  selectedGroup = {
61
62
  uuid: 'group-1',
62
63
  location: {
@@ -81,7 +82,7 @@ describe('GroupSearchHeader', () => {
81
82
 
82
83
  it('sorts cohort members by display name before storing the selected group', async () => {
83
84
  const user = userEvent.setup();
84
- const setGroup = jest.fn();
85
+ const setGroup = vi.fn();
85
86
  selectedGroup = {
86
87
  uuid: 'group-1',
87
88
  location: {
@@ -109,7 +110,7 @@ describe('GroupSearchHeader', () => {
109
110
 
110
111
  it('opens the add-group modal and lets the user cancel the session', async () => {
111
112
  const user = userEvent.setup();
112
- const destroySession = jest.fn();
113
+ const destroySession = vi.fn();
113
114
  renderGroupSearchHeader({ destroySession });
114
115
 
115
116
  await user.click(screen.getByRole('button', { name: 'Create New Group' }));
@@ -1,10 +1,11 @@
1
1
  import React from 'react';
2
+ import { vi, describe, it, expect, beforeEach, type MockedFunction } from 'vitest';
2
3
  import { act, render, screen } from '@testing-library/react';
3
4
  import { fetchCurrentPatient } from '@openmrs/esm-framework';
4
5
  import useGetPatient from './useGetPatient';
5
6
 
6
- jest.mock('@openmrs/esm-framework', () => ({
7
- fetchCurrentPatient: jest.fn(),
7
+ vi.mock('@openmrs/esm-framework', () => ({
8
+ fetchCurrentPatient: vi.fn(),
8
9
  }));
9
10
 
10
11
  type Deferred<T> = {
@@ -24,7 +25,7 @@ const createDeferred = <T,>(): Deferred<T> => {
24
25
  };
25
26
  };
26
27
 
27
- const mockFetchCurrentPatient = fetchCurrentPatient as jest.MockedFunction<typeof fetchCurrentPatient>;
28
+ const mockFetchCurrentPatient = fetchCurrentPatient as MockedFunction<typeof fetchCurrentPatient>;
28
29
 
29
30
  const TestHarness = ({ patientUuid }: { patientUuid?: string }) => {
30
31
  const patient = useGetPatient(patientUuid);
@@ -35,7 +36,7 @@ const TestHarness = ({ patientUuid }: { patientUuid?: string }) => {
35
36
 
36
37
  describe('useGetPatient', () => {
37
38
  beforeEach(() => {
38
- jest.clearAllMocks();
39
+ vi.clearAllMocks();
39
40
  });
40
41
 
41
42
  it('ignores stale responses after patientUuid changes', async () => {
@@ -1 +1,5 @@
1
- import '@testing-library/jest-dom/extend-expect';
1
+ import '@testing-library/jest-dom/vitest';
2
+ import { afterEach } from 'vitest';
3
+ import { cleanup } from '@testing-library/react';
4
+
5
+ afterEach(cleanup);