@openmrs/esm-sms-app 1.0.1-pre.22

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.
Files changed (108) hide show
  1. package/.turbo/turbo-build.log +32 -0
  2. package/dist/123.js +2 -0
  3. package/dist/123.js.LICENSE.txt +9 -0
  4. package/dist/123.js.map +1 -0
  5. package/dist/144.js +2 -0
  6. package/dist/144.js.LICENSE.txt +19 -0
  7. package/dist/144.js.map +1 -0
  8. package/dist/160.js +1 -0
  9. package/dist/160.js.map +1 -0
  10. package/dist/173.js +1 -0
  11. package/dist/173.js.map +1 -0
  12. package/dist/197.js +1 -0
  13. package/dist/260.js +1 -0
  14. package/dist/260.js.map +1 -0
  15. package/dist/285.js +1 -0
  16. package/dist/285.js.map +1 -0
  17. package/dist/300.js +2 -0
  18. package/dist/300.js.LICENSE.txt +5 -0
  19. package/dist/300.js.map +1 -0
  20. package/dist/335.js +1 -0
  21. package/dist/356.js +1 -0
  22. package/dist/356.js.map +1 -0
  23. package/dist/372.js +1 -0
  24. package/dist/372.js.map +1 -0
  25. package/dist/378.js +1 -0
  26. package/dist/378.js.map +1 -0
  27. package/dist/41.js +2 -0
  28. package/dist/41.js.LICENSE.txt +9 -0
  29. package/dist/41.js.map +1 -0
  30. package/dist/449.js +1 -0
  31. package/dist/449.js.map +1 -0
  32. package/dist/465.js +1 -0
  33. package/dist/465.js.map +1 -0
  34. package/dist/470.js +2 -0
  35. package/dist/470.js.LICENSE.txt +9 -0
  36. package/dist/470.js.map +1 -0
  37. package/dist/495.js +1 -0
  38. package/dist/495.js.map +1 -0
  39. package/dist/55.js +1 -0
  40. package/dist/613.js +2 -0
  41. package/dist/613.js.LICENSE.txt +5 -0
  42. package/dist/613.js.map +1 -0
  43. package/dist/628.js +1 -0
  44. package/dist/628.js.map +1 -0
  45. package/dist/652.js +1 -0
  46. package/dist/733.js +2 -0
  47. package/dist/733.js.LICENSE.txt +30 -0
  48. package/dist/733.js.map +1 -0
  49. package/dist/830.js +1 -0
  50. package/dist/830.js.map +1 -0
  51. package/dist/831.js +2 -0
  52. package/dist/831.js.LICENSE.txt +5 -0
  53. package/dist/831.js.map +1 -0
  54. package/dist/876.js +2 -0
  55. package/dist/876.js.LICENSE.txt +9 -0
  56. package/dist/876.js.map +1 -0
  57. package/dist/919.js +1 -0
  58. package/dist/99.js +1 -0
  59. package/dist/main.js +1 -0
  60. package/dist/main.js.map +1 -0
  61. package/dist/openmrs-esm-sms-app.js +1 -0
  62. package/dist/openmrs-esm-sms-app.js.buildmanifest.json +807 -0
  63. package/dist/openmrs-esm-sms-app.js.map +1 -0
  64. package/dist/routes.json +1 -0
  65. package/jest.config.js +3 -0
  66. package/package.json +55 -0
  67. package/src/api/providers.resource.ts +45 -0
  68. package/src/config-schema.ts +34 -0
  69. package/src/declarations.d.ts +4 -0
  70. package/src/hooks/useLogs.ts +28 -0
  71. package/src/hooks/useProviderConfigTemplates.ts +16 -0
  72. package/src/hooks/useProviderConfigurations.ts +32 -0
  73. package/src/index.ts +35 -0
  74. package/src/providers/add-config-form/provider-config-form.scss +118 -0
  75. package/src/providers/add-config-form/provider-config-form.test.tsx +252 -0
  76. package/src/providers/add-config-form/provider-config-form.workspace.tsx +347 -0
  77. package/src/providers/empty-state/empty-data-illustration.component.tsx +39 -0
  78. package/src/providers/empty-state/empty-state.component.tsx +41 -0
  79. package/src/providers/empty-state/empty-state.scss +55 -0
  80. package/src/providers/modals/config-upload.modal.tsx +170 -0
  81. package/src/providers/modals/config-upload.scss +33 -0
  82. package/src/providers/modals/remove-config.modal.tsx +69 -0
  83. package/src/providers/providers-dashboard.component.tsx +63 -0
  84. package/src/providers/providers-dashboard.scss +69 -0
  85. package/src/providers/providers-dashboard.test.tsx +63 -0
  86. package/src/providers/providers-overview/providers-action-menu.component.tsx +102 -0
  87. package/src/providers/providers-overview/providers-action-menu.scss +11 -0
  88. package/src/providers/providers-overview/providers-overview.component.tsx +306 -0
  89. package/src/providers/providers-overview/providers-overview.scss +114 -0
  90. package/src/providers/sms-logs-table/sms-logs-table.component.tsx +217 -0
  91. package/src/providers/sms-logs-table/sms-logs-table.scss +63 -0
  92. package/src/providers/sms-logs-table/sms-logs-table.test.tsx +103 -0
  93. package/src/providers/test-form/provider-config-test-form.scss +105 -0
  94. package/src/providers/test-form/provider-config-test-form.test.tsx +122 -0
  95. package/src/providers/test-form/provider-config-test-form.workspace.tsx +233 -0
  96. package/src/providers/utils/index.ts +57 -0
  97. package/src/root.scss +39 -0
  98. package/src/routes.json +44 -0
  99. package/src/sms-admin-card-link.component.tsx +24 -0
  100. package/src/types/index.ts +68 -0
  101. package/translations/am.json +4 -0
  102. package/translations/en.json +47 -0
  103. package/translations/es.json +4 -0
  104. package/translations/fr.json +4 -0
  105. package/translations/he.json +4 -0
  106. package/translations/km.json +4 -0
  107. package/tsconfig.json +5 -0
  108. package/webpack.config.js +1 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openmrs-esm-sms-app.js","mappings":"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","sources":["webpack://@openmrs/esm-sms-app/webpack/runtime/load script","webpack://@openmrs/esm-sms-app/webpack/runtime/consumes","webpack://@openmrs/esm-sms-app/webpack/container-entry","webpack://@openmrs/esm-sms-app/webpack/bootstrap","webpack://@openmrs/esm-sms-app/webpack/runtime/compat get default export","webpack://@openmrs/esm-sms-app/webpack/runtime/define property getters","webpack://@openmrs/esm-sms-app/webpack/runtime/ensure chunk","webpack://@openmrs/esm-sms-app/webpack/runtime/get javascript chunk filename","webpack://@openmrs/esm-sms-app/webpack/runtime/global","webpack://@openmrs/esm-sms-app/webpack/runtime/hasOwnProperty shorthand","webpack://@openmrs/esm-sms-app/webpack/runtime/make namespace object","webpack://@openmrs/esm-sms-app/webpack/runtime/node module decorator","webpack://@openmrs/esm-sms-app/webpack/runtime/sharing","webpack://@openmrs/esm-sms-app/webpack/runtime/publicPath","webpack://@openmrs/esm-sms-app/webpack/runtime/jsonp chunk loading","webpack://@openmrs/esm-sms-app/webpack/runtime/nonce","webpack://@openmrs/esm-sms-app/webpack/startup"],"names":["inProgress","dataWebpackPrefix","parseVersion","versionLt","rangeToString","satisfy","exists","get","eagerOnly","findSingletonVersionKey","getInvalidSingletonVersionMessage","fail","warn","useFallback","loadSingletonVersion","installedModules","moduleToHandlerMapping","chunkMapping","startedInstallModules","moduleMap","__webpack_require__","e","then","module","getScope","R","o","Promise","resolve","Error","undefined","init","shareScope","initScope","S","name","oldScope","I","d","exports","__webpack_module_cache__","moduleId","cachedModule","id","loaded","__webpack_modules__","call","m","c","n","getter","__esModule","a","definition","key","Object","defineProperty","enumerable","f","chunkId","all","keys","reduce","promises","u","g","globalThis","this","Function","window","obj","prop","prototype","hasOwnProperty","l","url","done","push","script","needAttach","scripts","document","getElementsByTagName","i","length","s","getAttribute","createElement","charset","timeout","nc","setAttribute","src","onScriptComplete","prev","event","onerror","onload","clearTimeout","doneFns","parentNode","removeChild","forEach","fn","setTimeout","bind","type","target","head","appendChild","r","Symbol","toStringTag","value","nmd","paths","children","initPromises","initTokens","initToken","indexOf","scope","uniqueName","register","version","factory","eager","versions","activeVersion","from","scriptUrl","importScripts","location","currentScript","tagName","toUpperCase","test","replace","p","str","split","map","exec","apply","b","t","range","pop","entry","filtered","requiredVersion","msg","console","scopeName","fallback","failAsNotExist","promise","consumes","onFactory","onError","error","installedChunks","j","installedChunkData","reject","errorType","realSrc","message","request","webpackJsonpCallback","parentChunkLoadingFunction","data","chunkIds","moreModules","runtime","some","chunkLoadingGlobal","__webpack_exports__"],"sourceRoot":""}
