@openmrs/esm-stock-management-app 1.0.1-pre.777 → 1.0.1-pre.785
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/__mocks__/index.ts +1 -0
- package/__mocks__/operation-type.mock.ts +532 -0
- package/dist/155.js +1 -0
- package/dist/155.js.map +1 -0
- package/dist/172.js +1 -1
- package/dist/20.js +1 -1
- package/dist/290.js +1 -1
- package/dist/493.js +2 -0
- package/dist/493.js.map +1 -0
- package/dist/606.js +1 -1
- package/dist/627.js +1 -1
- package/dist/{400.js → 914.js} +1 -1
- package/dist/914.js.map +1 -0
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/openmrs-esm-stock-management-app.js +1 -1
- package/dist/openmrs-esm-stock-management-app.js.buildmanifest.json +81 -57
- package/dist/openmrs-esm-stock-management-app.js.map +1 -1
- package/dist/routes.json +1 -1
- package/package.json +1 -1
- package/src/core/utils/utils.ts +29 -0
- package/src/index.ts +4 -0
- package/src/routes.json +9 -0
- package/src/stock-items/add-stock-item/transactions/printout/transactions-stockcard-printout.component.tsx +8 -12
- package/src/stock-items/add-stock-item/transactions/transactions.component.tsx +8 -12
- package/src/stock-items/stock-items.resource.ts +5 -5
- package/src/stock-lookups/stock-lookups.resource.ts +2 -2
- package/src/stock-operations/edit-stock-operation/edit-stock-operation-action-menu.component.tsx +41 -16
- package/src/stock-operations/{add-stock-operation/received-items.component.tsx → received-items.component.tsx} +1 -1
- package/src/stock-operations/stock-operation-reference.component.tsx +64 -0
- package/src/stock-operations/stock-operation-status/stock-operation-status-row.tsx +77 -0
- package/src/stock-operations/stock-operation-status/stock-operation-status.scss +32 -0
- package/src/stock-operations/stock-operation-status/stock-operation-status.tsx +45 -0
- package/src/stock-operations/stock-operation-types-selector/stock-operation-types-selector.component.tsx +30 -29
- package/src/stock-operations/stock-operation.utils.tsx +16 -79
- package/src/stock-operations/stock-operations-dialog/stock-operations-issue-stock-button.component.tsx +27 -39
- package/src/stock-operations/stock-operations-dialog/stock-operations-print-button.component.tsx +51 -59
- package/src/stock-operations/{stock-item-selector/stock-item-selector.resource.tsx → stock-operations-forms/hooks/useFilterableStockItems.ts} +4 -4
- package/src/stock-operations/stock-operations-forms/hooks/useFilteredOperationTypesByRoles.ts +30 -0
- package/src/stock-operations/stock-operations-forms/hooks/useOperationTypePermisions.ts +29 -0
- package/src/stock-operations/stock-operations-forms/hooks/useParties.ts +73 -0
- package/src/stock-operations/{users-selector/users-selector.resource.tsx → stock-operations-forms/hooks/useSearchUser.ts} +9 -7
- package/src/stock-operations/{batch-no-selector/batch-no-selector.resource.tsx → stock-operations-forms/hooks/useStockItemBatchNumbers.ts} +3 -3
- package/src/stock-operations/stock-operations-forms/hooks/useStockOperationLinks.ts +20 -0
- package/src/stock-operations/stock-operations-forms/input-components/batch-no-selector.component.tsx +72 -0
- package/src/stock-operations/stock-operations-forms/input-components/batch-no-selector.test.tsx +90 -0
- package/src/stock-operations/{add-stock-operation/stock-item-search/stock-item-search.scss → stock-operations-forms/input-components/input-components-styles.scss} +2 -2
- package/src/stock-operations/stock-operations-forms/input-components/qty-uim-selector.test.tsx +157 -0
- package/src/stock-operations/stock-operations-forms/input-components/quantity-uom-selector.component.tsx +53 -0
- package/src/stock-operations/stock-operations-forms/input-components/stock-item-search.component.tsx +56 -0
- package/src/stock-operations/stock-operations-forms/input-components/stock-operation-reason-selector.component.tsx +59 -0
- package/src/stock-operations/stock-operations-forms/input-components/stock-operation-reason-selector.test.tsx +216 -0
- package/src/stock-operations/stock-operations-forms/input-components/unique-batch-no-entry-input.component.tsx +59 -0
- package/src/stock-operations/stock-operations-forms/input-components/user-selector.test.tsx +110 -0
- package/src/stock-operations/stock-operations-forms/input-components/users-selector.component.tsx +111 -0
- package/src/stock-operations/stock-operations-forms/step1.test.tsx +303 -0
- package/src/stock-operations/stock-operations-forms/step2.test.tsx +250 -0
- package/src/stock-operations/stock-operations-forms/step3.test.tsx +223 -0
- package/src/stock-operations/stock-operations-forms/steps/base-operation-details-form-step.tsx +241 -0
- package/src/stock-operations/stock-operations-forms/steps/quantity-uom-cell.component.tsx +33 -0
- package/src/stock-operations/stock-operations-forms/steps/stock-availability-cell.component.tsx +51 -0
- package/src/stock-operations/stock-operations-forms/steps/stock-operation-item-batch-no-cell.component.tsx +40 -0
- package/src/stock-operations/stock-operations-forms/steps/stock-operation-item-cell.component.tsx +38 -0
- package/src/stock-operations/stock-operations-forms/steps/stock-operation-item-expiry-cell.component.tsx +41 -0
- package/src/stock-operations/stock-operations-forms/steps/stock-operation-items-form-step.component.tsx +281 -0
- package/src/stock-operations/stock-operations-forms/steps/stock-operation-items-form-step.scc.scss +64 -0
- package/src/stock-operations/stock-operations-forms/steps/stock-operation-submission-form-step.component.tsx +236 -0
- package/src/stock-operations/stock-operations-forms/stock-issue-form-initializer-with-related-requisition-operation.component.tsx +55 -0
- package/src/stock-operations/stock-operations-forms/stock-item-form/stock-item-form.scss +41 -0
- package/src/stock-operations/stock-operations-forms/stock-item-form/stock-item-form.workspace.tsx +197 -0
- package/src/stock-operations/stock-operations-forms/stock-operation-form-header.component.tsx +166 -0
- package/src/stock-operations/stock-operations-forms/stock-operation-form.component.tsx +200 -0
- package/src/stock-operations/stock-operations-forms/stock-operation-form.scss +111 -0
- package/src/stock-operations/stock-operations-forms/stock-operation-related-link.component.tsx +45 -0
- package/src/stock-operations/stock-operations-forms/stock-operation-stepper/stepper.scss +41 -0
- package/src/stock-operations/stock-operations-forms/stock-operation-stepper/stock-operation-stepper.component.tsx +52 -0
- package/src/stock-operations/stock-operations-forms/stock-operations-form-utils.ts +32 -0
- package/src/stock-operations/stock-operations-table.component.tsx +20 -56
- package/src/stock-operations/stock-operations.resource.ts +16 -13
- package/src/stock-operations/validation-schema.ts +72 -14
- package/dist/400.js.map +0 -1
- package/dist/766.js +0 -2
- package/dist/766.js.map +0 -1
- package/src/stock-operations/add-stock-operation/add-stock-operation.component.tsx +0 -349
- package/src/stock-operations/add-stock-operation/add-stock-operation.resource.tsx +0 -27
- package/src/stock-operations/add-stock-operation/add-stock-operation.scss +0 -60
- package/src/stock-operations/add-stock-operation/add-stock-operation.test.tsx +0 -192
- package/src/stock-operations/add-stock-operation/add-stock-operation.utils.tsx +0 -152
- package/src/stock-operations/add-stock-operation/add-stock-utils.ts +0 -103
- package/src/stock-operations/add-stock-operation/base-operation-details.component.tsx +0 -439
- package/src/stock-operations/add-stock-operation/base-operation-details.scss +0 -30
- package/src/stock-operations/add-stock-operation/stock-item-search/stock-item-search.component.tsx +0 -70
- package/src/stock-operations/add-stock-operation/stock-items-addition-row.component.tsx +0 -360
- package/src/stock-operations/add-stock-operation/stock-items-addition-row.resource.tsx +0 -0
- package/src/stock-operations/add-stock-operation/stock-items-addition-row.scss +0 -12
- package/src/stock-operations/add-stock-operation/stock-items-addition-row.test.tsx +0 -10
- package/src/stock-operations/add-stock-operation/stock-items-addition.component.scss +0 -17
- package/src/stock-operations/add-stock-operation/stock-items-addition.component.tsx +0 -254
- package/src/stock-operations/add-stock-operation/stock-operation-context/useStockOperationContext.tsx +0 -16
- package/src/stock-operations/add-stock-operation/stock-operation-reference.component.tsx +0 -39
- package/src/stock-operations/add-stock-operation/stock-operation-related-link.component.tsx +0 -38
- package/src/stock-operations/add-stock-operation/stock-operation-status.component.tsx +0 -170
- package/src/stock-operations/add-stock-operation/stock-operation-submission.component.tsx +0 -189
- package/src/stock-operations/add-stock-operation/stock-operation-submission.test.tsx +0 -138
- package/src/stock-operations/add-stock-operation/types.ts +0 -55
- package/src/stock-operations/add-stock-operation/validationSchema.ts +0 -54
- package/src/stock-operations/batch-no-selector/batch-no-selector.component.tsx +0 -114
- package/src/stock-operations/batch-no-selector/batch-no-selector.scss +0 -0
- package/src/stock-operations/batch-no-selector/batch-no-selector.test.tsx +0 -101
- package/src/stock-operations/party-selector/party-selector.component.tsx +0 -59
- package/src/stock-operations/qty-uom-selector/qty-uom-selector.component.tsx +0 -65
- package/src/stock-operations/qty-uom-selector/qty-uom-selector.resource.tsx +0 -0
- package/src/stock-operations/qty-uom-selector/qty-uom-selector.scss +0 -0
- package/src/stock-operations/qty-uom-selector/qty-uom-selector.test.tsx +0 -10
- package/src/stock-operations/stock-item-selector/stock-item-selector.component.tsx +0 -69
- package/src/stock-operations/stock-item-selector/stock-item-selector.scss +0 -0
- package/src/stock-operations/stock-item-selector/stock-item-selector.test.tsx +0 -10
- package/src/stock-operations/stock-operation-reason-selector/stock-operation-reason-selector.component.tsx +0 -62
- package/src/stock-operations/users-selector/users-selector.component.tsx +0 -75
- /package/dist/{766.js.LICENSE.txt → 493.js.LICENSE.txt} +0 -0
@@ -0,0 +1,250 @@
|
|
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 } from '../stock-operations.resource';
|
6
|
+
import { StockOperationDTO } from '../../core/api/types/stockOperation/StockOperationDTO';
|
7
|
+
import { StockOperationType } from '../../core/api/types/stockOperation/StockOperationType';
|
8
|
+
import { useStockOperations } from '../stock-operations.resource';
|
9
|
+
import { closeOverlay } from '../../core/components/overlay/hook';
|
10
|
+
import StockOperationForm from './stock-operation-form.component';
|
11
|
+
import useParties from './hooks/useParties';
|
12
|
+
import userEvent from '@testing-library/user-event';
|
13
|
+
import { StockItemDTO } from '../../core/api/types/stockItem/StockItem';
|
14
|
+
import { useStockItem, useStockItems, useStockBatches } from '../../stock-items/stock-items.resource';
|
15
|
+
import { initialStockOperationValue } from '../../core/utils/utils';
|
16
|
+
import { useForm, useFormContext, Controller, FormProvider } from 'react-hook-form';
|
17
|
+
import { BaseStockOperationItemFormData, StockOperationItemFormData } from '../validation-schema';
|
18
|
+
import { useStockItemBatchInformationHook } from '../../stock-items/add-stock-item/batch-information/batch-information.resource';
|
19
|
+
import { useFilterableStockItems } from './hooks/useFilterableStockItems';
|
20
|
+
import { formatForDatePicker } from '../../constants';
|
21
|
+
import { receiptOperationTypeMock } from '../../../__mocks__';
|
22
|
+
jest.mock('react-i18next', () => ({
|
23
|
+
useTranslation: jest.fn().mockReturnValue({ t: (key) => key }),
|
24
|
+
}));
|
25
|
+
|
26
|
+
jest.mock('@openmrs/esm-framework', () => ({
|
27
|
+
ActionMenu: jest.fn(() => null),
|
28
|
+
showSnackbar: jest.fn(),
|
29
|
+
useDebounce: jest.fn((x) => x),
|
30
|
+
getGlobalStore: jest.fn(() => ({
|
31
|
+
getState: jest.fn(),
|
32
|
+
subscribe: jest.fn(),
|
33
|
+
setState: jest.fn(),
|
34
|
+
})),
|
35
|
+
parseDate: jest.fn((date) => new Date(date)),
|
36
|
+
showNotification: jest.fn(),
|
37
|
+
usePagination: jest.fn(() => ({ currentPage: 1, setPage: jest.fn() })),
|
38
|
+
useSession: jest.fn(() => ({ user: { display: 'Test User' } })),
|
39
|
+
useConfig: jest.fn(),
|
40
|
+
ErrorState: jest.fn(({ error }: { error: any }) => <div>{error}</div>),
|
41
|
+
launchWorkspace: jest.fn(),
|
42
|
+
}));
|
43
|
+
|
44
|
+
jest.mock('../../stock-lookups/stock-lookups.resource', () => ({
|
45
|
+
useStockOperationTypes: jest.fn(),
|
46
|
+
useUsers: jest.fn().mockReturnValue({ items: { results: [] }, isLoading: false }),
|
47
|
+
useUser: jest.fn().mockReturnValue({ data: { display: 'Test User' }, isLoading: false, error: null }),
|
48
|
+
}));
|
49
|
+
|
50
|
+
jest.mock('../stock-operations.resource', () => ({
|
51
|
+
operationStatusColor: jest.fn(() => 'some-color'),
|
52
|
+
getStockOperationLinks: jest.fn(),
|
53
|
+
useStockOperations: jest.fn().mockReturnValue({
|
54
|
+
items: { results: [] },
|
55
|
+
isLoading: false,
|
56
|
+
error: null,
|
57
|
+
}),
|
58
|
+
}));
|
59
|
+
|
60
|
+
jest.mock('../../core/components/overlay/hook', () => ({
|
61
|
+
closeOverlay: jest.fn(),
|
62
|
+
}));
|
63
|
+
|
64
|
+
jest.mock('../../stock-items/stock-items.resource', () => ({
|
65
|
+
useStockItem: jest.fn(),
|
66
|
+
useStockItems: jest.fn().mockReturnValue({
|
67
|
+
isLoading: false,
|
68
|
+
error: null,
|
69
|
+
items: {},
|
70
|
+
}),
|
71
|
+
useStockBatches: jest.fn().mockReturnValue({
|
72
|
+
isLoading: false,
|
73
|
+
error: null,
|
74
|
+
|
75
|
+
items: {},
|
76
|
+
}),
|
77
|
+
}));
|
78
|
+
jest.mock('./hooks/useFilterableStockItems', () => ({
|
79
|
+
useFilterableStockItems: jest.fn().mockReturnValue({
|
80
|
+
stockItemsList: [],
|
81
|
+
setLimit: jest.fn(),
|
82
|
+
setRepresentation: jest.fn(),
|
83
|
+
setSearchString: jest.fn(),
|
84
|
+
isLoading: false,
|
85
|
+
}),
|
86
|
+
}));
|
87
|
+
jest.mock('./hooks/useParties', () => jest.fn());
|
88
|
+
jest.mock('react-hook-form', () => ({
|
89
|
+
useForm: jest.fn().mockReturnValue({
|
90
|
+
watch: jest.fn(),
|
91
|
+
formState: {
|
92
|
+
errors: {},
|
93
|
+
},
|
94
|
+
resetField: jest.fn(),
|
95
|
+
getValues: jest.fn(),
|
96
|
+
setValue: jest.fn(),
|
97
|
+
handleSubmit: jest.fn(),
|
98
|
+
}),
|
99
|
+
useFormContext: jest.fn().mockReturnValue({
|
100
|
+
watch: jest.fn(),
|
101
|
+
formState: {
|
102
|
+
errors: {},
|
103
|
+
},
|
104
|
+
resetField: jest.fn(),
|
105
|
+
getValues: jest.fn(),
|
106
|
+
setValue: jest.fn(),
|
107
|
+
handleSubmit: jest.fn(),
|
108
|
+
}),
|
109
|
+
Controller: ({ render }) => render({ field: {}, fieldState: {} }),
|
110
|
+
FormProvider: ({ children }: { children: React.ReactNode }) => <>{children}</>,
|
111
|
+
}));
|
112
|
+
|
113
|
+
jest.mock('../../stock-items/add-stock-item/batch-information/batch-information.resource', () => ({
|
114
|
+
useStockItemBatchInformationHook: jest.fn().mockReturnValue({
|
115
|
+
items: [],
|
116
|
+
totalCount: 0,
|
117
|
+
currentPage: 1,
|
118
|
+
currentPageSize: 10,
|
119
|
+
setCurrentPage: jest.fn(),
|
120
|
+
setPageSize: jest.fn(),
|
121
|
+
pageSizes: [],
|
122
|
+
isLoading: false,
|
123
|
+
error: undefined,
|
124
|
+
setSearchString: jest.fn(),
|
125
|
+
setStockItemUuid: jest.fn(),
|
126
|
+
setLocationUuid: jest.fn(),
|
127
|
+
setPartyUuid: jest.fn(),
|
128
|
+
setStockBatchUuid: jest.fn(),
|
129
|
+
}),
|
130
|
+
}));
|
131
|
+
|
132
|
+
describe('Stock Operation step 2 (stock operation items details)', () => {
|
133
|
+
beforeEach(() => {
|
134
|
+
const mockStockOperationTypes = { results: [] };
|
135
|
+
(useStockOperationTypes as jest.Mock).mockReturnValue(mockStockOperationTypes);
|
136
|
+
(useStockOperations as jest.Mock).mockReturnValue({ items: { results: [] }, isLoading: false, error: null });
|
137
|
+
(useConfig as jest.Mock).mockReturnValue({ autoPopulateResponsiblePerson: true });
|
138
|
+
(useParties as jest.Mock).mockReturnValue({
|
139
|
+
destinationParties: [],
|
140
|
+
sourceParties: [],
|
141
|
+
isLoading: false,
|
142
|
+
error: undefined,
|
143
|
+
sourceTags: [],
|
144
|
+
destinationTags: [],
|
145
|
+
});
|
146
|
+
});
|
147
|
+
|
148
|
+
it('should have both previous and next btns', async () => {
|
149
|
+
render(<StockOperationForm stockOperationType={receiptOperationTypeMock as any} />);
|
150
|
+
// MOVE TO STEP 2
|
151
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
152
|
+
|
153
|
+
expect(screen.getByRole('button', { name: /Next/i })).toBeInTheDocument();
|
154
|
+
expect(screen.getByRole('button', { name: /previous/i })).toBeInTheDocument();
|
155
|
+
});
|
156
|
+
|
157
|
+
it('should render stock operation items table with item search component', async () => {
|
158
|
+
render(<StockOperationForm stockOperationType={receiptOperationTypeMock as any} />);
|
159
|
+
const nextButton = screen.getByRole('button', { name: /Next/i });
|
160
|
+
expect(nextButton).toBeInTheDocument();
|
161
|
+
await userEvent.click(nextButton);
|
162
|
+
expect(screen.getByRole('table')).toBeInTheDocument();
|
163
|
+
expect(
|
164
|
+
screen.getByRole('searchbox', {
|
165
|
+
name(accessibleName, element) {
|
166
|
+
return (
|
167
|
+
element.getAttribute('id') === 'search-stock-operation-item' &&
|
168
|
+
element.getAttribute('placeholder') === 'findItems' &&
|
169
|
+
element.getAttribute('name') === 'search-stock-operation-item'
|
170
|
+
);
|
171
|
+
},
|
172
|
+
}),
|
173
|
+
).toBeInTheDocument();
|
174
|
+
});
|
175
|
+
|
176
|
+
it('should search stock operation item and render results', async () => {
|
177
|
+
const mocksetSearchString = jest.fn();
|
178
|
+
(useFilterableStockItems as jest.Mock).mockReturnValue({
|
179
|
+
stockItemsList: [{ uuid: 'mock-uuid', commonName: 'mock-common-name' }] as Array<StockItemDTO>,
|
180
|
+
setLimit: jest.fn(),
|
181
|
+
setRepresentation: jest.fn(),
|
182
|
+
isLoading: false,
|
183
|
+
setSearchString: mocksetSearchString,
|
184
|
+
});
|
185
|
+
render(<StockOperationForm stockOperationType={receiptOperationTypeMock as any} />);
|
186
|
+
// ----- CLICK NEXT TO MOVE TO STEP 2 ---------
|
187
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
188
|
+
// -------------------------------
|
189
|
+
const searchInput = screen.getByRole('searchbox', {
|
190
|
+
name: (_, element) => element.getAttribute('id') === 'search-stock-operation-item',
|
191
|
+
});
|
192
|
+
expect(searchInput).toBeInTheDocument();
|
193
|
+
await userEvent.click(searchInput);
|
194
|
+
await userEvent.type(searchInput, 'stock');
|
195
|
+
expect(mocksetSearchString).toHaveBeenCalledWith('stock');
|
196
|
+
expect(screen.getByText('mock-common-name'));
|
197
|
+
});
|
198
|
+
|
199
|
+
it('should properly handle stock operation item selection', async () => {
|
200
|
+
(useFilterableStockItems as jest.Mock).mockReturnValue({
|
201
|
+
stockItemsList: [{ uuid: 'mock-uuid', commonName: 'mock-common-name' }] as Array<StockItemDTO>,
|
202
|
+
setLimit: jest.fn(),
|
203
|
+
setRepresentation: jest.fn(),
|
204
|
+
isLoading: false,
|
205
|
+
setSearchString: jest.fn(),
|
206
|
+
});
|
207
|
+
render(<StockOperationForm stockOperationType={receiptOperationTypeMock as any} />);
|
208
|
+
// ----- CLICK NEXT TO MOVE TO STEP 2 ---------
|
209
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
210
|
+
// -------------------------------
|
211
|
+
const searchInput = screen.getByRole('searchbox', {
|
212
|
+
name: (_, element) => element.getAttribute('id') === 'search-stock-operation-item',
|
213
|
+
});
|
214
|
+
await userEvent.click(searchInput);
|
215
|
+
await userEvent.type(searchInput, 'stock');
|
216
|
+
await userEvent.click(screen.getByText('mock-common-name'));
|
217
|
+
expect(launchWorkspace).toHaveBeenCalled();
|
218
|
+
});
|
219
|
+
|
220
|
+
it('should render stock operation items in data table', async () => {
|
221
|
+
(useStockItem as jest.Mock).mockReturnValue({
|
222
|
+
isLoading: false,
|
223
|
+
error: null,
|
224
|
+
item: { commonName: 'mock-stock-item-common name', uuid: 'mock-uuid' } as StockItemDTO,
|
225
|
+
});
|
226
|
+
const mockQuantity = 99999;
|
227
|
+
const mockExpiration = new Date();
|
228
|
+
(useFormContext as jest.Mock).mockReturnValue({
|
229
|
+
watch: jest.fn().mockReturnValue([
|
230
|
+
{
|
231
|
+
quantity: mockQuantity,
|
232
|
+
expiration: mockExpiration,
|
233
|
+
},
|
234
|
+
] as BaseStockOperationItemFormData),
|
235
|
+
resetField: jest.fn(),
|
236
|
+
formState: {
|
237
|
+
errors: {},
|
238
|
+
},
|
239
|
+
getValues: jest.fn(),
|
240
|
+
setValue: jest.fn(),
|
241
|
+
handleSubmit: jest.fn(),
|
242
|
+
});
|
243
|
+
render(<StockOperationForm stockOperationType={receiptOperationTypeMock as any} />);
|
244
|
+
// ----- CLICK NEXT TO MOVE TO STEP 2 ---------
|
245
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
246
|
+
// -------------------------------
|
247
|
+
expect(screen.getByText(mockQuantity.toLocaleString())).toBeInTheDocument(); //Find by quentity
|
248
|
+
expect(screen.getByText(formatForDatePicker(mockExpiration))).toBeInTheDocument(); //Find by quentity
|
249
|
+
});
|
250
|
+
});
|
@@ -0,0 +1,223 @@
|
|
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 } from '../stock-operations.resource';
|
5
|
+
import { StockOperationDTO } from '../../core/api/types/stockOperation/StockOperationDTO';
|
6
|
+
import { StockOperationType } from '../../core/api/types/stockOperation/StockOperationType';
|
7
|
+
import { useStockOperations } from '../stock-operations.resource';
|
8
|
+
import { closeOverlay } from '../../core/components/overlay/hook';
|
9
|
+
import StockOperationForm from './stock-operation-form.component';
|
10
|
+
import useParties from './hooks/useParties';
|
11
|
+
import userEvent from '@testing-library/user-event';
|
12
|
+
import { StockItemDTO } from '../../core/api/types/stockItem/StockItem';
|
13
|
+
import { useStockItem, useStockItems } 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 { BaseStockOperationItemFormData, StockOperationItemFormData } from '../validation-schema';
|
17
|
+
import { useStockItemBatchInformationHook } from '../../stock-items/add-stock-item/batch-information/batch-information.resource';
|
18
|
+
import { useFilterableStockItems } from './hooks/useFilterableStockItems';
|
19
|
+
import { formatForDatePicker } from '../../constants';
|
20
|
+
import React from 'react';
|
21
|
+
import { receiptOperationTypeMock, returnOperationTypeMock, stockIssueOperationtypeMock } from '../../../__mocks__';
|
22
|
+
jest.mock('react-i18next', () => ({
|
23
|
+
useTranslation: jest.fn().mockReturnValue({ t: (key) => key }),
|
24
|
+
}));
|
25
|
+
|
26
|
+
jest.mock('@openmrs/esm-framework', () => ({
|
27
|
+
ActionMenu: jest.fn(() => null),
|
28
|
+
showSnackbar: jest.fn(),
|
29
|
+
useDebounce: jest.fn((x) => x),
|
30
|
+
getGlobalStore: jest.fn(() => ({
|
31
|
+
getState: jest.fn(),
|
32
|
+
subscribe: jest.fn(),
|
33
|
+
setState: jest.fn(),
|
34
|
+
})),
|
35
|
+
parseDate: jest.fn((date) => new Date(date)),
|
36
|
+
showNotification: jest.fn(),
|
37
|
+
usePagination: jest.fn(() => ({ currentPage: 1, setPage: jest.fn() })),
|
38
|
+
useSession: jest.fn(() => ({ user: { display: 'Test User' } })),
|
39
|
+
useConfig: jest.fn(),
|
40
|
+
ErrorState: jest.fn(({ error }: { error: any }) => <div>{error}</div>),
|
41
|
+
launchWorkspace: jest.fn(),
|
42
|
+
}));
|
43
|
+
|
44
|
+
jest.mock('../../stock-lookups/stock-lookups.resource', () => ({
|
45
|
+
useStockOperationTypes: jest.fn(),
|
46
|
+
useUsers: jest.fn().mockReturnValue({ items: { results: [] }, isLoading: false }),
|
47
|
+
useUser: jest.fn().mockReturnValue({ data: { display: 'Test User' }, isLoading: false, error: null }),
|
48
|
+
}));
|
49
|
+
|
50
|
+
jest.mock('../stock-operations.resource', () => ({
|
51
|
+
operationStatusColor: jest.fn(() => 'some-color'),
|
52
|
+
getStockOperationLinks: jest.fn(),
|
53
|
+
useStockOperations: jest.fn().mockReturnValue({
|
54
|
+
items: { results: [] },
|
55
|
+
isLoading: false,
|
56
|
+
error: null,
|
57
|
+
}),
|
58
|
+
useStockOperation: jest.fn().mockReturnValue({
|
59
|
+
items: undefined,
|
60
|
+
isLoading: false,
|
61
|
+
error: null,
|
62
|
+
}),
|
63
|
+
}));
|
64
|
+
|
65
|
+
jest.mock('../../core/components/overlay/hook', () => ({
|
66
|
+
closeOverlay: jest.fn(),
|
67
|
+
}));
|
68
|
+
|
69
|
+
jest.mock('../../stock-items/stock-items.resource', () => ({
|
70
|
+
useStockItem: jest.fn(),
|
71
|
+
useStockItems: jest.fn().mockReturnValue({
|
72
|
+
isLoading: false,
|
73
|
+
error: null,
|
74
|
+
items: {},
|
75
|
+
}),
|
76
|
+
}));
|
77
|
+
jest.mock('./hooks/useFilterableStockItems', () => ({
|
78
|
+
useFilterableStockItems: jest.fn().mockReturnValue({
|
79
|
+
stockItemsList: [],
|
80
|
+
setLimit: jest.fn(),
|
81
|
+
setRepresentation: jest.fn(),
|
82
|
+
setSearchString: jest.fn(),
|
83
|
+
isLoading: false,
|
84
|
+
}),
|
85
|
+
}));
|
86
|
+
jest.mock('./hooks/useParties', () => jest.fn());
|
87
|
+
jest.mock('react-hook-form', () => ({
|
88
|
+
useForm: jest.fn().mockReturnValue({
|
89
|
+
watch: jest.fn(),
|
90
|
+
formState: {
|
91
|
+
errors: {},
|
92
|
+
},
|
93
|
+
resetField: jest.fn(),
|
94
|
+
getValues: jest.fn(),
|
95
|
+
setValue: jest.fn(),
|
96
|
+
handleSubmit: jest.fn(),
|
97
|
+
}),
|
98
|
+
useFormContext: jest.fn().mockReturnValue({
|
99
|
+
watch: jest.fn(),
|
100
|
+
formState: {
|
101
|
+
errors: {},
|
102
|
+
},
|
103
|
+
resetField: jest.fn(),
|
104
|
+
getValues: jest.fn(),
|
105
|
+
setValue: jest.fn(),
|
106
|
+
handleSubmit: jest.fn(),
|
107
|
+
}),
|
108
|
+
Controller: ({ render }) => render({ field: {}, fieldState: {} }),
|
109
|
+
FormProvider: ({ children }: { children: React.ReactNode }) => <>{children}</>,
|
110
|
+
}));
|
111
|
+
|
112
|
+
jest.mock('../../stock-items/add-stock-item/batch-information/batch-information.resource', () => ({
|
113
|
+
useStockItemBatchInformationHook: jest.fn().mockReturnValue({
|
114
|
+
items: [],
|
115
|
+
totalCount: 0,
|
116
|
+
currentPage: 1,
|
117
|
+
currentPageSize: 10,
|
118
|
+
setCurrentPage: jest.fn(),
|
119
|
+
setPageSize: jest.fn(),
|
120
|
+
pageSizes: [],
|
121
|
+
isLoading: false,
|
122
|
+
error: undefined,
|
123
|
+
setSearchString: jest.fn(),
|
124
|
+
setStockItemUuid: jest.fn(),
|
125
|
+
setLocationUuid: jest.fn(),
|
126
|
+
setPartyUuid: jest.fn(),
|
127
|
+
setStockBatchUuid: jest.fn(),
|
128
|
+
}),
|
129
|
+
}));
|
130
|
+
|
131
|
+
describe('Stock Operation form step 3 (stock submision)', () => {
|
132
|
+
beforeEach(() => {
|
133
|
+
const mockStockOperationTypes = { results: [] };
|
134
|
+
(useStockOperationTypes as jest.Mock).mockReturnValue(mockStockOperationTypes);
|
135
|
+
(useStockOperations as jest.Mock).mockReturnValue({ items: { results: [] }, isLoading: false, error: null });
|
136
|
+
(useConfig as jest.Mock).mockReturnValue({ autoPopulateResponsiblePerson: true });
|
137
|
+
(useParties as jest.Mock).mockReturnValue({
|
138
|
+
destinationParties: [],
|
139
|
+
sourceParties: [],
|
140
|
+
isLoading: false,
|
141
|
+
error: undefined,
|
142
|
+
sourceTags: [],
|
143
|
+
destinationTags: [],
|
144
|
+
});
|
145
|
+
});
|
146
|
+
|
147
|
+
it('should have previous btn and not next btn', async () => {
|
148
|
+
render(<StockOperationForm stockOperationType={receiptOperationTypeMock as any} />);
|
149
|
+
// MOVE TO STEP 2
|
150
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
151
|
+
// MOVE TO STEP3
|
152
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
153
|
+
|
154
|
+
expect(screen.queryByRole('button', { name: /Next/i })).not.toBeInTheDocument();
|
155
|
+
expect(screen.getByRole('button', { name: /previous/i })).toBeInTheDocument();
|
156
|
+
});
|
157
|
+
|
158
|
+
it('should render require approval radio button and save button', async () => {
|
159
|
+
render(<StockOperationForm stockOperationType={receiptOperationTypeMock as any} />);
|
160
|
+
// MOVE TO STEP 2
|
161
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
162
|
+
// MOVE TO STEP3
|
163
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
164
|
+
|
165
|
+
// Shouls have save button
|
166
|
+
expect(screen.getByRole('button', { name: /save/i })).toBeInTheDocument();
|
167
|
+
expect(screen.getAllByRole('radio', { name: /yes|no/i })).toHaveLength(2);
|
168
|
+
});
|
169
|
+
it('should render submitForReview button when require aprroval radion button is checked yes', async () => {
|
170
|
+
render(<StockOperationForm stockOperationType={receiptOperationTypeMock as any} />);
|
171
|
+
// MOVE TO STEP 2
|
172
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
173
|
+
// MOVE TO STEP3
|
174
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
175
|
+
|
176
|
+
const yesRadioButton = screen.getByRole('radio', { name: /yes/i });
|
177
|
+
expect(yesRadioButton).toBeInTheDocument();
|
178
|
+
// Submit for review shouldnt be in doc
|
179
|
+
expect(screen.queryByRole('button', { name: /submitForReview/i })).not.toBeInTheDocument();
|
180
|
+
await userEvent.click(yesRadioButton);
|
181
|
+
// On require aprooval should now show
|
182
|
+
expect(screen.getByRole('button', { name: /submitForReview/i })).toBeInTheDocument();
|
183
|
+
});
|
184
|
+
it('should render complete button when require aprroval radion button is checked no', async () => {
|
185
|
+
render(<StockOperationForm stockOperationType={receiptOperationTypeMock as any} />);
|
186
|
+
// MOVE TO STEP 2
|
187
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
188
|
+
// MOVE TO STEP3
|
189
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
190
|
+
|
191
|
+
const noRadioButton = screen.getByRole('radio', { name: /no/i });
|
192
|
+
expect(noRadioButton).toBeInTheDocument();
|
193
|
+
await userEvent.click(noRadioButton);
|
194
|
+
// On require aprooval should now show complete btn
|
195
|
+
expect(screen.getByRole('button', { name: /complete/i })).toBeInTheDocument();
|
196
|
+
});
|
197
|
+
it('should render dispatch btn for stock return operation and dont require aproval', async () => {
|
198
|
+
render(<StockOperationForm stockOperationType={returnOperationTypeMock as any} />);
|
199
|
+
// MOVE TO STEP 2
|
200
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
201
|
+
// MOVE TO STEP3
|
202
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
203
|
+
|
204
|
+
const noRadioButton = screen.getByRole('radio', { name: /no/i });
|
205
|
+
expect(noRadioButton).toBeInTheDocument();
|
206
|
+
await userEvent.click(noRadioButton);
|
207
|
+
// On require aprooval should now show complete btn
|
208
|
+
expect(screen.getByRole('button', { name: /dispatch/i })).toBeInTheDocument();
|
209
|
+
});
|
210
|
+
it('should render dispatch btn for stock issue operation and dont require aproval', async () => {
|
211
|
+
render(<StockOperationForm stockOperationType={stockIssueOperationtypeMock as any} />);
|
212
|
+
// MOVE TO STEP 2
|
213
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
214
|
+
// MOVE TO STEP3
|
215
|
+
await userEvent.click(screen.getByRole('button', { name: /Next/i }));
|
216
|
+
|
217
|
+
const noRadioButton = screen.getByRole('radio', { name: /no/i });
|
218
|
+
expect(noRadioButton).toBeInTheDocument();
|
219
|
+
await userEvent.click(noRadioButton);
|
220
|
+
// On require aprooval should now show complete btn
|
221
|
+
expect(screen.getByRole('button', { name: /dispatch/i })).toBeInTheDocument();
|
222
|
+
});
|
223
|
+
});
|