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