@openmrs/esm-stock-management-app 1.0.1-pre.641 → 1.0.1-pre.652

Sign up to get free protection for your applications and to get access to all the features.
package/dist/routes.json CHANGED
@@ -1 +1 @@
1
- {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"fhir2":">=1.2","webservices.rest":"^2.24.0"},"extensions":[{"name":"stock-nav-menu","slot":"stock-sidebar-slot","component":"stockNavMenu","online":true,"offline":true},{"name":"overview-db-link","slot":"stock-page-dashboard-slot","component":"stockOverviewLink","meta":{"name":"overview","slot":"overview-dashboard-slot","title":"overview"},"order":0,"online":true,"offline":true},{"name":"stock-overview-db","slot":"overview-dashboard-slot","component":"stockOverview"},{"name":"operations-db-link","slot":"stock-page-dashboard-slot","component":"stockOperationsLink","meta":{"name":"operations","slot":"operations-dashboard-slot","title":"operations"},"order":2,"online":true,"offline":true},{"name":"stock-operations-db","slot":"operations-dashboard-slot","component":"stockOperations"},{"name":"items-db-link","slot":"stock-page-dashboard-slot","component":"stockItemsLink","meta":{"name":"items","slot":"items-dashboard-slot","title":"items"},"order":1,"online":true,"offline":true},{"name":"stock-items-db","slot":"items-dashboard-slot","component":"stockItems"},{"name":"user-scopes-db-link","slot":"stock-page-dashboard-slot","component":"stockUserScopesLink","meta":{"name":"user-scopes","slot":"user-scopes-dashboard-slot","title":"user-scopes"},"order":3,"online":true,"offline":true},{"name":"stock-user-scopes-db","slot":"user-scopes-dashboard-slot","component":"stockUserScopes"},{"name":"sources-db-link","slot":"stock-page-dashboard-slot","component":"stockSourcesLink","meta":{"name":"sources","slot":"sources-dashboard-slot","title":"Sources"},"order":2,"online":true,"offline":true},{"name":"stock-sources-db","slot":"sources-dashboard-slot","component":"stockSources"},{"name":"locations-db-link","slot":"stock-page-dashboard-slot","component":"stockLocationsLink","meta":{"name":"locations","slot":"locations-dashboard-slot","title":"Locations"},"order":4,"online":true,"offline":true},{"name":"stock-locations-db","slot":"locations-dashboard-slot","component":"stockLocations"},{"name":"reports-db-link","slot":"stock-page-dashboard-slot","component":"stockReportsLink","meta":{"name":"reports","slot":"reports-dashboard-slot","title":"Reports"},"order":5,"online":true,"offline":true},{"name":"stock-reports-db","slot":"reports-dashboard-slot","component":"stockReports"},{"name":"settings-db-link","slot":"stock-page-dashboard-slot","component":"stockSettingsLink","meta":{"name":"settings","slot":"settings-dashboard-slot","title":"Settings"},"order":6,"online":true,"offline":true},{"name":"stock-settings-db","slot":"settings-dashboard-slot","component":"stockSettings"},{"name":"stock-management-admin-card-link","slot":"system-admin-page-card-link-slot","component":"stockManagementAdminCardLink"},{"name":"stock-operation-dialog","component":"stockOperationDialog"},{"name":"import-bulk-stock-items","component":"importBulkStockItemsDialog"},{"name":"delete-stock-modal","component":"deleteStockModal"},{"name":"delete-stock-user-scope-modal","component":"deleteUserScopeModal"},{"name":"stock-management-app-menu-item","component":"stockManagementAppMenuItem","slot":"app-menu-item-slot","meta":{"name":" Stock Management"}},{"name":"delete-stock-rule-modal","component":"deleteStockRuleModal"},{"name":"delete-packaging-unit-modal","component":"deletePackagingUnitModal"},{"name":"delete-packaging-unit-button","component":"deletePackagingUnitButton"}],"pages":[{"component":"root","route":"stock-management"}],"version":"1.0.1-pre.641"}
1
+ {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"fhir2":">=1.2","webservices.rest":"^2.24.0"},"extensions":[{"name":"stock-nav-menu","slot":"stock-sidebar-slot","component":"stockNavMenu","online":true,"offline":true},{"name":"overview-db-link","slot":"stock-page-dashboard-slot","component":"stockOverviewLink","meta":{"name":"overview","slot":"overview-dashboard-slot","title":"overview"},"order":0,"online":true,"offline":true},{"name":"stock-overview-db","slot":"overview-dashboard-slot","component":"stockOverview"},{"name":"operations-db-link","slot":"stock-page-dashboard-slot","component":"stockOperationsLink","meta":{"name":"operations","slot":"operations-dashboard-slot","title":"operations"},"order":2,"online":true,"offline":true},{"name":"stock-operations-db","slot":"operations-dashboard-slot","component":"stockOperations"},{"name":"items-db-link","slot":"stock-page-dashboard-slot","component":"stockItemsLink","meta":{"name":"items","slot":"items-dashboard-slot","title":"items"},"order":1,"online":true,"offline":true},{"name":"stock-items-db","slot":"items-dashboard-slot","component":"stockItems"},{"name":"user-scopes-db-link","slot":"stock-page-dashboard-slot","component":"stockUserScopesLink","meta":{"name":"user-scopes","slot":"user-scopes-dashboard-slot","title":"user-scopes"},"order":3,"online":true,"offline":true},{"name":"stock-user-scopes-db","slot":"user-scopes-dashboard-slot","component":"stockUserScopes"},{"name":"sources-db-link","slot":"stock-page-dashboard-slot","component":"stockSourcesLink","meta":{"name":"sources","slot":"sources-dashboard-slot","title":"Sources"},"order":2,"online":true,"offline":true},{"name":"stock-sources-db","slot":"sources-dashboard-slot","component":"stockSources"},{"name":"locations-db-link","slot":"stock-page-dashboard-slot","component":"stockLocationsLink","meta":{"name":"locations","slot":"locations-dashboard-slot","title":"Locations"},"order":4,"online":true,"offline":true},{"name":"stock-locations-db","slot":"locations-dashboard-slot","component":"stockLocations"},{"name":"reports-db-link","slot":"stock-page-dashboard-slot","component":"stockReportsLink","meta":{"name":"reports","slot":"reports-dashboard-slot","title":"Reports"},"order":5,"online":true,"offline":true},{"name":"stock-reports-db","slot":"reports-dashboard-slot","component":"stockReports"},{"name":"settings-db-link","slot":"stock-page-dashboard-slot","component":"stockSettingsLink","meta":{"name":"settings","slot":"settings-dashboard-slot","title":"Settings"},"order":6,"online":true,"offline":true},{"name":"stock-settings-db","slot":"settings-dashboard-slot","component":"stockSettings"},{"name":"stock-management-admin-card-link","slot":"system-admin-page-card-link-slot","component":"stockManagementAdminCardLink"},{"name":"stock-operation-dialog","component":"stockOperationDialog"},{"name":"import-bulk-stock-items","component":"importBulkStockItemsDialog"},{"name":"delete-stock-modal","component":"deleteStockModal"},{"name":"delete-stock-user-scope-modal","component":"deleteUserScopeModal"},{"name":"stock-management-app-menu-item","component":"stockManagementAppMenuItem","slot":"app-menu-item-slot","meta":{"name":" Stock Management"}},{"name":"delete-stock-rule-modal","component":"deleteStockRuleModal"},{"name":"delete-packaging-unit-modal","component":"deletePackagingUnitModal"},{"name":"delete-packaging-unit-button","component":"deletePackagingUnitButton"}],"pages":[{"component":"root","route":"stock-management"}],"version":"1.0.1-pre.652"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openmrs/esm-stock-management-app",
3
- "version": "1.0.1-pre.641",
3
+ "version": "1.0.1-pre.652",
4
4
  "license": "MPL-2.0",