@@ -0,0 +1 @@
1
+ {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{},"extensions":[{"name":"sms-providers-settings-admin-card-link","component":"smsAdminCardLink","slot":"system-admin-page-card-link-slot","online":true,"offline":true}],"workspaces":[{"name":"add-provider-config-form","component":"addProviderConfigForm","title":"addProviderConfigWorkspaceTitle"},{"name":"provider-config-test-form","component":"providerConfigTestForm","title":"providerConfigTestWorkspaceTitle"}],"pages":[{"component":"providersDashboard","route":"provider-settings","online":true,"offline":true,"order":1}],"modals":[{"name":"config-upload-modal","component":"configUploadModal"},{"name":"remove-config-modal","component":"removeConfigModal"}],"version":"1.0.1-pre.22"}
package/jest.config.js ADDED
@@ -0,0 +1,3 @@
1
+ const rootConfig = require('../../jest.config.js');
2
+
3
+ module.exports = rootConfig;
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@openmrs/esm-sms-app",
3
+ "version": "1.0.1-pre.22",
4
+ "description": "CFL SMS microfrontend for the OpenMRS SPA",
5
+ "browser": "dist/openmrs-esm-sms-app.js",
6
+ "main": "src/index.ts",
7
+ "source": true,
8
+ "license": "MPL-2.0",
9
+ "homepage": "https://github.com/openmrs/openmrs-esm-patient-communications#readme",
10
+ "scripts": {
11
+ "start": "openmrs develop",
12
+ "serve": "webpack serve --mode=development",
13
+ "debug": "npm run serve",
14
+ "build": "webpack --mode production",
15
+ "analyze": "webpack --mode=production --env.analyze=true",
16
+ "lint": "cross-env eslint src --ext ts,tsx",
17
+ "test": "cross-env TZ=UTC jest --config jest.config.js --verbose false --passWithNoTests --color",
18
+ "test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js --color",
19
+ "coverage": "yarn test --coverage",
20
+ "typescript": "tsc",
21
+ "extract-translations": "i18next 'src/**/*.component.tsx' --config ../../tools/i18next-parser.config.js"
22
+ },
23
+ "browserslist": [
24
+ "extends browserslist-config-openmrs"
25
+ ],
26
+ "keywords": [
27
+ "openmrs"
28
+ ],
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "git+https://github.com/openmrs/openmrs-esm-patient-communications.git"
35
+ },
36
+ "bugs": {
37
+ "url": "https://github.com/openmrs/openmrs-esm-patient-communications/issues"
38
+ },
39
+ "dependencies": {
40
+ "@carbon/react": "~1.37.0",
41
+ "lodash-es": "^4.17.15"
42
+ },
43
+ "peerDependencies": {
44
+ "@openmrs/esm-framework": "5.x",
45
+ "dayjs": "1.x",
46
+ "react": "^18.1.0",
47
+ "react-dom": "^18.1.0",
48
+ "react-i18next": "11.x",
49
+ "swr": "2.x"
50
+ },
51
+ "devDependencies": {
52
+ "webpack": "^5.74.0"
53
+ },
54
+ "stableVersion": "1.0.0"
55
+ }
@@ -0,0 +1,45 @@
1
+ import { openmrsFetch } from '@openmrs/esm-framework';
2
+ import { type ProviderConfiguration } from '../types';
3
+
4
+ async function postData(url: string, data = {}, ac = new AbortController()) {
5
+ const response = await openmrsFetch(url, {
6
+ signal: ac.signal,
7
+ method: 'POST',
8
+ headers: {
9
+ 'Content-Type': 'application/json',
10
+ },
11
+ body: JSON.stringify(data),
12
+ });
13
+
14
+ return response.data;
15
+ }
16
+
17
+ export async function saveConfig(providerConfig: Array<ProviderConfiguration>) {
18
+ const url = '/ws/sms/configs';
19
+ return await postData(url, { configs: providerConfig });
20
+ }
21
+
22
+ export async function uploadConfigTemplate(file: File) {
23
+ const url = '/ws/sms/templates/import';
24
+ const ac = new AbortController();
25
+
26
+ const formData = new FormData();
27
+ formData.append('file', file);
28
+
29
+ return await openmrsFetch(url, {
30
+ signal: ac.signal,
31
+ method: 'POST',
32
+ headers: {},
33
+ body: formData,
34
+ });
35
+ }
36
+
37
+ export async function sendTestMessage(payload) {
38
+ const url = '/ws/sms/send';
39
+ return await postData(url, payload);
40
+ }
41
+
42
+ export async function setAsDefaultConfig(payload) {
43
+ const url = '/ws/sms/configs';
44
+ return await postData(url, payload);
45
+ }
@@ -0,0 +1,34 @@
1
+ import { Type, oneOf } from '@openmrs/esm-framework';
2
+
3
+ // Define allowed properties for the sms logs table object.
4
+ // These properties are described here: https://github.com/johnsonandjohnson/openmrs-distro-cfl/wiki/Admin-SMS#sms-logs
5
+ const allowedProperties = [
6
+ 'id',
7
+ 'errorMessage',
8
+ 'providerStatus',
9
+ 'openMrsId',
10
+ 'providerId',
11
+ 'deliveryStatus',
12
+ 'messageContent',
13
+ 'timestamp',
14
+ 'config',
15
+ 'smsDirection',
16
+ 'phoneNumber',
17
+ 'modificationDate',
18
+ 'creationDate',
19
+ 'modifiedBy',
20
+ 'creator',
21
+ ];
22
+
23
+ export const configSchema = {
24
+ smsLogsColumns: {
25
+ _type: Type.Array,
26
+ _description: 'Columns to display in logs table. Each value should be a property of SMSlogs record type',
27
+ _default: ['timestamp', 'messageContent', 'config', 'phoneNumber', 'providerId'],
28
+ _validators: [oneOf(allowedProperties)],
29
+ },
30
+ };
31
+
32
+ export interface ConfigObject {
33
+ smsLogsColumns: Array<string>;
34
+ }
@@ -0,0 +1,4 @@
1
+ declare module '@carbon/react';
2
+ declare module '*.css';
3
+ declare module '*.scss';
4
+ declare module '*.png';
@@ -0,0 +1,28 @@
1
+ import useSWRInfinite from 'swr/infinite';
2
+ import { openmrsFetch, useConfig, type FetchResponse } from '@openmrs/esm-framework';
3
+ import { type SMSLog, type SMSLogsResponse } from '../types';
4
+ import { type ConfigObject } from '../config-schema';
5
+
6
+ export function useLogsRecords() {
7
+ const getKey = (pageIndex, previousPageData) => {
8
+ if (previousPageData && !previousPageData.rows.length) return null;
9
+
10
+ return `/ws/sms/log?page=${pageIndex + 1}`;
11
+ };
12
+
13
+ const { data, error, size, setSize, isValidating, isLoading, mutate } = useSWRInfinite<
14
+ FetchResponse<SMSLogsResponse>,
15
+ Error
16
+ >(getKey, openmrsFetch);
17
+
18
+ const smsLogs: SMSLog[] = data ? [].concat(...data.map((page) => page.data.rows)) : [];
19
+
20
+ return {
21
+ smsLogs,
22
+ isLoadingLogs: isLoading,
23
+ isValidatingLogs: isValidating,
24
+ mutateLogs: mutate,
25
+ setSize,
26
+ error,
27
+ };
28
+ }
@@ -0,0 +1,16 @@
1
+ import { type FetchResponse, openmrsFetch } from '@openmrs/esm-framework';
2
+ import useSWR from 'swr';
3
+ import { type ServiceConfigTemplates } from '../types';
4
+
5
+ export function useProviderConfigTemplates() {
6
+ const url = 'ws/sms/templates';
7
+
8
+ const { data, isLoading, mutate, error } = useSWR<FetchResponse<ServiceConfigTemplates>>(url, openmrsFetch);
9
+
10
+ return {
11
+ templates: data?.data ?? {},
12
+ isLoadingTemplates: isLoading,
13
+ mutateTemplates: mutate,
14
+ error,
15
+ };
16
+ }
@@ -0,0 +1,32 @@
1
+ import { openmrsFetch, type FetchResponse } from '@openmrs/esm-framework';
2
+ import useSWR from 'swr';
3
+ import { type ProviderConfigurationsResponse } from '../types';
4
+ import { useMemo } from 'react';
5
+
6
+ export function useProviderConfigurations() {
7
+ const url = '/ws/sms/configs';
8
+ const { data, isLoading, error, mutate, isValidating } = useSWR<FetchResponse<ProviderConfigurationsResponse>, Error>(
9
+ url,
10
+ openmrsFetch,
11
+ );
12
+
13
+ const providerConfigurations = useMemo(() => {
14
+ if (!isLoading || !isValidating) {
15
+ return data.data.configs.map((config) => ({
16
+ ...config,
17
+ isDefaultConfig: data.data.defaultConfigName === config.name,
18
+ }));
19
+ } else {
20
+ return [];
21
+ }
22
+ }, [data?.data?.configs, data?.data?.defaultConfigName, isLoading, isValidating]);
23
+
24
+ return {
25
+ providerConfigurations,
26
+ defaultConfig: data?.data?.defaultConfigName,
27
+ isLoadingConfigs: isLoading,
28
+ isValidatingConfigs: isValidating,
29
+ mutateConfigs: mutate,
30
+ error,
31
+ };
32
+ }
package/src/index.ts ADDED
@@ -0,0 +1,35 @@
1
+ import { defineConfigSchema, getAsyncLifecycle } from '@openmrs/esm-framework';
2
+ import { configSchema } from './config-schema';
3
+
4
+ const moduleName = '@openmrs/esm-sms-app';
5
+
6
+ const options = {
7
+ featureName: 'provider-settings',
8
+ moduleName,
9
+ };
10
+
11
+ export const importTranslation = require.context('../translations', true, /.json$/, 'lazy');
12
+
13
+ export const providersDashboard = getAsyncLifecycle(() => import('./providers/providers-dashboard.component'), options);
14
+
15
+ export const smsAdminCardLink = getAsyncLifecycle(() => import('./sms-admin-card-link.component'), options);
16
+
17
+ // t('providerConfigTestWorkspaceTitle', 'Test configuration');
18
+ export const providerConfigTestForm = getAsyncLifecycle(
19
+ () => import('./providers/test-form/provider-config-test-form.workspace'),
20
+ options,
21
+ );
22
+
23
+ // t('addProviderConfigWorkspaceTitle', 'Add Provider');
24
+ export const addProviderConfigForm = getAsyncLifecycle(
25
+ () => import('./providers/add-config-form/provider-config-form.workspace'),
26
+ options,
27
+ );
28
+
29
+ export const configUploadModal = getAsyncLifecycle(() => import('./providers/modals/config-upload.modal'), options);
30
+
31
+ export const removeConfigModal = getAsyncLifecycle(() => import('./providers/modals/remove-config.modal'), options);
32
+
33
+ export function startupApp() {
34
+ defineConfigSchema(moduleName, configSchema);
35
+ }
@@ -0,0 +1,118 @@
1
+ @use '@carbon/colors';
2
+ @use '@carbon/layout';
3
+ @use '@carbon/type';
4
+ @use '@carbon/styles/scss/spacing';
5
+
6
+ .heading {
7
+ @include type.type-style("heading-03");
8
+ margin-bottom: spacing.$spacing-03;
9
+ }
10
+
11
+ .columnLabel {
12
+ @include type.type-style("heading-compact-02");
13
+ color: colors.$gray-70;
14
+ }
15
+
16
+ .radioButtonGroup{
17
+ :global(.cds--radio-button-group--vertical) {
18
+ gap: spacing.$spacing-05;
19
+ }
20
+
21
+ }
22
+
23
+ .dynamicRow {
24
+ padding-block: spacing.$spacing-05;
25
+ }
26
+
27
+ .checkBox {
28
+ :global(.cds--checkbox-label-text) {
29
+ @include type.type-style("heading-compact-02");
30
+ color: colors.$gray-70;
31
+ }
32
+ :global(.cds--checkbox-label) {
33
+ padding-top: 0;
34
+ }
35
+ }
36
+
37
+ .button {
38
+ height: spacing.$spacing-10;
39
+ display: flex;
40
+ align-content: flex-start;
41
+ align-items: baseline;
42
+ min-width: 50%;
43
+ }
44
+
45
+ .spinner {
46
+ min-height: spacing.$spacing-05;
47
+ }
48
+
49
+ .tablet {
50
+ padding: spacing.$spacing-06 spacing.$spacing-05;
51
+ background-color: white;
52
+ }
53
+
54
+ .desktop {
55
+ padding: 0;
56
+ }
57
+
58
+ .formContainer {
59
+ margin: spacing.$spacing-08 spacing.$spacing-05;
60
+ }
61
+
62
+ .form {
63
+ display: flex;
64
+ flex-direction: column;
65
+ justify-content: space-between;
66
+ height: var(--desktop-workspace-window-height);
67
+ }
68
+
69
+ .grid {
70
+ margin: 0;
71
+ padding: 0;
72
+ }
73
+
74
+ .row {
75
+ margin: spacing.$spacing-03 0 spacing.$spacing-08;
76
+ }
77
+
78
+ .errorMessage {
79
+ @include type.type-style("label-02");
80
+ color: colors.$red-60;
81
+ }
82
+
83
+ :global(.omrs-breakpoint-lt-desktop) {
84
+ .form {
85
+ height: var(--tablet-workspace-window-height);
86
+ }
87
+
88
+ .row {
89
+ display: flex;
90
+ gap: 4rem;
91
+
92
+ :global(.cds--col-sm-1) {
93
+ flex-basis: 30%;
94
+ min-width: 8rem;
95
+ text-align: left;
96
+ }
97
+
98
+ :global(.cds--col-sm-3) {
99
+ flex-basis: 70%;
100
+ }
101
+ }
102
+
103
+ .skeleton {
104
+ height: spacing.$spacing-08;
105
+ }
106
+ }
107
+
108
+ .errorNotification {
109
+ margin-top: 0.25rem;
110
+ }
111
+
112
+ :global(.omrs-breakpoint-gt-tablet) {
113
+ .row {
114
+ display: flex;
115
+ flex-direction: column;
116
+ gap: spacing.$spacing-05;
117
+ }
118
+ }
@@ -0,0 +1,252 @@
1
+ import React from 'react';
2
+ import { screen } from '@testing-library/react';
3
+ import { userEvent } from '@testing-library/user-event';
4
+ import { renderWithSwr } from 'tools';
5
+ import AddProviderConfigForm from './provider-config-form.workspace';
6
+ import { openmrsFetch, showSnackbar } from '@openmrs/esm-framework';
7
+ import { saveConfig } from '../../api/providers.resource';
8
+
9
+ jest.mock('zod', () => {
10
+ const originalModule = jest.requireActual('zod');
11
+ const mockedZod = {
12
+ ...originalModule,
13
+ z: {
14
+ ...originalModule.z,
15
+ schema: jest.fn(() => ({
16
+ safeParse: jest.fn(() => ({
17
+ success: true,
18
+ data: {},
19
+ })),
20
+ })),
21
+ },
22
+ };
23
+ return mockedZod;
24
+ });
25
+
26
+ jest.mock('../../hooks/useProviderConfigurations', () => ({
27
+ useProviderConfigurations: () => ({
28
+ mutateConfigs: jest.fn(),
29
+ providerConfigurations: [],
30
+ }),
31
+ }));
32
+
33
+ jest.mock('../../hooks/useProviderConfigTemplates', () => ({
34
+ useProviderConfigTemplates: () => ({
35
+ templates: mockTemplates,
36
+ isLoading: false,
37
+ error: null,
38
+ }),
39
+ }));
40
+
41
+ jest.mock('../../api/providers.resource', () => ({
42
+ saveConfig: jest.fn(),
43
+ }));
44
+
45
+ jest.mock('@openmrs/esm-framework', () => ({
46
+ openmrsFetch: jest.fn(),
47
+ showSnackbar: jest.fn(),
48
+ useLayoutType: () => 'desktop',
49
+ ResponsiveWrapper: ({ children }) => <div>{children}</div>,
50
+ }));
51
+
52
+ const mockOpenmrsFetch = openmrsFetch as jest.Mock;
53
+ const mockSaveConfig = saveConfig as jest.Mock;
54
+
55
+ describe('AddProviderConfigForm', () => {
56
+ it('Renders form fields correctly', async () => {
57
+ renderAddProviderConfigForm();
58
+ const inputs = getFormInputs();
59
+
60
+ expect(inputs.nameInput).toBeInTheDocument();
61
+ expect(inputs.templateInput).toBeInTheDocument();
62
+ expect(inputs.maxRetriesInput).toBeInTheDocument();
63
+ expect(inputs.splitHeaderInput).toBeInTheDocument();
64
+ expect(inputs.splitFooterInput).toBeInTheDocument();
65
+ expect(inputs.excludeLastFooterInput).toBeInTheDocument();
66
+ expect(inputs.autoScriptInput).toBeInTheDocument();
67
+
68
+ const buttons = getFormButtons();
69
+ expect(buttons.cancelButton).toBeInTheDocument();
70
+ expect(buttons.cancelButton).not.toBeDisabled();
71
+ expect(buttons.submitButton).toBeInTheDocument();
72
+ expect(buttons.submitButton).not.toBeDisabled();
73
+ });
74
+
75
+ it('saves and creates a new provider configuration', async () => {
76
+ mockSaveConfig.mockResolvedValue({ data: { configs: [mockConfig], defaultConfigName: null } });
77
+ const user = userEvent.setup();
78
+ renderAddProviderConfigForm();
79
+ const inputs = getFormInputs();
80
+
81
+ await fillFormInputs(user, inputs, {
82
+ name: 'Vonage',
83
+ template: 'Twilio',
84
+ maxRetries: '0',
85
+ splitHeader: 'Msg $m of $t',
86
+ splitFooter: '...',
87
+ });
88
+
89
+ const dynamicInputs = getDynamicFormInputs();
90
+
91
+ await fillDynamicFormInputs(user, dynamicInputs, {
92
+ username: 'test-username',
93
+ password: 'test-password',
94
+ from: 'test-from',
95
+ });
96
+
97
+ const buttons = getFormButtons();
98
+ await user.click(buttons.submitButton);
99
+
100
+ expect(saveConfig).toHaveBeenCalled();
101
+ expect(saveConfig).toHaveBeenCalledWith([
102
+ {
103
+ name: 'Vonage',
104
+ templateName: 'Twilio',
105
+ autoScript: undefined,
106
+ maxRetries: 0,
107
+ splitHeader: 'Msg $m of $t',
108
+ splitFooter: '...',
109
+ excludeLastFooter: true,
110
+ props: [
111
+ { name: 'username', value: 'test-username' },
112
+ { name: 'password', value: 'test-password' },
113
+ { name: 'from', value: 'test-from' },
114
+ ],
115
+ },
116
+ ]);
117
+ expect(showSnackbar).toHaveBeenCalled();
118
+ expect(showSnackbar).toHaveBeenCalledWith({
119
+ title: 'Configuration saved',
120
+ kind: 'success',
121
+ });
122
+ });
123
+
124
+ it('should show field errors when invalid data type is provided', async () => {
125
+ const user = userEvent.setup();
126
+ renderAddProviderConfigForm();
127
+
128
+ const formbuttons = getFormButtons();
129
+ await user.click(formbuttons.submitButton);
130
+
131
+ expect(screen.getAllByText('Required')).toHaveLength(4);
132
+ });
133
+
134
+ it('renders an error snackbar when there is a problem creating a new provider config', async () => {
135
+ const user = userEvent.setup();
136
+ renderAddProviderConfigForm();
137
+ const error = new Error('Configuration not saved');
138
+
139
+ mockSaveConfig.mockResolvedValue(error);
140
+
141
+ const formbuttons = getFormButtons();
142
+ await user.click(formbuttons.submitButton);
143
+
144
+ expect(saveConfig).toHaveBeenCalled();
145
+ expect(showSnackbar).toHaveBeenCalled();
146
+ });
147
+ });
148
+
149
+ function renderAddProviderConfigForm() {
150
+ return renderWithSwr(<AddProviderConfigForm />);
151
+ }
152
+
153
+ function getFormInputs() {
154
+ return {
155
+ nameInput: screen.getByTestId('provider-name'),
156
+ templateInput: screen.getByTestId('select-template'),
157
+ maxRetriesInput: screen.getByTestId('numberOfRetries'),
158
+ splitHeaderInput: screen.getByTestId('split-header'),
159
+ splitFooterInput: screen.getByTestId('split-footer'),
160
+ excludeLastFooterInput: screen.getByTestId('exclude-last-footer'),
161
+ autoScriptInput: screen.getByTestId('auto-script'),
162
+ };
163
+ }
164
+
165
+ function getDynamicFormInputs() {
166
+ return {
167
+ dynamicUsernameInput: screen.getByTestId('username'),
168
+ dynamicPasswordInput: screen.getByTestId('password'),
169
+ dynamicFromInput: screen.getByTestId('from'),
170
+ };
171
+ }
172
+
173
+ function getFormButtons() {
174
+ return {
175
+ cancelButton: screen.getByRole('button', { name: /Discard/i }),
176
+ submitButton: screen.getByRole('button', { name: /Save and close/i }),
177
+ };
178
+ }
179
+
180
+ async function fillFormInputs(user, inputs, values) {
181
+ await user.type(inputs.nameInput, values.name);
182
+ await user.selectOptions(inputs.templateInput, values.template);
183
+ await user.type(inputs.maxRetriesInput, values.maxRetries);
184
+ await user.type(inputs.splitHeaderInput, values.splitHeader);
185
+ await user.type(inputs.splitFooterInput, values.splitFooter);
186
+ await user.click(inputs.excludeLastFooterInput);
187
+ }
188
+
189
+ async function fillDynamicFormInputs(user, inputs, values) {
190
+ await user.type(inputs.dynamicUsernameInput, values.username);
191
+ await user.type(inputs.dynamicPasswordInput, values.password);
192
+ await user.type(inputs.dynamicFromInput, values.from);
193
+ }
194
+
195
+ const mockTemplates = {
196
+ Clickatell: {
197
+ name: 'Clickatell',
198
+ configurables: ['username', 'password', 'clickatell_api_id', 'from'],
199
+ },
200
+ Nuntium: {
201
+ name: 'Nuntium',
202
+ configurables: ['username', 'password', 'from'],
203
+ },
204
+ Twilio: {
205
+ name: 'Twilio',
206
+ configurables: ['username', 'password', 'from'],
207
+ },
208
+ Voxeo: {
209
+ name: 'Voxeo',
210
+ configurables: ['username', 'password', 'botkey', 'from'],
211
+ },
212
+ KooKoo: {
213
+ name: 'KooKoo',
214
+ configurables: ['api_key'],
215
+ },
216
+ Plivo: {
217
+ name: 'Plivo',
218
+ configurables: ['username', 'password', 'from'],
219
+ },
220
+ Voto: {
221
+ name: 'Voto',
222
+ configurables: ['api_key'],
223
+ },
224
+ Rancard: {
225
+ name: 'Rancard',
226
+ configurables: ['username', 'password', 'from'],
227
+ },
228
+ };
229
+
230
+ const mockConfig = {
231
+ name: 'Vonage',
232
+ maxRetries: 0,
233
+ excludeLastFooter: true,
234
+ splitHeader: 'Msg $m of $t',
235
+ splitFooter: '...',
236
+ templateName: 'Twilio',
237
+ props: [
238
+ {
239
+ name: 'username',
240
+ value: '13ad7f87',
241
+ },
242
+ {
243
+ name: 'password',
244
+ value: 'tHUk4XoMxTKBw4fj',
245
+ },
246
+ {
247
+ name: 'from',
248
+ value: '14157386102',
249
+ },
250
+ ],
251
+ automaticResponseScript: null,
252
+ };