@openmrs/esm-framework 3.4.1-pre.98 → 4.0.1-pre.204
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/.turbo/turbo-build.log +16 -138
- package/dist/openmrs-esm-framework.js +1 -1
- package/dist/openmrs-esm-framework.js.LICENSE.txt +9 -21
- package/dist/openmrs-esm-framework.js.map +1 -1
- package/docs/API.md +588 -756
- package/docs/classes/OpenmrsFetchError.md +4 -10
- package/docs/enums/Type.md +20 -20
- package/docs/enums/VisitMode.md +8 -8
- package/docs/enums/VisitStatus.md +6 -6
- package/docs/interfaces/AssignedExtension.md +7 -9
- package/docs/interfaces/BreadcrumbRegistration.md +2 -2
- package/docs/interfaces/BreadcrumbSettings.md +4 -22
- package/docs/interfaces/CancelLoading.md +1 -1
- package/docs/interfaces/ClearDynamicRoutesMessage.md +1 -1
- package/docs/interfaces/ComponentDefinition.md +7 -19
- package/docs/interfaces/Config.md +3 -17
- package/docs/interfaces/ConfigObject.md +14 -17
- package/docs/interfaces/ConfigSchema.md +3 -3
- package/docs/interfaces/ConfigurableLinkProps.md +12 -1
- package/docs/interfaces/ConnectedExtension.md +4 -6
- package/docs/interfaces/ConnectivityChangedEvent.md +1 -1
- package/docs/interfaces/CurrentPatientOptions.md +1 -1
- package/docs/interfaces/DisplayConditionsConfigObject.md +19 -0
- package/docs/interfaces/DynamicOfflineData.md +63 -0
- package/docs/interfaces/DynamicOfflineDataHandler.md +88 -0
- package/docs/interfaces/DynamicOfflineDataSyncState.md +63 -0
- package/docs/interfaces/ErrorStateProps.md +30 -0
- package/docs/interfaces/ExtensionData.md +3 -3
- package/docs/interfaces/ExtensionDefinition.md +13 -37
- package/docs/interfaces/ExtensionProps.md +2 -2
- package/docs/interfaces/ExtensionRegistration.md +18 -7
- package/docs/interfaces/ExtensionSlotBaseProps.md +15 -4
- package/docs/interfaces/ExtensionSlotConfig.md +4 -4
- package/docs/interfaces/ExtensionSlotConfigObject.md +3 -9
- package/docs/interfaces/ExtensionSlotState.md +2 -2
- package/docs/interfaces/ExtensionStore.md +1 -1
- package/docs/interfaces/FHIRCode.md +13 -2
- package/docs/interfaces/FHIRRequestObj.md +3 -3
- package/docs/interfaces/FHIRRequestOptions.md +41 -0
- package/docs/interfaces/FHIRResource.md +4 -1
- package/docs/interfaces/FetchResponse.md +1 -1
- package/docs/interfaces/FetchResponseJson.md +7 -0
- package/docs/interfaces/ImportMap.md +1 -1
- package/docs/interfaces/Lifecycle.md +4 -4
- package/docs/interfaces/Location.md +3 -3
- package/docs/interfaces/LoggedInUser.md +11 -11
- package/docs/interfaces/LoggedInUserFetchResponse.md +1 -1
- package/docs/interfaces/MessageServiceWorkerResult.md +3 -3
- package/docs/interfaces/NavigateOptions.md +12 -1
- package/docs/interfaces/NewVisitPayload.md +6 -6
- package/docs/interfaces/NotificationDescriptor.md +6 -6
- package/docs/interfaces/OfflineModeResult.md +3 -3
- package/docs/interfaces/OfflinePatientArgs.md +2 -6
- package/docs/interfaces/OfflinePatientDataSyncHandler.md +5 -14
- package/docs/interfaces/OfflinePatientDataSyncState.md +6 -24
- package/docs/interfaces/OfflinePatientDataSyncStore.md +2 -9
- package/docs/interfaces/OldExtensionSlotBaseProps.md +65 -0
- package/docs/interfaces/OmrsServiceWorkerMessage.md +1 -1
- package/docs/interfaces/OnImportMapChangedMessage.md +2 -2
- package/docs/interfaces/OnlyThePatient.md +1 -1
- package/docs/interfaces/OpenmrsResource.md +2 -2
- package/docs/interfaces/PageDefinition.md +9 -25
- package/docs/interfaces/PatientWithFullResponse.md +1 -1
- package/docs/interfaces/Person.md +3 -3
- package/docs/interfaces/Privilege.md +3 -3
- package/docs/interfaces/QueueItemDescriptor.md +4 -9
- package/docs/interfaces/RegisterDynamicRouteMessage.md +4 -4
- package/docs/interfaces/ResourceLoader.md +1 -1
- package/docs/interfaces/RetryOptions.md +7 -18
- package/docs/interfaces/Role.md +3 -3
- package/docs/interfaces/Session.md +7 -7
- package/docs/interfaces/SessionLocation.md +3 -3
- package/docs/interfaces/ShowNotificationEvent.md +5 -5
- package/docs/interfaces/ShowToastEvent.md +4 -4
- package/docs/interfaces/SpaConfig.md +5 -19
- package/docs/interfaces/SyncItem.md +7 -11
- package/docs/interfaces/SyncProcessOptions.md +5 -7
- package/docs/interfaces/ToastDescriptor.md +5 -5
- package/docs/interfaces/ToastNotificationMeta.md +6 -6
- package/docs/interfaces/UserHasAccessProps.md +24 -2
- package/docs/interfaces/Visit.md +9 -9
- package/docs/interfaces/VisitItem.md +4 -4
- package/docs/interfaces/VisitType.md +3 -3
- package/jest.config.js +8 -0
- package/mock.tsx +4 -7
- package/package.json +13 -13
- package/src/integration-tests/extension-config.test.tsx +218 -21
- package/typedoc.json +1 -1
package/jest.config.js
CHANGED
|
@@ -6,6 +6,14 @@ module.exports = {
|
|
|
6
6
|
"\\.(s?css)$": "identity-obj-proxy",
|
|
7
7
|
"\\.(svg)$": "<rootDir>/__mocks__/fileMock.js",
|
|
8
8
|
"lodash-es/(.*)": "lodash/$1",
|
|
9
|
+
// See https://jestjs.io/docs/upgrading-to-jest28#packagejson-exports
|
|
10
|
+
// which links to https://github.com/microsoft/accessibility-insights-web/pull/5421#issuecomment-1109168149
|
|
11
|
+
"^dexie$": require.resolve("dexie"),
|
|
12
|
+
"^uuid$": require.resolve("uuid"),
|
|
9
13
|
},
|
|
10
14
|
setupFilesAfterEnv: ["<rootDir>/src/integration-tests/setup-tests.ts"],
|
|
15
|
+
testEnvironment: "jsdom",
|
|
16
|
+
testEnvironmentOptions: {
|
|
17
|
+
url: "http://localhost/",
|
|
18
|
+
},
|
|
11
19
|
};
|
package/mock.tsx
CHANGED
|
@@ -3,6 +3,7 @@ import type {} from "@openmrs/esm-globals";
|
|
|
3
3
|
import createStore, { Store } from "unistore";
|
|
4
4
|
import { never, of } from "rxjs";
|
|
5
5
|
import { interpolateUrl } from "@openmrs/esm-config";
|
|
6
|
+
import { SessionStore } from "@openmrs/esm-api";
|
|
6
7
|
export {
|
|
7
8
|
parseDate,
|
|
8
9
|
formatDate,
|
|
@@ -14,7 +15,9 @@ export {
|
|
|
14
15
|
interpolateString,
|
|
15
16
|
interpolateUrl,
|
|
16
17
|
validators,
|
|
18
|
+
validator,
|
|
17
19
|
} from "@openmrs/esm-config";
|
|
20
|
+
export { isDesktop } from "@openmrs/esm-react-utils";
|
|
18
21
|
|
|
19
22
|
window.i18next = { ...window.i18next, language: "en" };
|
|
20
23
|
|
|
@@ -50,7 +53,7 @@ export function getCurrentUser() {
|
|
|
50
53
|
return of({ authenticated: false });
|
|
51
54
|
}
|
|
52
55
|
|
|
53
|
-
export const mockSessionStore = createGlobalStore("mock-session-store", {
|
|
56
|
+
export const mockSessionStore = createGlobalStore<SessionStore>("mock-session-store", {
|
|
54
57
|
loaded: false,
|
|
55
58
|
session: null,
|
|
56
59
|
});
|
|
@@ -247,12 +250,6 @@ export const useSession = jest.fn(() => ({
|
|
|
247
250
|
|
|
248
251
|
export const useLayoutType = jest.fn(() => "desktop");
|
|
249
252
|
|
|
250
|
-
export const useExtensionSlot = jest.fn(() => ({
|
|
251
|
-
extensionSlotModuleName: "",
|
|
252
|
-
attachedExtensionSlotName: "",
|
|
253
|
-
extensionIdsToRender: [],
|
|
254
|
-
}));
|
|
255
|
-
|
|
256
253
|
export const useExtensionSlotMeta = jest.fn(() => ({}));
|
|
257
254
|
|
|
258
255
|
export const UserHasAccess = jest.fn().mockImplementation((props: any) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openmrs/esm-framework",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1-pre.204",
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
5
|
"browser": "dist/openmrs-esm-framework.js",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -35,18 +35,18 @@
|
|
|
35
35
|
"access": "public"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@openmrs/esm-api": "^
|
|
39
|
-
"@openmrs/esm-breadcrumbs": "^
|
|
40
|
-
"@openmrs/esm-config": "^
|
|
41
|
-
"@openmrs/esm-error-handling": "^
|
|
42
|
-
"@openmrs/esm-extensions": "^
|
|
43
|
-
"@openmrs/esm-globals": "^
|
|
44
|
-
"@openmrs/esm-offline": "^
|
|
45
|
-
"@openmrs/esm-react-utils": "^
|
|
46
|
-
"@openmrs/esm-state": "^
|
|
47
|
-
"@openmrs/esm-styleguide": "^
|
|
48
|
-
"@openmrs/esm-utils": "^
|
|
38
|
+
"@openmrs/esm-api": "^4.0.1-pre.204",
|
|
39
|
+
"@openmrs/esm-breadcrumbs": "^4.0.1-pre.204",
|
|
40
|
+
"@openmrs/esm-config": "^4.0.1-pre.204",
|
|
41
|
+
"@openmrs/esm-error-handling": "^4.0.1-pre.204",
|
|
42
|
+
"@openmrs/esm-extensions": "^4.0.1-pre.204",
|
|
43
|
+
"@openmrs/esm-globals": "^4.0.1-pre.204",
|
|
44
|
+
"@openmrs/esm-offline": "^4.0.1-pre.204",
|
|
45
|
+
"@openmrs/esm-react-utils": "^4.0.1-pre.204",
|
|
46
|
+
"@openmrs/esm-state": "^4.0.1-pre.204",
|
|
47
|
+
"@openmrs/esm-styleguide": "^4.0.1-pre.204",
|
|
48
|
+
"@openmrs/esm-utils": "^4.0.1-pre.204",
|
|
49
49
|
"dayjs": "^1.10.7"
|
|
50
50
|
},
|
|
51
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "4ba2589b61d90c81eef0a21b87332b9f799f8dac"
|
|
52
52
|
}
|
|
@@ -3,8 +3,6 @@ import {
|
|
|
3
3
|
attach,
|
|
4
4
|
registerExtension,
|
|
5
5
|
updateInternalExtensionStore,
|
|
6
|
-
getExtensionInternalStore,
|
|
7
|
-
getExtensionStore,
|
|
8
6
|
} from "../../../esm-extensions";
|
|
9
7
|
import {
|
|
10
8
|
ExtensionSlot,
|
|
@@ -22,7 +20,17 @@ import {
|
|
|
22
20
|
getExtensionSlotsConfigStore,
|
|
23
21
|
} from "../../../esm-config/src";
|
|
24
22
|
import { act, render, screen, waitFor } from "@testing-library/react";
|
|
25
|
-
import {
|
|
23
|
+
import { Person } from "@openmrs/esm-api";
|
|
24
|
+
import { mockSessionStore } from "../../mock";
|
|
25
|
+
|
|
26
|
+
jest.mock("@openmrs/esm-api", () => {
|
|
27
|
+
const original = jest.requireActual("@openmrs/esm-api");
|
|
28
|
+
return {
|
|
29
|
+
...original,
|
|
30
|
+
getSessionStore: () => mockSessionStore,
|
|
31
|
+
refetchCurrentUser: jest.fn(),
|
|
32
|
+
};
|
|
33
|
+
});
|
|
26
34
|
|
|
27
35
|
describe("Interaction between configuration and extension systems", () => {
|
|
28
36
|
beforeEach(() => {
|
|
@@ -55,9 +63,12 @@ describe("Interaction between configuration and extension systems", () => {
|
|
|
55
63
|
moduleName: "esm-flintstone",
|
|
56
64
|
featureName: "The Flintstones",
|
|
57
65
|
disableTranslations: true,
|
|
58
|
-
})(() => <ExtensionSlot data-testid="slot"
|
|
66
|
+
})(() => <ExtensionSlot data-testid="slot" name="A slot" />);
|
|
67
|
+
|
|
59
68
|
render(<App />);
|
|
69
|
+
|
|
60
70
|
await waitFor(() => expect(screen.getByText("Betty")).toBeInTheDocument());
|
|
71
|
+
|
|
61
72
|
const slot = screen.getByTestId("slot");
|
|
62
73
|
const extensions = slot.childNodes;
|
|
63
74
|
expect(extensions[0]).toHaveTextContent("Betty");
|
|
@@ -93,18 +104,15 @@ describe("Interaction between configuration and extension systems", () => {
|
|
|
93
104
|
disableTranslations: true,
|
|
94
105
|
})(() => (
|
|
95
106
|
<>
|
|
96
|
-
<ExtensionSlot
|
|
97
|
-
|
|
98
|
-
extensionSlotName="Flintstone slot"
|
|
99
|
-
/>
|
|
100
|
-
<ExtensionSlot
|
|
101
|
-
data-testid="future-slot"
|
|
102
|
-
extensionSlotName="Future slot"
|
|
103
|
-
/>
|
|
107
|
+
<ExtensionSlot data-testid="flintstone-slot" name="Flintstone slot" />
|
|
108
|
+
<ExtensionSlot data-testid="future-slot" name="Future slot" />
|
|
104
109
|
</>
|
|
105
110
|
));
|
|
111
|
+
|
|
106
112
|
render(<App />);
|
|
113
|
+
|
|
107
114
|
await screen.findAllByText(/.*Pebbles.*/);
|
|
115
|
+
|
|
108
116
|
const flintstonePebbles = screen.getByTestId("flintstone-slot");
|
|
109
117
|
expect(flintstonePebbles).toHaveTextContent(/Pebbles:.*Springfield/);
|
|
110
118
|
const futurePebbles = screen.getByTestId("future-slot");
|
|
@@ -140,14 +148,14 @@ describe("Interaction between configuration and extension systems", () => {
|
|
|
140
148
|
disableTranslations: true,
|
|
141
149
|
})(() => (
|
|
142
150
|
<>
|
|
143
|
-
<ExtensionSlot
|
|
144
|
-
data-testid="flintstone-slot"
|
|
145
|
-
extensionSlotName="Flintstone slot"
|
|
146
|
-
/>
|
|
151
|
+
<ExtensionSlot data-testid="flintstone-slot" name="Flintstone slot" />
|
|
147
152
|
</>
|
|
148
153
|
));
|
|
154
|
+
|
|
149
155
|
render(<App />);
|
|
156
|
+
|
|
150
157
|
await screen.findAllByText(/.*Dino.*/);
|
|
158
|
+
|
|
151
159
|
const slot = screen.getByTestId("flintstone-slot");
|
|
152
160
|
expect(slot.firstChild).toHaveTextContent(/Dino/);
|
|
153
161
|
expect(slot.lastChild).toHaveTextContent(/Baby Puss/);
|
|
@@ -161,9 +169,12 @@ describe("Interaction between configuration and extension systems", () => {
|
|
|
161
169
|
moduleName: "esm-slaghoople",
|
|
162
170
|
featureName: "The Slaghooples",
|
|
163
171
|
disableTranslations: true,
|
|
164
|
-
})(() => <ExtensionSlot data-testid="slot"
|
|
172
|
+
})(() => <ExtensionSlot data-testid="slot" name="A slot" />);
|
|
173
|
+
|
|
165
174
|
render(<App />);
|
|
175
|
+
|
|
166
176
|
await waitFor(() => expect(screen.getByText("Pearl")).toBeInTheDocument());
|
|
177
|
+
|
|
167
178
|
act(() => {
|
|
168
179
|
temporaryConfigStore.setState({
|
|
169
180
|
config: {
|
|
@@ -177,6 +188,7 @@ describe("Interaction between configuration and extension systems", () => {
|
|
|
177
188
|
},
|
|
178
189
|
});
|
|
179
190
|
});
|
|
191
|
+
|
|
180
192
|
expect(screen.queryByText("Pearl")).not.toBeInTheDocument();
|
|
181
193
|
});
|
|
182
194
|
|
|
@@ -188,12 +200,16 @@ describe("Interaction between configuration and extension systems", () => {
|
|
|
188
200
|
moduleName: "esm-quarry",
|
|
189
201
|
featureName: "The Flintstones",
|
|
190
202
|
disableTranslations: true,
|
|
191
|
-
})(() => <ExtensionSlot data-testid="slot"
|
|
203
|
+
})(() => <ExtensionSlot data-testid="slot" name="A slot" />);
|
|
204
|
+
|
|
192
205
|
render(<App />);
|
|
206
|
+
|
|
193
207
|
await waitFor(() =>
|
|
194
208
|
expect(screen.getByText(/Mr. Slate/)).toBeInTheDocument()
|
|
195
209
|
);
|
|
210
|
+
|
|
196
211
|
expect(screen.getByTestId("slot")).toHaveTextContent(/green/);
|
|
212
|
+
|
|
197
213
|
act(() => {
|
|
198
214
|
temporaryConfigStore.setState({
|
|
199
215
|
config: {
|
|
@@ -209,8 +225,11 @@ describe("Interaction between configuration and extension systems", () => {
|
|
|
209
225
|
},
|
|
210
226
|
});
|
|
211
227
|
});
|
|
228
|
+
|
|
212
229
|
expect(screen.queryByText("green")).not.toBeInTheDocument();
|
|
213
|
-
|
|
230
|
+
waitFor(() =>
|
|
231
|
+
expect(screen.getByTestId("slot")).toHaveTextContent(/black/)
|
|
232
|
+
);
|
|
214
233
|
});
|
|
215
234
|
|
|
216
235
|
test("Extension config should be available in extension store", async () => {
|
|
@@ -221,7 +240,7 @@ describe("Interaction between configuration and extension systems", () => {
|
|
|
221
240
|
const store = useExtensionStore();
|
|
222
241
|
return (
|
|
223
242
|
<div>
|
|
224
|
-
<ExtensionSlot data-testid="slot"
|
|
243
|
+
<ExtensionSlot data-testid="slot" name="A slot" />
|
|
225
244
|
{store.slots["A slot"].assignedExtensions.map((e) => (
|
|
226
245
|
<div key={e.name}>{JSON.stringify(e.config)}</div>
|
|
227
246
|
))}
|
|
@@ -233,9 +252,13 @@ describe("Interaction between configuration and extension systems", () => {
|
|
|
233
252
|
featureName: "The Flintstones",
|
|
234
253
|
disableTranslations: true,
|
|
235
254
|
})(RootComponent);
|
|
255
|
+
|
|
236
256
|
render(<App />);
|
|
257
|
+
|
|
237
258
|
await waitFor(() => expect(screen.getByTestId(/slot/)).toBeInTheDocument());
|
|
259
|
+
|
|
238
260
|
expect(screen.getByText(/clothes/)).toHaveTextContent(/leopard/);
|
|
261
|
+
|
|
239
262
|
act(() => {
|
|
240
263
|
temporaryConfigStore.setState({
|
|
241
264
|
config: {
|
|
@@ -251,14 +274,187 @@ describe("Interaction between configuration and extension systems", () => {
|
|
|
251
274
|
},
|
|
252
275
|
});
|
|
253
276
|
});
|
|
277
|
+
|
|
254
278
|
expect(screen.getByText(/clothes/)).toHaveTextContent(/tiger/);
|
|
255
279
|
});
|
|
280
|
+
|
|
281
|
+
test("should not show extension when user lacks configured privilege", async () => {
|
|
282
|
+
mockSessionStore.setState({
|
|
283
|
+
loaded: true,
|
|
284
|
+
session: {
|
|
285
|
+
authenticated: true,
|
|
286
|
+
sessionId: "1",
|
|
287
|
+
user: {
|
|
288
|
+
uuid: "1",
|
|
289
|
+
display: "Non-Admin",
|
|
290
|
+
username: "nonadmin",
|
|
291
|
+
systemId: "nonadmin",
|
|
292
|
+
userProperties: {},
|
|
293
|
+
person: {} as Person,
|
|
294
|
+
privileges: [],
|
|
295
|
+
roles: [],
|
|
296
|
+
retired: false,
|
|
297
|
+
locale: "en",
|
|
298
|
+
allowedLocales: ["en"],
|
|
299
|
+
},
|
|
300
|
+
},
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
registerSimpleExtension("Schmoo", "esm-bedrock", true);
|
|
304
|
+
registerSimpleExtension("Wilma", "esm-flintstones", true);
|
|
305
|
+
attach("A slot", "Schmoo");
|
|
306
|
+
attach("A slot", "Wilma");
|
|
307
|
+
defineConfigSchema("esm-bedrock", {});
|
|
308
|
+
defineConfigSchema("esm-flintstones", {});
|
|
309
|
+
provide({
|
|
310
|
+
"esm-bedrock": {
|
|
311
|
+
"Display conditions": {
|
|
312
|
+
privileges: ["Yabadabadoo!"],
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
});
|
|
316
|
+
provide({
|
|
317
|
+
"esm-flintstones": {},
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
function RootComponent() {
|
|
321
|
+
return (
|
|
322
|
+
<div>
|
|
323
|
+
<ExtensionSlot data-testid="slot" name="A slot" />
|
|
324
|
+
</div>
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
const App = openmrsComponentDecorator({
|
|
328
|
+
moduleName: "esm-bedrock",
|
|
329
|
+
featureName: "Bedrock",
|
|
330
|
+
disableTranslations: true,
|
|
331
|
+
})(RootComponent);
|
|
332
|
+
|
|
333
|
+
render(<App />);
|
|
334
|
+
|
|
335
|
+
await waitFor(() => expect(screen.getByTestId(/slot/)).toBeInTheDocument());
|
|
336
|
+
expect(screen.getByTestId("slot").firstChild).toHaveAttribute(
|
|
337
|
+
"data-extension-id",
|
|
338
|
+
"Wilma"
|
|
339
|
+
);
|
|
340
|
+
expect(screen.queryAllByText(/\bSchmoo\b/)).toHaveLength(0);
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
test("should show extension when user has configured privilege", async () => {
|
|
344
|
+
mockSessionStore.setState({
|
|
345
|
+
loaded: true,
|
|
346
|
+
session: {
|
|
347
|
+
authenticated: true,
|
|
348
|
+
sessionId: "1",
|
|
349
|
+
user: {
|
|
350
|
+
uuid: "1",
|
|
351
|
+
display: "Non-Admin",
|
|
352
|
+
username: "nonadmin",
|
|
353
|
+
systemId: "nonadmin",
|
|
354
|
+
userProperties: {},
|
|
355
|
+
person: {} as Person,
|
|
356
|
+
privileges: [{ uuid: "1", display: "Yabadabadoo!" }],
|
|
357
|
+
roles: [],
|
|
358
|
+
retired: false,
|
|
359
|
+
locale: "en",
|
|
360
|
+
allowedLocales: ["en"],
|
|
361
|
+
},
|
|
362
|
+
},
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
registerSimpleExtension("Schmoo", "esm-bedrock", true);
|
|
366
|
+
attach("A slot", "Schmoo");
|
|
367
|
+
defineConfigSchema("esm-bedrock", {});
|
|
368
|
+
provide({
|
|
369
|
+
"esm-bedrock": {
|
|
370
|
+
"Display conditions": {
|
|
371
|
+
privileges: ["Yabadabadoo!"],
|
|
372
|
+
},
|
|
373
|
+
},
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
function RootComponent() {
|
|
377
|
+
return (
|
|
378
|
+
<div>
|
|
379
|
+
<ExtensionSlot data-testid="slot" name="A slot" />
|
|
380
|
+
</div>
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
const App = openmrsComponentDecorator({
|
|
384
|
+
moduleName: "esm-bedrock",
|
|
385
|
+
featureName: "Bedrock",
|
|
386
|
+
disableTranslations: true,
|
|
387
|
+
})(RootComponent);
|
|
388
|
+
|
|
389
|
+
render(<App />);
|
|
390
|
+
|
|
391
|
+
await waitFor(() => expect(screen.getByTestId(/slot/)).toBeInTheDocument());
|
|
392
|
+
expect(screen.getByTestId("slot").firstChild).toHaveAttribute(
|
|
393
|
+
"data-extension-id",
|
|
394
|
+
"Schmoo"
|
|
395
|
+
);
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
test("should only show extensions users have default privilege for", async () => {
|
|
399
|
+
mockSessionStore.setState({
|
|
400
|
+
loaded: true,
|
|
401
|
+
session: {
|
|
402
|
+
authenticated: true,
|
|
403
|
+
sessionId: "1",
|
|
404
|
+
user: {
|
|
405
|
+
uuid: "1",
|
|
406
|
+
display: "Non-Admin",
|
|
407
|
+
username: "nonadmin",
|
|
408
|
+
systemId: "nonadmin",
|
|
409
|
+
userProperties: {},
|
|
410
|
+
person: {} as Person,
|
|
411
|
+
privileges: [{ uuid: "1", display: "YOWTCH!" }],
|
|
412
|
+
roles: [],
|
|
413
|
+
retired: false,
|
|
414
|
+
locale: "en",
|
|
415
|
+
allowedLocales: ["en"],
|
|
416
|
+
},
|
|
417
|
+
},
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
registerSimpleExtension("Schmoo", "esm-bedrock", true, "Yabadabadoo!");
|
|
421
|
+
registerSimpleExtension("Wilma", "esm-flintstones", true, "YOWTCH!");
|
|
422
|
+
attach("A slot", "Schmoo");
|
|
423
|
+
attach("A slot", "Wilma");
|
|
424
|
+
defineConfigSchema("esm-bedrock", {});
|
|
425
|
+
defineConfigSchema("esm-flintstones", {});
|
|
426
|
+
provide({ "esm-bedrock": {} });
|
|
427
|
+
provide({ "esm-flintstones": {} });
|
|
428
|
+
|
|
429
|
+
function RootComponent() {
|
|
430
|
+
return (
|
|
431
|
+
<div>
|
|
432
|
+
<ExtensionSlot data-testid="slot" name="A slot" />
|
|
433
|
+
</div>
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
const App = openmrsComponentDecorator({
|
|
437
|
+
moduleName: "esm-bedrock",
|
|
438
|
+
featureName: "Bedrock",
|
|
439
|
+
disableTranslations: true,
|
|
440
|
+
})(RootComponent);
|
|
441
|
+
|
|
442
|
+
render(<App />);
|
|
443
|
+
|
|
444
|
+
await waitFor(() => expect(screen.getByTestId(/slot/)).toBeInTheDocument());
|
|
445
|
+
expect(screen.getByTestId("slot").firstChild).toHaveAttribute(
|
|
446
|
+
"data-extension-id",
|
|
447
|
+
"Wilma"
|
|
448
|
+
);
|
|
449
|
+
expect(screen.queryAllByText(/\bSchmoo\b/)).toHaveLength(0);
|
|
450
|
+
});
|
|
256
451
|
});
|
|
257
452
|
|
|
258
453
|
function registerSimpleExtension(
|
|
259
454
|
name: string,
|
|
260
455
|
moduleName: string,
|
|
261
|
-
takesConfig: boolean = false
|
|
456
|
+
takesConfig: boolean = false,
|
|
457
|
+
privileges?: string | string[]
|
|
262
458
|
) {
|
|
263
459
|
const SimpleComponent = () => <div>{name}</div>;
|
|
264
460
|
const ConfigurableComponent = () => {
|
|
@@ -281,5 +477,6 @@ function registerSimpleExtension(
|
|
|
281
477
|
}
|
|
282
478
|
),
|
|
283
479
|
meta: {},
|
|
480
|
+
privileges,
|
|
284
481
|
});
|
|
285
482
|
}
|