5
5
  "description": "Stock management microfrontend for OpenMRS 3.x",
6
6
  "browser": "dist/openmrs-esm-stock-management-app.js",
@@ -0,0 +1,138 @@
1
+ import React from 'react';
2
+ import { render, waitFor, screen } from '@testing-library/react';
3
+ import StockOperationSubmission from './stock-operation-submission.component';
4
+ import { StockOperationDTO } from '../../core/api/types/stockOperation/StockOperationDTO';
5
+ import { StockOperationType } from '../../core/api/types/stockOperation/StockOperationType';
6
+ import { InitializeResult } from './types';
7
+ import userEvent from '@testing-library/user-event';
8
+
9
+ const mockOnGoBack = jest.fn();
10
+ const mockOnSave = jest.fn();
11
+ const mockOnComplete = jest.fn();
12
+ const mockOnSubmit = jest.fn();
13
+ const mockOnDispatch = jest.fn();
14
+ const defaultProps = {
15
+ canEdit: true,
16
+ locked: false,
17
+ model: { approvalRequired: null } as StockOperationDTO,
18
+ operation: {
19
+ name: 'Stock Issue',
20
+ description: 'Issuing stock',
21
+ operationType: 'stockissue',
22
+ hasSource: true,
23
+ sourceType: {},
24
+ hasDestination: true,
25
+ destinationType: {},
26
+ hasRecipient: false,
27
+ recipientRequired: false,
28
+ availableWhenReserved: false,
29
+ allowExpiredBatchNumbers: false,
30
+ stockOperationTypeLocationScopes: [],
31
+ } as StockOperationType,
32
+ setup: {
33
+ isNegativeQuantityAllowed: false,
34
+ requiresBatchUuid: false,
35
+ requiresActualBatchInfo: false,
36
+ isQuantityOptional: false,
37
+ } as InitializeResult,
38
+ actions: {
39
+ onGoBack: mockOnGoBack,
40
+ onSave: mockOnSave,
41
+ onComplete: mockOnComplete,
42
+ onSubmit: mockOnSubmit,
43
+ onDispatch: mockOnDispatch,
44
+ },
45
+ };
46
+
47
+ describe('StockOperationSubmission', () => {
48
+ let user;
49
+
50
+ beforeEach(() => {
51
+ jest.clearAllMocks();
52
+ user = userEvent.setup();
53
+ });
54
+
55
+ it('renders without crashing', () => {
56
+ render(<StockOperationSubmission {...defaultProps} />);
57
+ expect(screen.getByText(/does the transaction require approval/i)).toBeInTheDocument();
58
+ });
59
+
60
+ it('allows approval required to be selected', async () => {
61
+ render(<StockOperationSubmission {...defaultProps} />);
62
+ await user.click(screen.getByLabelText(/yes/i));
63
+ const yesRadioButton = screen.getByLabelText(/yes/i) as HTMLInputElement;
64
+ expect(yesRadioButton.checked).toBe(true);
65
+ });
66
+
67
+ it('allows approval not required to be selected', async () => {
68
+ render(<StockOperationSubmission {...defaultProps} />);
69
+ await user.click(screen.getByLabelText(/no/i));
70
+ const noRadioButton = screen.getByLabelText(/no/i) as HTMLInputElement;
71
+ expect(noRadioButton.checked).toBe(true);
72
+ });
73
+
74
+ it('calls onGoBack when Go Back button is clicked', async () => {
75
+ render(<StockOperationSubmission {...defaultProps} />);
76
+ await user.click(screen.getByText(/go back/i));
77
+ expect(mockOnGoBack).toHaveBeenCalled();
78
+ });
79
+
80
+ it('shows loading indicator when saving', async () => {
81
+ render(<StockOperationSubmission {...defaultProps} />);
82
+ await user.click(screen.getByText(/save/i));
83
+ await waitFor(() => {
84
+ expect(mockOnSave).toHaveBeenCalled();
85
+ });
86
+ });
87
+
88
+ it('calls onSave when save button is clicked', async () => {
89
+ render(<StockOperationSubmission {...defaultProps} />);
90
+ await user.click(screen.getByText(/save/i));
91
+ await waitFor(() => {
92
+ expect(mockOnSave).toHaveBeenCalled();
93
+ });
94
+ });
95
+
96
+ it('disables the save button while saving', async () => {
97
+ const mockOnSave = jest.fn<Promise<void>, [StockOperationDTO]>(
98
+ (model) => new Promise((resolve) => setTimeout(resolve, 500)),
99
+ );
100
+
101
+ const testProps = {
102
+ ...defaultProps,
103
+ actions: {
104
+ ...defaultProps.actions,
105
+ onSave: mockOnSave,
106
+ },
107
+ };
108
+
109
+ render(<StockOperationSubmission {...testProps} />);
110
+ const saveButton = screen.getByRole('button', { name: 'Save' });
111
+ await user.click(saveButton);
112
+
113
+ expect(saveButton).toBeDisabled();
114
+
115
+ await waitFor(() => {
116
+ expect(saveButton).not.toBeDisabled();
117
+ });
118
+ });
119
+
120
+ it('calls onComplete when Complete button is clicked', async () => {
121
+ render(<StockOperationSubmission {...defaultProps} />);
122
+ await user.click(screen.getByText(/complete/i));
123
+ await waitFor(() => {
124
+ expect(mockOnComplete).toHaveBeenCalled();
125
+ });
126
+ });
127
+
128
+ it('does not render buttons when locked', () => {
129
+ const lockedProps = {
130
+ ...defaultProps,
131
+ locked: true,
132
+ };
133
+
134
+ render(<StockOperationSubmission {...lockedProps} />);
135
+ expect(screen.queryByRole('button', { name: /save/i })).not.toBeInTheDocument();
136
+ expect(screen.queryByRole('button', { name: /complete/i })).not.toBeInTheDocument();
137
+ });
138
+ });