@openmrs/esm-stock-management-app 3.0.1-pre.853 → 3.0.1-pre.855
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.
- package/.husky/pre-commit +1 -4
- package/__mocks__/react-i18next.js +9 -8
- package/dist/10.js +1 -1
- package/dist/10.js.map +1 -1
- package/dist/119.js +1 -1
- package/dist/119.js.map +1 -1
- package/dist/14.js +1 -1
- package/dist/14.js.map +1 -1
- package/dist/172.js +1 -1
- package/dist/172.js.map +1 -1
- package/dist/20.js +1 -1
- package/dist/20.js.map +1 -1
- package/dist/290.js +1 -1
- package/dist/290.js.map +1 -1
- package/dist/467.js +1 -1
- package/dist/467.js.map +1 -1
- package/dist/574.js +1 -1
- package/dist/606.js +1 -1
- package/dist/606.js.map +1 -1
- package/dist/627.js +1 -0
- package/dist/627.js.map +1 -0
- package/dist/642.js +1 -1
- package/dist/642.js.map +1 -1
- package/dist/675.js +1 -1
- package/dist/675.js.map +1 -1
- package/dist/727.js +1 -1
- package/dist/727.js.map +1 -1
- package/dist/842.js +1 -1
- package/dist/842.js.map +1 -1
- package/dist/93.js +1 -1
- package/dist/93.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/openmrs-esm-stock-management-app.js.buildmanifest.json +70 -70
- package/dist/routes.json +1 -1
- package/jest.config.js +3 -6
- package/package.json +1 -1
- package/src/core/components/table/table.component.tsx +2 -2
- package/src/index.ts +5 -5
- package/src/stock-items/add-bulk-stock-item/add-stock-items-bulk-import-action-button.component.tsx +3 -3
- package/src/stock-items/add-bulk-stock-item/{stock-items-bulk-import.modal.tsx → stock-items-bulk-import.component.tsx} +19 -20
- package/src/stock-items/add-bulk-stock-item/stock-items-bulk-import.resource.ts +1 -1
- package/src/stock-items/add-bulk-stock-item/stock-items-bulk-import.test.tsx +59 -59
- package/src/stock-items/add-stock-item/add-stock-action-button.component.tsx +6 -6
- package/src/stock-items/add-stock-item/add-stock-item.component.tsx +4 -6
- package/src/stock-items/add-stock-item/add-stock-item.scss +0 -5
- package/src/stock-items/add-stock-item/add-stock-item.test.tsx +43 -28
- package/src/stock-items/add-stock-item/packaging-units/packaging-units-delete-modal.component.tsx +4 -3
- package/src/stock-items/add-stock-item/packaging-units/packaging-units.component.tsx +10 -9
- package/src/stock-items/add-stock-item/packaging-units/packaging-units.scss +4 -4
- package/src/stock-items/add-stock-item/stock-item-details/stock-item-details.component.tsx +19 -27
- package/src/stock-items/add-stock-item/stock-item-references/stock-item-references.scss +4 -4
- package/src/stock-items/add-stock-item/stock-item-rules/add-stock-rules.component.tsx +9 -15
- package/src/stock-items/add-stock-item/stock-item-rules/add-stock-rules.scss +0 -1
- package/src/stock-items/add-stock-item/stock-item-rules/delete-stock-rule-modal.component.tsx +1 -2
- package/src/stock-items/add-stock-item/stock-item-rules/stock-item-rules.component.tsx +16 -14
- package/src/stock-items/add-stock-item/stock-item-rules/stock-item-rules.scss +3 -7
- package/src/stock-items/add-stock-item/transactions/printout/transactions-print-bincard-preview.modal.tsx +6 -14
- package/src/stock-items/add-stock-item/transactions/printout/transactions-print-stockcard-preview.modal.tsx +8 -14
- package/src/stock-items/edit-stock-item/edit-stock-item-action-menu.component.tsx +2 -2
- package/src/stock-items/stock-item.utils.tsx +5 -3
- package/src/stock-items/stock-items-table.component.tsx +45 -47
- package/src/stock-items/stock-items-table.resource.ts +2 -2
- package/src/stock-items/stock-items-table.scss +1 -5
- package/src/stock-items/stock-items-table.test.tsx +65 -106
- package/src/stock-locations/location-admin-form.component.tsx +4 -5
- package/src/stock-locations/stock-locations-table.component.tsx +8 -10
- package/src/stock-lookups/stock-lookups.resource.ts +2 -3
- package/src/stock-operations/stock-operations-dialog/stock-operations-dialog.component.tsx +2 -2
- package/src/stock-operations/stock-operations-forms/input-components/batch-no-selector.component.tsx +11 -11
- package/src/stock-operations/stock-operations-forms/input-components/batch-no-selector.test.tsx +25 -115
- package/src/stock-operations/stock-operations-forms/input-components/qty-uim-selector.test.tsx +65 -107
- package/src/stock-operations/stock-operations-forms/input-components/quantity-uom-selector.component.tsx +9 -9
- package/src/stock-operations/stock-operations-forms/input-components/stock-operation-reason-selector.test.tsx +153 -35
- package/src/stock-operations/stock-operations-forms/input-components/user-selector.test.tsx +29 -82
- package/src/stock-operations/stock-operations-forms/step1.test.tsx +69 -204
- package/src/stock-operations/stock-operations-forms/step2.test.tsx +63 -140
- package/src/stock-operations/stock-operations-forms/step3.test.tsx +60 -79
- package/src/stock-operations/stock-operations-forms/steps/stock-operation-items-form-step.component.tsx +5 -6
- package/src/stock-operations/stock-operations-forms/steps/stock-operation-submission-form-step.component.tsx +11 -12
- package/src/stock-operations/stock-operations-forms/stock-item-form/stock-item-form.scss +0 -1
- package/src/stock-operations/stock-operations-forms/stock-item-form/stock-item-form.workspace.tsx +12 -20
- package/src/stock-operations/stock-operations-forms/stock-operation-form.scss +0 -1
- package/src/stock-operations/stock-operations-forms/stock-operation-stepper/stepper.scss +3 -1
- package/src/stock-operations/stock-operations-forms/stock-operation-stepper/stock-operation-stepper.component.tsx +1 -2
- package/src/stock-reports/generate-report/create-stock-report.scss +2 -3
- package/src/stock-reports/generate-report/create-stock-report.workspace.tsx +25 -32
- package/src/stock-reports/report-list/stock-report-parameters.component.tsx +1 -1
- package/src/stock-reports/report-list/stock-report-status.component.tsx +1 -1
- package/src/stock-reports/report-list/stock-reports.component.tsx +25 -24
- package/src/stock-reports/report-list/stock-reports.scss +2 -10
- package/src/stock-sources/add-stock-sources/add-stock-sources.scss +4 -11
- package/src/stock-sources/add-stock-sources/add-stock-sources.test.tsx +36 -38
- package/src/stock-sources/add-stock-sources/add-stock-sources.workspace.tsx +30 -35
- package/src/stock-sources/delete-stock-modal.component.tsx +1 -2
- package/src/stock-sources/stock-sources-delete/stock-sources-delete.test.tsx +36 -27
- package/src/stock-sources/stock-sources-filter/stock-sources-filter.component.tsx +21 -33
- package/src/stock-sources/stock-sources-items-table.component.tsx +17 -16
- package/src/stock-sources/stock-sources-items-table.resource.ts +6 -8
- package/src/stock-sources/stock-sources-items-table.test.tsx +37 -60
- package/src/stock-sources/stock-sources.scss +2 -6
- package/src/stock-user-role-scopes/add-stock-user-scope/add-stock-user-role-scope.scss +13 -5
- package/src/stock-user-role-scopes/add-stock-user-scope/add-stock-user-role-scope.workspace.tsx +2 -2
- package/src/stock-user-role-scopes/delete-stock-user-scope-modal.component.tsx +1 -2
- package/translations/en.json +6 -5
- package/tsconfig.json +0 -4
- package/dist/33.js +0 -1
- package/dist/33.js.map +0 -1
@@ -1,27 +1,44 @@
|
|
1
1
|
import React from 'react';
|
2
|
+
import { render, waitFor, screen, fireEvent } from '@testing-library/react';
|
3
|
+
import { showSnackbar, useConfig, ErrorState, launchWorkspace } from '@openmrs/esm-framework';
|
4
|
+
import { useStockOperationTypes, useUser } from '../../stock-lookups/stock-lookups.resource';
|
5
|
+
import { getStockOperationLinks, useStockOperations } from '../stock-operations.resource';
|
6
|
+
import { StockOperationDTO } from '../../core/api/types/stockOperation/StockOperationDTO';
|
7
|
+
import { StockOperationType } from '../../core/api/types/stockOperation/StockOperationType';
|
8
|
+
import { closeOverlay } from '../../core/components/overlay/hook';
|
9
|
+
import StockOperationForm from './stock-operation-form.component';
|
10
|
+
import useParties from './hooks/useParties';
|
2
11
|
import userEvent from '@testing-library/user-event';
|
3
|
-
import { render, screen } from '@testing-library/react';
|
4
|
-
import { useFormContext, type UseFormReturn } from 'react-hook-form';
|
5
|
-
import { useConfig, useSession } from '@openmrs/esm-framework';
|
6
|
-
import { formatForDatePicker } from '../../constants';
|
7
|
-
import { receiptOperationTypeMock } from '@mocks';
|
8
|
-
import { type BaseStockOperationItemFormData } from '../validation-schema';
|
9
12
|
import { type StockItemDTO } from '../../core/api/types/stockItem/StockItem';
|
13
|
+
import { useStockItem, useStockItems, useStockBatches } from '../../stock-items/stock-items.resource';
|
14
|
+
import { initialStockOperationValue } from '../../core/utils/utils';
|
15
|
+
import { useForm, useFormContext, Controller, FormProvider } from 'react-hook-form';
|
16
|
+
import { type BaseStockOperationItemFormData, StockOperationItemFormData } from '../validation-schema';
|
17
|
+
import { useStockItemBatchInformationHook } from '../../stock-items/add-stock-item/batch-information/batch-information.resource';
|
10
18
|
import { useFilterableStockItems } from './hooks/useFilterableStockItems';
|
11
|
-
import {
|
12
|
-
import {
|
13
|
-
|
14
|
-
|
15
|
-
|
19
|
+
import { formatForDatePicker } from '../../constants';
|
20
|
+
import { receiptOperationTypeMock } from '../../../__mocks__';
|
21
|
+
jest.mock('react-i18next', () => ({
|
22
|
+
useTranslation: jest.fn().mockReturnValue({ t: (key) => key }),
|
23
|
+
}));
|
16
24
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
+
jest.mock('@openmrs/esm-framework', () => ({
|
26
|
+
ActionMenu: jest.fn(() => null),
|
27
|
+
showSnackbar: jest.fn(),
|
28
|
+
useDebounce: jest.fn((x) => x),
|
29
|
+
getGlobalStore: jest.fn(() => ({
|
30
|
+
getState: jest.fn(),
|
31
|
+
subscribe: jest.fn(),
|
32
|
+
setState: jest.fn(),
|
33
|
+
})),
|
34
|
+
parseDate: jest.fn((date) => new Date(date)),
|
35
|
+
showNotification: jest.fn(),
|
36
|
+
usePagination: jest.fn(() => ({ currentPage: 1, setPage: jest.fn() })),
|
37
|
+
useSession: jest.fn(() => ({ user: { display: 'Test User' } })),
|
38
|
+
useConfig: jest.fn(),
|
39
|
+
ErrorState: jest.fn(({ error }: { error: any }) => <div>{error}</div>),
|
40
|
+
launchWorkspace: jest.fn(),
|
41
|
+
}));
|
25
42
|
|
26
43
|
jest.mock('../../stock-lookups/stock-lookups.resource', () => ({
|
27
44
|
useStockOperationTypes: jest.fn(),
|
@@ -33,11 +50,7 @@ jest.mock('../stock-operations.resource', () => ({
|
|
33
50
|
operationStatusColor: jest.fn(() => 'some-color'),
|
34
51
|
getStockOperationLinks: jest.fn(),
|
35
52
|
useStockOperations: jest.fn().mockReturnValue({
|
36
|
-
items: {
|
37
|
-
results: [],
|
38
|
-
links: [],
|
39
|
-
totalCount: 0,
|
40
|
-
},
|
53
|
+
items: { results: [] },
|
41
54
|
isLoading: false,
|
42
55
|
error: null,
|
43
56
|
}),
|
@@ -65,7 +78,6 @@ jest.mock('../../stock-items/stock-items.resource', () => ({
|
|
65
78
|
items: {},
|
66
79
|
}),
|
67
80
|
}));
|
68
|
-
|
69
81
|
jest.mock('./hooks/useFilterableStockItems', () => ({
|
70
82
|
useFilterableStockItems: jest.fn().mockReturnValue({
|
71
83
|
stockItemsList: [],
|
@@ -75,9 +87,7 @@ jest.mock('./hooks/useFilterableStockItems', () => ({
|
|
75
87
|
isLoading: false,
|
76
88
|
}),
|
77
89
|
}));
|
78
|
-
|
79
90
|
jest.mock('./hooks/useParties', () => jest.fn());
|
80
|
-
|
81
91
|
jest.mock('react-hook-form', () => ({
|
82
92
|
useForm: jest.fn().mockReturnValue({
|
83
93
|
watch: jest.fn(),
|
@@ -93,17 +103,6 @@ jest.mock('react-hook-form', () => ({
|
|
93
103
|
watch: jest.fn(),
|
94
104
|
formState: {
|
95
105
|
errors: {},
|
96
|
-
isDirty: false,
|
97
|
-
isLoading: false,
|
98
|
-
isSubmitted: false,
|
99
|
-
isSubmitSuccessful: false,
|
100
|
-
isSubmitting: false,
|
101
|
-
isValid: true,
|
102
|
-
isValidating: false,
|
103
|
-
submitCount: 0,
|
104
|
-
touchedFields: {},
|
105
|
-
dirtyFields: {},
|
106
|
-
disabled: false,
|
107
106
|
},
|
108
107
|
resetField: jest.fn(),
|
109
108
|
getValues: jest.fn(),
|
@@ -135,71 +134,21 @@ jest.mock('../../stock-items/add-stock-item/batch-information/batch-information.
|
|
135
134
|
|
136
135
|
describe('Stock Operation step 2 (stock operation items details)', () => {
|
137
136
|
beforeEach(() => {
|
138
|
-
const mockStockOperationTypes = {
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
},
|
144
|
-
isLoading: false,
|
145
|
-
error: null,
|
146
|
-
};
|
147
|
-
|
148
|
-
mockUseStockOperationTypes.mockReturnValue(mockStockOperationTypes);
|
149
|
-
|
150
|
-
mockUseStockOperations.mockReturnValue({
|
151
|
-
items: {
|
152
|
-
results: [],
|
153
|
-
links: [],
|
154
|
-
totalCount: 0,
|
155
|
-
},
|
156
|
-
isLoading: false,
|
157
|
-
error: null,
|
158
|
-
});
|
159
|
-
|
160
|
-
mockUseConfig.mockReturnValue({ autoPopulateResponsiblePerson: true });
|
161
|
-
|
162
|
-
mockUseParties.mockReturnValue({
|
137
|
+
const mockStockOperationTypes = { results: [] };
|
138
|
+
(useStockOperationTypes as jest.Mock).mockReturnValue(mockStockOperationTypes);
|
139
|
+
(useStockOperations as jest.Mock).mockReturnValue({ items: { results: [] }, isLoading: false, error: null });
|
140
|
+
(useConfig as jest.Mock).mockReturnValue({ autoPopulateResponsiblePerson: true });
|
141
|
+
(useParties as jest.Mock).mockReturnValue({
|
163
142
|
destinationParties: [],
|
164
|
-
destinationPartiesFilter: jest.fn(),
|
165
|
-
destinationTags: [],
|
166
|
-
error: undefined,
|
167
|
-
isLoading: false,
|
168
|
-
mutate: jest.fn(),
|
169
|
-
parties: [],
|
170
143
|
sourceParties: [],
|
171
|
-
|
144
|
+
isLoading: false,
|
145
|
+
error: undefined,
|
172
146
|
sourceTags: [],
|
173
|
-
|
174
|
-
|
175
|
-
mockUseSession.mockReturnValue({
|
176
|
-
authenticated: true,
|
177
|
-
sessionId: 'test-session-id',
|
178
|
-
user: {
|
179
|
-
uuid: 'test-user-uuid',
|
180
|
-
display: 'Test User',
|
181
|
-
username: 'testuser',
|
182
|
-
systemId: 'test-system-id',
|
183
|
-
userProperties: {},
|
184
|
-
person: { uuid: 'test-person-uuid' },
|
185
|
-
privileges: [],
|
186
|
-
roles: [],
|
187
|
-
retired: false,
|
188
|
-
links: [],
|
189
|
-
locale: 'en',
|
190
|
-
allowedLocales: ['en'],
|
191
|
-
},
|
192
|
-
sessionLocation: {
|
193
|
-
uuid: 'test-location-uuid',
|
194
|
-
display: 'Test Location',
|
195
|
-
links: [],
|
196
|
-
},
|
147
|
+
destinationTags: [],
|
197
148
|
});
|
198
149
|
});
|
199
150
|
|
200
151
|
it('should have both previous and next btns', async () => {
|
201
|
-
const user = userEvent.setup();
|
202
|
-
|
203
152
|
render(
|
204
153
|
<StockOperationForm
|
205
154
|
stockOperationType={receiptOperationTypeMock as any}
|
@@ -210,15 +159,13 @@ describe('Stock Operation step 2 (stock operation items details)', () => {
|
|
210
159
|
/>,
|
211
160
|
);
|
212
161
|
// MOVE TO STEP 2
|
213
|
-
await
|
162
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
214
163
|
|
215
164
|
expect(screen.getByRole('button', { name: /Next/i })).toBeInTheDocument();
|
216
165
|
expect(screen.getByTestId('previous-btn')).toBeInTheDocument();
|
217
166
|
});
|
218
167
|
|
219
168
|
it('should render stock operation items table with item search component', async () => {
|
220
|
-
const user = userEvent.setup();
|
221
|
-
|
222
169
|
render(
|
223
170
|
<StockOperationForm
|
224
171
|
stockOperationType={receiptOperationTypeMock as any}
|
@@ -228,17 +175,16 @@ describe('Stock Operation step 2 (stock operation items details)', () => {
|
|
228
175
|
promptBeforeClosing={jest.fn()}
|
229
176
|
/>,
|
230
177
|
);
|
231
|
-
|
232
178
|
const nextButton = screen.getByRole('button', { name: /Next/i });
|
233
179
|
expect(nextButton).toBeInTheDocument();
|
234
|
-
await
|
180
|
+
await userEvent.click(nextButton);
|
235
181
|
expect(screen.getByRole('table')).toBeInTheDocument();
|
236
182
|
expect(
|
237
183
|
screen.getByRole('searchbox', {
|
238
184
|
name(accessibleName, element) {
|
239
185
|
return (
|
240
186
|
element.getAttribute('id') === 'search-stock-operation-item' &&
|
241
|
-
element.getAttribute('placeholder') === '
|
187
|
+
element.getAttribute('placeholder') === 'findItems' &&
|
242
188
|
element.getAttribute('name') === 'search-stock-operation-item'
|
243
189
|
);
|
244
190
|
},
|
@@ -247,10 +193,8 @@ describe('Stock Operation step 2 (stock operation items details)', () => {
|
|
247
193
|
});
|
248
194
|
|
249
195
|
it('should search stock operation item and render results', async () => {
|
250
|
-
const user = userEvent.setup();
|
251
|
-
|
252
196
|
const mocksetSearchString = jest.fn();
|
253
|
-
|
197
|
+
(useFilterableStockItems as jest.Mock).mockReturnValue({
|
254
198
|
stockItemsList: [
|
255
199
|
{ uuid: 'mock-uuid', commonName: 'mock-common-name', drugName: 'mock-common-name' },
|
256
200
|
] as Array<StockItemDTO>,
|
@@ -259,7 +203,6 @@ describe('Stock Operation step 2 (stock operation items details)', () => {
|
|
259
203
|
isLoading: false,
|
260
204
|
setSearchString: mocksetSearchString,
|
261
205
|
});
|
262
|
-
|
263
206
|
render(
|
264
207
|
<StockOperationForm
|
265
208
|
stockOperationType={receiptOperationTypeMock as any}
|
@@ -269,24 +212,21 @@ describe('Stock Operation step 2 (stock operation items details)', () => {
|
|
269
212
|
promptBeforeClosing={jest.fn()}
|
270
213
|
/>,
|
271
214
|
);
|
272
|
-
|
273
215
|
// ----- CLICK NEXT TO MOVE TO STEP 2 ---------
|
274
|
-
await
|
216
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
275
217
|
// -------------------------------
|
276
218
|
const searchInput = screen.getByRole('searchbox', {
|
277
|
-
name:
|
219
|
+
name: (_, element) => element.getAttribute('id') === 'search-stock-operation-item',
|
278
220
|
});
|
279
221
|
expect(searchInput).toBeInTheDocument();
|
280
|
-
await
|
281
|
-
await
|
222
|
+
await userEvent.click(searchInput);
|
223
|
+
await userEvent.type(searchInput, 'stock');
|
282
224
|
expect(mocksetSearchString).toHaveBeenCalledWith('stock');
|
283
225
|
expect(screen.getByText('mock-common-name'));
|
284
226
|
});
|
285
227
|
|
286
228
|
it('should properly handle stock operation item selection', async () => {
|
287
|
-
|
288
|
-
|
289
|
-
mockUseFilterableStockItems.mockReturnValue({
|
229
|
+
(useFilterableStockItems as jest.Mock).mockReturnValue({
|
290
230
|
stockItemsList: [
|
291
231
|
{ uuid: 'mock-uuid', commonName: 'mock-common-name', drugName: 'mock-common-name' },
|
292
232
|
] as Array<StockItemDTO>,
|
@@ -295,7 +235,6 @@ describe('Stock Operation step 2 (stock operation items details)', () => {
|
|
295
235
|
isLoading: false,
|
296
236
|
setSearchString: jest.fn(),
|
297
237
|
});
|
298
|
-
|
299
238
|
render(
|
300
239
|
<StockOperationForm
|
301
240
|
stockOperationType={receiptOperationTypeMock as any}
|
@@ -306,30 +245,27 @@ describe('Stock Operation step 2 (stock operation items details)', () => {
|
|
306
245
|
/>,
|
307
246
|
);
|
308
247
|
// ----- CLICK NEXT TO MOVE TO STEP 2 ---------
|
309
|
-
await
|
248
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
310
249
|
// -------------------------------
|
311
250
|
const searchInput = screen.getByRole('searchbox', {
|
312
251
|
name: (_, element) => element.getAttribute('id') === 'search-stock-operation-item',
|
313
252
|
});
|
314
|
-
await
|
315
|
-
await
|
316
|
-
await
|
253
|
+
await userEvent.click(searchInput);
|
254
|
+
await userEvent.type(searchInput, 'stock');
|
255
|
+
await userEvent.click(screen.getByText('mock-common-name'));
|
317
256
|
// Look for common name at the top of workspace
|
318
|
-
expect(screen.getByText(/
|
257
|
+
expect(screen.getByText(/noDrugNameAvailable|noCommonNameAvailable|mock-common-name/i)).toBeInTheDocument();
|
319
258
|
});
|
320
259
|
|
321
260
|
it('should render stock operation items in data table', async () => {
|
322
|
-
|
323
|
-
|
324
|
-
mockUseStockItem.mockReturnValue({
|
261
|
+
(useStockItem as jest.Mock).mockReturnValue({
|
325
262
|
isLoading: false,
|
326
263
|
error: null,
|
327
264
|
item: { commonName: 'mock-stock-item-common name', uuid: 'mock-uuid' } as StockItemDTO,
|
328
265
|
});
|
329
|
-
|
330
266
|
const mockQuantity = 99999;
|
331
267
|
const mockExpiration = new Date();
|
332
|
-
|
268
|
+
(useFormContext as jest.Mock).mockReturnValue({
|
333
269
|
watch: jest.fn().mockReturnValue([
|
334
270
|
{
|
335
271
|
quantity: mockQuantity,
|
@@ -339,23 +275,11 @@ describe('Stock Operation step 2 (stock operation items details)', () => {
|
|
339
275
|
resetField: jest.fn(),
|
340
276
|
formState: {
|
341
277
|
errors: {},
|
342
|
-
isDirty: false,
|
343
|
-
isLoading: false,
|
344
|
-
isSubmitted: false,
|
345
|
-
isSubmitSuccessful: false,
|
346
|
-
isSubmitting: false,
|
347
|
-
isValid: true,
|
348
|
-
isValidating: false,
|
349
|
-
submitCount: 0,
|
350
|
-
touchedFields: {},
|
351
|
-
dirtyFields: {},
|
352
|
-
disabled: false,
|
353
278
|
},
|
354
279
|
getValues: jest.fn(),
|
355
280
|
setValue: jest.fn(),
|
356
281
|
handleSubmit: jest.fn(),
|
357
|
-
}
|
358
|
-
|
282
|
+
});
|
359
283
|
render(
|
360
284
|
<StockOperationForm
|
361
285
|
stockOperationType={receiptOperationTypeMock as any}
|
@@ -365,9 +289,8 @@ describe('Stock Operation step 2 (stock operation items details)', () => {
|
|
365
289
|
promptBeforeClosing={jest.fn()}
|
366
290
|
/>,
|
367
291
|
);
|
368
|
-
|
369
292
|
// ----- CLICK NEXT TO MOVE TO STEP 2 ---------
|
370
|
-
await
|
293
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
371
294
|
// -------------------------------
|
372
295
|
expect(screen.getByText(mockQuantity.toLocaleString())).toBeInTheDocument(); //Find by quentity
|
373
296
|
expect(screen.getByText(formatForDatePicker(mockExpiration))).toBeInTheDocument(); //Find by quentity
|
@@ -1,18 +1,44 @@
|
|
1
|
-
import
|
2
|
-
import
|
3
|
-
import {
|
4
|
-
import {
|
5
|
-
import {
|
6
|
-
import {
|
7
|
-
import {
|
8
|
-
import useParties from './hooks/useParties';
|
1
|
+
import { render, waitFor, screen, fireEvent } from '@testing-library/react';
|
2
|
+
import { showSnackbar, useConfig, ErrorState, launchWorkspace } from '@openmrs/esm-framework';
|
3
|
+
import { useStockOperationTypes, useUser } from '../../stock-lookups/stock-lookups.resource';
|
4
|
+
import { getStockOperationLinks, useStockOperation, useStockOperations } from '../stock-operations.resource';
|
5
|
+
import { StockOperationDTO } from '../../core/api/types/stockOperation/StockOperationDTO';
|
6
|
+
import { StockOperationType } from '../../core/api/types/stockOperation/StockOperationType';
|
7
|
+
import { closeOverlay } from '../../core/components/overlay/hook';
|
9
8
|
import StockOperationForm from './stock-operation-form.component';
|
9
|
+
import useParties from './hooks/useParties';
|
10
|
+
import userEvent from '@testing-library/user-event';
|
11
|
+
import { StockItemDTO } from '../../core/api/types/stockItem/StockItem';
|
12
|
+
import { useStockItem, useStockItems } from '../../stock-items/stock-items.resource';
|
13
|
+
import { initialStockOperationValue } from '../../core/utils/utils';
|
14
|
+
import { useForm, useFormContext, Controller, FormProvider } from 'react-hook-form';
|
15
|
+
import { BaseStockOperationItemFormData, StockOperationItemFormData } from '../validation-schema';
|
16
|
+
import { useStockItemBatchInformationHook } from '../../stock-items/add-stock-item/batch-information/batch-information.resource';
|
17
|
+
import { useFilterableStockItems } from './hooks/useFilterableStockItems';
|
18
|
+
import { formatForDatePicker } from '../../constants';
|
19
|
+
import React from 'react';
|
20
|
+
import { receiptOperationTypeMock, returnOperationTypeMock, stockIssueOperationtypeMock } from '../../../__mocks__';
|
21
|
+
jest.mock('react-i18next', () => ({
|
22
|
+
useTranslation: jest.fn().mockReturnValue({ t: (key) => key }),
|
23
|
+
}));
|
10
24
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
25
|
+
jest.mock('@openmrs/esm-framework', () => ({
|
26
|
+
ActionMenu: jest.fn(() => null),
|
27
|
+
showSnackbar: jest.fn(),
|
28
|
+
useDebounce: jest.fn((x) => x),
|
29
|
+
getGlobalStore: jest.fn(() => ({
|
30
|
+
getState: jest.fn(),
|
31
|
+
subscribe: jest.fn(),
|
32
|
+
setState: jest.fn(),
|
33
|
+
})),
|
34
|
+
parseDate: jest.fn((date) => new Date(date)),
|
35
|
+
showNotification: jest.fn(),
|
36
|
+
usePagination: jest.fn(() => ({ currentPage: 1, setPage: jest.fn() })),
|
37
|
+
useSession: jest.fn(() => ({ user: { display: 'Test User' } })),
|
38
|
+
useConfig: jest.fn(),
|
39
|
+
ErrorState: jest.fn(({ error }: { error: any }) => <div>{error}</div>),
|
40
|
+
launchWorkspace: jest.fn(),
|
41
|
+
}));
|
16
42
|
|
17
43
|
jest.mock('../../stock-lookups/stock-lookups.resource', () => ({
|
18
44
|
useStockOperationTypes: jest.fn(),
|
@@ -52,7 +78,6 @@ jest.mock('../../stock-items/stock-items.resource', () => ({
|
|
52
78
|
items: {},
|
53
79
|
}),
|
54
80
|
}));
|
55
|
-
|
56
81
|
jest.mock('./hooks/useFilterableStockItems', () => ({
|
57
82
|
useFilterableStockItems: jest.fn().mockReturnValue({
|
58
83
|
stockItemsList: [],
|
@@ -62,9 +87,7 @@ jest.mock('./hooks/useFilterableStockItems', () => ({
|
|
62
87
|
isLoading: false,
|
63
88
|
}),
|
64
89
|
}));
|
65
|
-
|
66
90
|
jest.mock('./hooks/useParties', () => jest.fn());
|
67
|
-
|
68
91
|
jest.mock('react-hook-form', () => ({
|
69
92
|
useForm: jest.fn().mockReturnValue({
|
70
93
|
watch: jest.fn(),
|
@@ -111,55 +134,17 @@ jest.mock('../../stock-items/add-stock-item/batch-information/batch-information.
|
|
111
134
|
|
112
135
|
describe('Stock Operation form step 3 (stock submision)', () => {
|
113
136
|
beforeEach(() => {
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
mockUseStockOperations.mockReturnValue({
|
121
|
-
items: { results: [], links: [], totalCount: 0 },
|
122
|
-
isLoading: false,
|
123
|
-
error: null,
|
124
|
-
});
|
125
|
-
|
126
|
-
mockUseConfig.mockReturnValue({ autoPopulateResponsiblePerson: true });
|
127
|
-
|
128
|
-
mockUseParties.mockReturnValue({
|
137
|
+
const mockStockOperationTypes = { results: [] };
|
138
|
+
(useStockOperationTypes as jest.Mock).mockReturnValue(mockStockOperationTypes);
|
139
|
+
(useStockOperations as jest.Mock).mockReturnValue({ items: { results: [] }, isLoading: false, error: null });
|
140
|
+
(useConfig as jest.Mock).mockReturnValue({ autoPopulateResponsiblePerson: true });
|
141
|
+
(useParties as jest.Mock).mockReturnValue({
|
129
142
|
destinationParties: [],
|
130
143
|
sourceParties: [],
|
131
144
|
isLoading: false,
|
132
145
|
error: undefined,
|
133
146
|
sourceTags: [],
|
134
147
|
destinationTags: [],
|
135
|
-
parties: [],
|
136
|
-
mutate: jest.fn(),
|
137
|
-
sourcePartiesFilter: () => true,
|
138
|
-
destinationPartiesFilter: () => true,
|
139
|
-
});
|
140
|
-
|
141
|
-
mockUseSession.mockReturnValue({
|
142
|
-
authenticated: true,
|
143
|
-
sessionId: 'test-session-id',
|
144
|
-
user: {
|
145
|
-
uuid: 'test-user-uuid',
|
146
|
-
display: 'Test User',
|
147
|
-
username: 'testuser',
|
148
|
-
systemId: 'test-system-id',
|
149
|
-
userProperties: {},
|
150
|
-
person: { uuid: 'test-person-uuid' },
|
151
|
-
privileges: [],
|
152
|
-
roles: [],
|
153
|
-
retired: false,
|
154
|
-
links: [],
|
155
|
-
locale: 'en',
|
156
|
-
allowedLocales: ['en'],
|
157
|
-
},
|
158
|
-
sessionLocation: {
|
159
|
-
uuid: 'test-location-uuid',
|
160
|
-
display: 'Test Location',
|
161
|
-
links: [],
|
162
|
-
},
|
163
148
|
});
|
164
149
|
});
|
165
150
|
|
@@ -174,11 +159,11 @@ describe('Stock Operation form step 3 (stock submision)', () => {
|
|
174
159
|
/>,
|
175
160
|
);
|
176
161
|
// MOVE TO STEP 2
|
177
|
-
await userEvent.click(screen.getByRole('button', { name: /
|
162
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
178
163
|
// MOVE TO STEP3
|
179
|
-
await userEvent.click(screen.getByRole('button', { name: /
|
164
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
180
165
|
|
181
|
-
expect(screen.queryByRole('button', { name: /
|
166
|
+
expect(screen.queryByRole('button', { name: /Next/i })).not.toBeInTheDocument();
|
182
167
|
expect(screen.getByTestId('previous-btn')).toBeInTheDocument();
|
183
168
|
});
|
184
169
|
|
@@ -193,15 +178,14 @@ describe('Stock Operation form step 3 (stock submision)', () => {
|
|
193
178
|
/>,
|
194
179
|
);
|
195
180
|
// MOVE TO STEP 2
|
196
|
-
await userEvent.click(screen.getByRole('button', { name: /
|
181
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
197
182
|
// MOVE TO STEP3
|
198
|
-
await userEvent.click(screen.getByRole('button', { name: /
|
183
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
199
184
|
|
200
185
|
// Shouls have save button
|
201
186
|
expect(screen.getByRole('button', { name: /save/i })).toBeInTheDocument();
|
202
187
|
expect(screen.getAllByRole('radio', { name: /yes|no/i })).toHaveLength(2);
|
203
188
|
});
|
204
|
-
|
205
189
|
it('should render submitForReview button when require aprroval radion button is checked yes', async () => {
|
206
190
|
render(
|
207
191
|
<StockOperationForm
|
@@ -213,19 +197,18 @@ describe('Stock Operation form step 3 (stock submision)', () => {
|
|
213
197
|
/>,
|
214
198
|
);
|
215
199
|
// MOVE TO STEP 2
|
216
|
-
await userEvent.click(screen.getByRole('button', { name: /
|
200
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
217
201
|
// MOVE TO STEP3
|
218
|
-
await userEvent.click(screen.getByRole('button', { name: /
|
202
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
219
203
|
|
220
204
|
const yesRadioButton = screen.getByRole('radio', { name: /yes/i });
|
221
205
|
expect(yesRadioButton).toBeInTheDocument();
|
222
206
|
// Submit for review shouldnt be in doc
|
223
|
-
expect(screen.queryByRole('button', { name: /
|
207
|
+
expect(screen.queryByRole('button', { name: /submitForReview/i })).not.toBeInTheDocument();
|
224
208
|
await userEvent.click(yesRadioButton);
|
225
209
|
// On require aprooval should now show
|
226
|
-
expect(screen.getByRole('button', { name: /
|
210
|
+
expect(screen.getByRole('button', { name: /submitForReview/i })).toBeInTheDocument();
|
227
211
|
});
|
228
|
-
|
229
212
|
it('should render complete button when require aprroval radion button is checked no', async () => {
|
230
213
|
render(
|
231
214
|
<StockOperationForm
|
@@ -237,9 +220,9 @@ describe('Stock Operation form step 3 (stock submision)', () => {
|
|
237
220
|
/>,
|
238
221
|
);
|
239
222
|
// MOVE TO STEP 2
|
240
|
-
await userEvent.click(screen.getByRole('button', { name: /
|
223
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
241
224
|
// MOVE TO STEP3
|
242
|
-
await userEvent.click(screen.getByRole('button', { name: /
|
225
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
243
226
|
|
244
227
|
const noRadioButton = screen.getByRole('radio', { name: /no/i });
|
245
228
|
expect(noRadioButton).toBeInTheDocument();
|
@@ -247,7 +230,6 @@ describe('Stock Operation form step 3 (stock submision)', () => {
|
|
247
230
|
// On require aprooval should now show complete btn
|
248
231
|
expect(screen.getByTestId('complete-button')).toBeInTheDocument();
|
249
232
|
});
|
250
|
-
|
251
233
|
it('should render dispatch btn for stock return operation and dont require aproval', async () => {
|
252
234
|
render(
|
253
235
|
<StockOperationForm
|
@@ -259,9 +241,9 @@ describe('Stock Operation form step 3 (stock submision)', () => {
|
|
259
241
|
/>,
|
260
242
|
);
|
261
243
|
// MOVE TO STEP 2
|
262
|
-
await userEvent.click(screen.getByRole('button', { name: /
|
244
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
263
245
|
// MOVE TO STEP3
|
264
|
-
await userEvent.click(screen.getByRole('button', { name: /
|
246
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
265
247
|
|
266
248
|
const noRadioButton = screen.getByRole('radio', { name: /no/i });
|
267
249
|
expect(noRadioButton).toBeInTheDocument();
|
@@ -269,7 +251,6 @@ describe('Stock Operation form step 3 (stock submision)', () => {
|
|
269
251
|
// On require aprooval should now show complete btn
|
270
252
|
expect(screen.getByTestId('dipatch-button')).toBeInTheDocument();
|
271
253
|
});
|
272
|
-
|
273
254
|
it('should render dispatch btn for stock issue operation and dont require aproval', async () => {
|
274
255
|
render(
|
275
256
|
<StockOperationForm
|
@@ -281,14 +262,14 @@ describe('Stock Operation form step 3 (stock submision)', () => {
|
|
281
262
|
/>,
|
282
263
|
);
|
283
264
|
// MOVE TO STEP 2
|
284
|
-
await userEvent.click(screen.getByRole('button', { name: /
|
265
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
285
266
|
// MOVE TO STEP3
|
286
|
-
await userEvent.click(screen.getByRole('button', { name: /
|
267
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
287
268
|
|
288
269
|
const noRadioButton = screen.getByRole('radio', { name: /no/i });
|
289
270
|
expect(noRadioButton).toBeInTheDocument();
|
290
271
|
await userEvent.click(noRadioButton);
|
291
|
-
// On require
|
272
|
+
// On require aprooval should now show complete btn
|
292
273
|
expect(screen.getByTestId('dipatch-button')).toBeInTheDocument();
|
293
274
|
});
|
294
275
|
});
|
@@ -1,5 +1,3 @@
|
|
1
|
-
import React, { useCallback, useId, useMemo } from 'react';
|
2
|
-
import { ArrowLeft, ArrowRight, Edit, TrashCan } from '@carbon/react/icons';
|
3
1
|
import {
|
4
2
|
Button,
|
5
3
|
DataTable,
|
@@ -11,6 +9,8 @@ import {
|
|
11
9
|
TableHeader,
|
12
10
|
TableRow,
|
13
11
|
} from '@carbon/react';
|
12
|
+
import { ArrowLeft, ArrowRight, Edit, TrashCan } from '@carbon/react/icons';
|
13
|
+
import React, { useCallback, useMemo } from 'react';
|
14
14
|
import { useFormContext } from 'react-hook-form';
|
15
15
|
import { useTranslation } from 'react-i18next';
|
16
16
|
import { type StockOperationDTO } from '../../../core/api/types/stockOperation/StockOperationDTO';
|
@@ -42,7 +42,6 @@ const StockOperationItemsFormStep: React.FC<StockOperationItemsFormStepProps> =
|
|
42
42
|
}) => {
|
43
43
|
const { t } = useTranslation();
|
44
44
|
const operationTypePermision = useOperationTypePermisions(stockOperationType);
|
45
|
-
const uniqueId = useId();
|
46
45
|
|
47
46
|
const form = useFormContext<StockOperationItemDtoSchema>();
|
48
47
|
const observableOperationItems = form.watch('stockOperationItems');
|
@@ -112,7 +111,7 @@ const StockOperationItemsFormStep: React.FC<StockOperationItemsFormStepProps> =
|
|
112
111
|
);
|
113
112
|
|
114
113
|
const tableRows = useMemo(() => {
|
115
|
-
return observableOperationItems?.map((item
|
114
|
+
return observableOperationItems?.map((item) => {
|
116
115
|
const {
|
117
116
|
batchNo,
|
118
117
|
expiration,
|
@@ -125,7 +124,7 @@ const StockOperationItemsFormStep: React.FC<StockOperationItemsFormStepProps> =
|
|
125
124
|
} = item;
|
126
125
|
|
127
126
|
return {
|
128
|
-
id: uuid
|
127
|
+
id: uuid,
|
129
128
|
item: stockItemUuid ? <StockOperationItemCell stockItemUuid={stockItemUuid} /> : '--',
|
130
129
|
itemDetails: stockItemUuid ? <StockAvailability stockItemUuid={stockItemUuid} /> : '--',
|
131
130
|
batch: (
|
@@ -179,7 +178,7 @@ const StockOperationItemsFormStep: React.FC<StockOperationItemsFormStepProps> =
|
|
179
178
|
),
|
180
179
|
};
|
181
180
|
});
|
182
|
-
}, [observableOperationItems, onLaunchItemsForm, stockOperationType
|
181
|
+
}, [observableOperationItems, onLaunchItemsForm, stockOperationType]);
|
183
182
|
|
184
183
|
const headerTitle = t('stockoperationItems', 'Stock operation items');
|
185
184
|
|