@esri/solutions-components 0.5.3 → 0.5.4

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 (116) hide show
  1. package/dist/cjs/calcite-input-text_5.cjs.entry.js +36 -36
  2. package/dist/cjs/calcite-shell-panel_14.cjs.entry.js +1 -1
  3. package/dist/cjs/solution-configuration.cjs.entry.js +1 -1
  4. package/dist/cjs/solution-contents_3.cjs.entry.js +1 -1
  5. package/dist/cjs/{solution-store-70002b57.js → solution-store-ca4639d5.js} +3 -3
  6. package/dist/collection/components/add-record-modal/test/add-record-modal.e2e.js +24 -0
  7. package/dist/collection/components/add-record-modal/test/add-record-modal.spec.js +32 -0
  8. package/dist/collection/components/buffer-tools/test/buffer-tools.e2e.js +24 -0
  9. package/dist/collection/components/buffer-tools/test/buffer-tools.spec.js +157 -0
  10. package/dist/collection/components/card-manager/test/card-manager.e2e.js +24 -0
  11. package/dist/collection/components/card-manager/test/card-manager.spec.js +32 -0
  12. package/dist/collection/components/comment-card/test/comment-card.e2e.js +24 -0
  13. package/dist/collection/components/comment-card/test/comment-card.spec.js +32 -0
  14. package/dist/collection/components/crowdsource-manager/test/crowdsource-manager.e2e.js +24 -0
  15. package/dist/collection/components/crowdsource-manager/test/crowdsource-manager.spec.js +32 -0
  16. package/dist/collection/components/crowdsource-reporter/test/crowdsource-reporter.e2e.js +24 -0
  17. package/dist/collection/components/crowdsource-reporter/test/crowdsource-reporter.spec.js +32 -0
  18. package/dist/collection/components/deduct-calculator/test/deduct-calculator.e2e.js +24 -0
  19. package/dist/collection/components/deduct-calculator/test/deduct-calculator.spec.js +32 -0
  20. package/dist/collection/components/edit-record-modal/test/edit-record-modal.e2e.js +24 -0
  21. package/dist/collection/components/edit-record-modal/test/edit-record-modal.spec.js +32 -0
  22. package/dist/collection/components/info-card/test/info-card.e2e.js +24 -0
  23. package/dist/collection/components/info-card/test/info-card.spec.js +32 -0
  24. package/dist/collection/components/json-editor/test/json-editor.e2e.js +31 -0
  25. package/dist/collection/components/json-editor/test/json-editor.spec.js +60 -0
  26. package/dist/collection/components/layer-table/test/layer-table.e2e.js +24 -0
  27. package/dist/collection/components/layer-table/test/layer-table.spec.js +32 -0
  28. package/dist/collection/components/list-item/test/list-item.e2e.js +24 -0
  29. package/dist/collection/components/list-item/test/list-item.spec.js +32 -0
  30. package/dist/collection/components/map-card/test/map-card.e2e.js +24 -0
  31. package/dist/collection/components/map-card/test/map-card.spec.js +32 -0
  32. package/dist/collection/components/map-draw-tools/test/map-draw-tools.e2e.js +24 -0
  33. package/dist/collection/components/map-draw-tools/test/map-draw-tools.spec.js +32 -0
  34. package/dist/collection/components/map-layer-picker/test/map-layer-picker.e2e.js +24 -0
  35. package/dist/collection/components/map-layer-picker/test/map-layer-picker.spec.js +109 -0
  36. package/dist/collection/components/map-search/test/map-search.e2e.js +24 -0
  37. package/dist/collection/components/map-search/test/map-search.spec.js +53 -0
  38. package/dist/collection/components/map-select-tools/map-select-tools.js +36 -36
  39. package/dist/collection/components/map-select-tools/test/map-select-tools.e2e.js +24 -0
  40. package/dist/collection/components/map-select-tools/test/map-select-tools.spec.js +349 -0
  41. package/dist/collection/components/media-card/test/media-card.e2e.js +24 -0
  42. package/dist/collection/components/media-card/test/media-card.spec.js +32 -0
  43. package/dist/collection/components/pci-calculator/test/pci-calculator.e2e.js +24 -0
  44. package/dist/collection/components/pci-calculator/test/pci-calculator.spec.js +32 -0
  45. package/dist/collection/components/pdf-download/test/pdf-download.e2e.js +71 -0
  46. package/dist/collection/components/pdf-download/test/pdf-download.spec.js +104 -0
  47. package/dist/collection/components/public-notification/test/public-notification.e2e.js +95 -0
  48. package/dist/collection/components/public-notification/test/public-notification.spec.js +149 -0
  49. package/dist/collection/components/refine-selection/refine-selection.css +85 -85
  50. package/dist/collection/components/solution-configuration/test/solution-configuration.e2e.js +31 -0
  51. package/dist/collection/components/solution-configuration/test/solution-configuration.spec.js +114 -0
  52. package/dist/collection/components/solution-contents/test/solution-contents.e2e.js +89 -0
  53. package/dist/collection/components/solution-contents/test/solution-contents.spec.js +138 -0
  54. package/dist/collection/components/solution-item/test/solution-item.e2e.js +31 -0
  55. package/dist/collection/components/solution-item/test/solution-item.spec.js +72 -0
  56. package/dist/collection/components/solution-item-details/test/solution-item-details.e2e.js +31 -0
  57. package/dist/collection/components/solution-item-details/test/solution-item-details.spec.js +137 -0
  58. package/dist/collection/components/solution-item-icon/test/solution-item-icon.e2e.js +24 -0
  59. package/dist/collection/components/solution-item-icon/test/solution-item-icon.spec.js +34 -0
  60. package/dist/collection/components/solution-item-sharing/test/solution-item-sharing.e2e.js +31 -0
  61. package/dist/collection/components/solution-item-sharing/test/solution-item-sharing.spec.js +49 -0
  62. package/dist/collection/components/solution-organization-variables/test/solution-organization-variables.e2e.js +31 -0
  63. package/dist/collection/components/solution-organization-variables/test/solution-organization-variables.spec.js +60 -0
  64. package/dist/collection/components/solution-resource-item/test/solution-resource-item.e2e.js +31 -0
  65. package/dist/collection/components/solution-resource-item/test/solution-resource-item.spec.js +50 -0
  66. package/dist/collection/components/solution-spatial-ref/test/solution-spatial-ref.e2e.js +31 -0
  67. package/dist/collection/components/solution-spatial-ref/test/solution-spatial-ref.spec.js +170 -0
  68. package/dist/collection/components/solution-template-data/test/solution-template-data.e2e.js +31 -0
  69. package/dist/collection/components/solution-template-data/test/solution-template-data.spec.js +55 -0
  70. package/dist/collection/components/solution-variables/test/solution-variables.e2e.js +31 -0
  71. package/dist/collection/components/solution-variables/test/solution-variables.spec.js +126 -0
  72. package/dist/collection/utils/publicNotificationUtils.js +45 -0
  73. package/dist/collection/utils/templates.e2e.js +25 -0
  74. package/dist/collection/utils/test/csvUtils.spec.js +46 -0
  75. package/dist/collection/utils/test/downloadUtils.spec.js +102 -0
  76. package/dist/collection/utils/test/pciUtils.spec.js +297 -0
  77. package/dist/collection/utils/test/solution-store.spec.js +439 -0
  78. package/dist/components/map-select-tools2.js +36 -36
  79. package/dist/components/solution-store.js +3 -3
  80. package/dist/esm/calcite-input-text_5.entry.js +36 -36
  81. package/dist/esm/calcite-shell-panel_14.entry.js +1 -1
  82. package/dist/esm/solution-configuration.entry.js +1 -1
  83. package/dist/esm/solution-contents_3.entry.js +1 -1
  84. package/dist/esm/{solution-store-5d068b07.js → solution-store-70f874f8.js} +3 -3
  85. package/dist/solutions-components/{p-41802f6b.entry.js → p-16dfb254.entry.js} +1 -1
  86. package/dist/solutions-components/{p-4769a2a5.entry.js → p-5ed755a2.entry.js} +1 -1
  87. package/dist/solutions-components/{p-826a814d.js → p-78719506.js} +2 -2
  88. package/dist/solutions-components/{p-9f620303.entry.js → p-b4b19fd3.entry.js} +1 -1
  89. package/dist/solutions-components/{p-24fe6e1c.entry.js → p-d5d5942d.entry.js} +1 -1
  90. package/dist/solutions-components/solutions-components.esm.js +1 -1
  91. package/dist/solutions-components/utils/common.js +291 -0
  92. package/dist/solutions-components/utils/csvDownload.js +36 -0
  93. package/dist/solutions-components/utils/csvUtils.js +32 -0
  94. package/dist/solutions-components/utils/downloadUtils.js +386 -0
  95. package/dist/solutions-components/utils/interfaces.js +56 -0
  96. package/dist/solutions-components/utils/languageUtil.js +85 -0
  97. package/dist/solutions-components/utils/loadModules.js +20 -0
  98. package/dist/solutions-components/utils/locale.js +56 -0
  99. package/dist/solutions-components/utils/mapViewUtils.js +140 -0
  100. package/dist/solutions-components/utils/pciUtils.js +837 -0
  101. package/dist/solutions-components/utils/pdfUtils.js +62 -0
  102. package/dist/solutions-components/utils/publicNotificationStore.js +38 -0
  103. package/dist/solutions-components/utils/publicNotificationUtils.js +45 -0
  104. package/dist/solutions-components/utils/queryUtils.js +148 -0
  105. package/dist/solutions-components/utils/solution-store.js +579 -0
  106. package/dist/solutions-components/utils/templates.e2e.js +25 -0
  107. package/dist/solutions-components/utils/templates.js +341 -0
  108. package/dist/solutions-components/utils/test/csvUtils.spec.js +46 -0
  109. package/dist/solutions-components/utils/test/downloadUtils.spec.js +102 -0
  110. package/dist/solutions-components/utils/test/mocks/jsApi.js +74 -0
  111. package/dist/solutions-components/utils/test/pciUtils.spec.js +297 -0
  112. package/dist/solutions-components/utils/test/solution-store.spec.js +439 -0
  113. package/dist/solutions-components/utils/test/testUtils.js +135 -0
  114. package/dist/solutions-components/utils/types.js +14 -0
  115. package/dist/solutions-components_commit.txt +7 -0
  116. package/package.json +7 -7
@@ -0,0 +1,439 @@
1
+ /** @license
2
+ * Copyright 2022 Esri
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import * as common from "@esri/solution-common";
17
+ import * as testUtils from "./testUtils";
18
+ import solution_734164 from "./solution_734164.json";
19
+ import solution_ca924c from "./solution_ca924c.json";
20
+ import state from "../solution-store";
21
+ import { EUpdateType } from '../interfaces';
22
+ let MOCK_USER_SESSION;
23
+ jest.setTimeout(30000);
24
+ beforeEach(() => {
25
+ MOCK_USER_SESSION = testUtils.createRuntimeMockUserSession();
26
+ state._testAccess("_emptyTheStore");
27
+ });
28
+ afterEach(() => {
29
+ jest.restoreAllMocks();
30
+ });
31
+ let itemEdit;
32
+ describe("solution-store", () => {
33
+ it("creates store", () => {
34
+ expect(state.getStoreInfo("solutionItemId")).toEqual("");
35
+ });
36
+ it("loads a solution", async () => {
37
+ jest.spyOn(common, "getItemDataAsJson").mockImplementation(() => solution_ca924c);
38
+ await state.loadSolution("ca924c6db7d247b9a31fa30532fb5913", MOCK_USER_SESSION);
39
+ expect(state.getStoreInfo("solutionItemId")).toEqual("ca924c6db7d247b9a31fa30532fb5913");
40
+ });
41
+ it("loads a solution, and then another one", async () => {
42
+ jest.spyOn(common, "getItemDataAsJson").mockImplementation(() => solution_ca924c);
43
+ await state.loadSolution("ca924c6db7d247b9a31fa30532fb5913", MOCK_USER_SESSION);
44
+ expect(state.getStoreInfo("solutionItemId")).toEqual("ca924c6db7d247b9a31fa30532fb5913");
45
+ // Replace the solution with a different one
46
+ jest.spyOn(common, "getItemDataAsJson").mockImplementation(() => solution_734164);
47
+ await state.loadSolution("7341644e455e4a068eba58f1939caac4", MOCK_USER_SESSION);
48
+ expect(state.getStoreInfo("solutionItemId")).toEqual("7341644e455e4a068eba58f1939caac4");
49
+ expect(state.getStoreInfo("solutionData").templates.length).toEqual(12);
50
+ });
51
+ describe("replaceItemThumbnail", () => {
52
+ beforeEach(() => {
53
+ itemEdit = testUtils.getSampleItemEdit();
54
+ });
55
+ it("queues a thumbnail for replacement", () => {
56
+ // Set a new thumbnail
57
+ itemEdit.thumbnail = testUtils.getSampleImageAsFile("thumb1");
58
+ // Register it in the store
59
+ state.replaceItemThumbnail(itemEdit);
60
+ // Check that the previous thumbnail is marked for removal and the new one is queued for adding
61
+ expect(itemEdit.resourceFilePaths.length).toEqual(3);
62
+ expect(itemEdit.resourceFilePaths[0].filename).toEqual("qc.project.json");
63
+ expect(itemEdit.resourceFilePaths[0].updateType).toEqual(3);
64
+ expect(itemEdit.resourceFilePaths[1].filename).toEqual("esri_133.png");
65
+ expect(itemEdit.resourceFilePaths[1].updateType).toEqual(2);
66
+ expect(itemEdit.resourceFilePaths[2].filename).toEqual("thumb1");
67
+ expect(itemEdit.resourceFilePaths[2].updateType).toEqual(0);
68
+ });
69
+ it("twice queues thumbnails for replacement", () => {
70
+ // Set a new thumbnail
71
+ itemEdit.thumbnail = testUtils.getSampleImageAsFile("thumb1");
72
+ // Register it in the store
73
+ state.replaceItemThumbnail(itemEdit);
74
+ // Set a new thumbnail
75
+ itemEdit.thumbnail = testUtils.getSampleImageAsFile("thumb2");
76
+ // Register it in the store
77
+ state.replaceItemThumbnail(itemEdit);
78
+ // Check that the previous thumbnail is marked for removal and the new one is queued for adding
79
+ expect(itemEdit.resourceFilePaths.length).toEqual(3);
80
+ expect(itemEdit.resourceFilePaths[0].filename).toEqual("qc.project.json");
81
+ expect(itemEdit.resourceFilePaths[0].updateType).toEqual(3);
82
+ expect(itemEdit.resourceFilePaths[1].filename).toEqual("esri_133.png");
83
+ expect(itemEdit.resourceFilePaths[1].updateType).toEqual(2);
84
+ expect(itemEdit.resourceFilePaths[2].filename).toEqual("thumb2");
85
+ expect(itemEdit.resourceFilePaths[2].updateType).toEqual(0);
86
+ });
87
+ it("thrice queues thumbnails for replacement", () => {
88
+ // Set a new thumbnail
89
+ itemEdit.thumbnail = testUtils.getSampleImageAsFile("thumb1");
90
+ // Register it in the store
91
+ state.replaceItemThumbnail(itemEdit);
92
+ // Set a new thumbnail
93
+ itemEdit.thumbnail = testUtils.getSampleImageAsFile("thumb2");
94
+ // Register it in the store
95
+ state.replaceItemThumbnail(itemEdit);
96
+ // Set a new thumbnail
97
+ itemEdit.thumbnail = testUtils.getSampleImageAsFile("thumb3");
98
+ // Register it in the store
99
+ state.replaceItemThumbnail(itemEdit);
100
+ // Check that the previous thumbnail is marked for removal and the new one is queued for adding
101
+ expect(itemEdit.resourceFilePaths.length).toEqual(3);
102
+ expect(itemEdit.resourceFilePaths[0].filename).toEqual("qc.project.json");
103
+ expect(itemEdit.resourceFilePaths[0].updateType).toEqual(3);
104
+ expect(itemEdit.resourceFilePaths[1].filename).toEqual("esri_133.png");
105
+ expect(itemEdit.resourceFilePaths[1].updateType).toEqual(2);
106
+ expect(itemEdit.resourceFilePaths[2].filename).toEqual("thumb3");
107
+ expect(itemEdit.resourceFilePaths[2].updateType).toEqual(0);
108
+ });
109
+ });
110
+ it("fails to find an item when fetching its value", async () => {
111
+ const item = state.getItemInfo("79036430a6274e17ae915d0278b8569c");
112
+ expect(item).toBeUndefined();
113
+ });
114
+ it("changes an item's value", async () => {
115
+ jest.spyOn(common, "getItemDataAsJson").mockImplementation(() => JSON.parse(JSON.stringify(solution_ca924c)));
116
+ await state.loadSolution("ca924c6db7d247b9a31fa30532fb5913", MOCK_USER_SESSION);
117
+ expect(state.getStoreInfo("solutionData").templates.length).toEqual(25);
118
+ const item = state.getItemInfo("9c1311d827f44fdc9680651420a63484");
119
+ expect(item.item.description).toEqual("An ArcGIS Survey123 form used by operations managers and yard supervisors to report materials used by each vehicle during winter weather operations.");
120
+ // Change the item's description
121
+ item.item.description = "Nullam ac urna mattis, maximus urna sit amet.";
122
+ state.setItemInfo(item);
123
+ const updatedItem = state.getItemInfo("9c1311d827f44fdc9680651420a63484");
124
+ expect(updatedItem.item.description).toEqual("Nullam ac urna mattis, maximus urna sit amet.");
125
+ });
126
+ it("changes a store value", async () => {
127
+ jest.spyOn(common, "getItemDataAsJson").mockImplementation(() => JSON.parse(JSON.stringify(solution_ca924c)));
128
+ await state.loadSolution("ca924c6db7d247b9a31fa30532fb5913", MOCK_USER_SESSION);
129
+ const origDefaultWkid = state.getStoreInfo("defaultWkid");
130
+ expect(origDefaultWkid).toBeUndefined();
131
+ state.setStoreInfo("defaultWkid", "2865");
132
+ const modifiedDefaultWkid = state.getStoreInfo("defaultWkid");
133
+ expect(modifiedDefaultWkid).toEqual("2865");
134
+ });
135
+ describe("saveSolution", () => {
136
+ it("saves a solution with a custom spatial reference", async () => {
137
+ jest.spyOn(common, "getItemDataAsJson").mockImplementation(() => {
138
+ return Object.assign(Object.assign({}, JSON.parse(JSON.stringify(solution_ca924c))), { "params": {
139
+ "wkid": {
140
+ "label": "Spatial Reference",
141
+ "default": 102100,
142
+ "valueType": "spatialReference",
143
+ "attributes": {
144
+ "required": "true"
145
+ }
146
+ }
147
+ } });
148
+ });
149
+ const updateSpy = jest.spyOn(common, "updateItem").mockImplementation((itemInfo, _authentication, _folderId) => {
150
+ expect(itemInfo.id).toEqual("ca924c6db7d247b9a31fa30532fb5913");
151
+ return Promise.resolve(null);
152
+ });
153
+ await state.loadSolution("ca924c6db7d247b9a31fa30532fb5913", MOCK_USER_SESSION);
154
+ await state.saveSolution();
155
+ expect(updateSpy).toHaveBeenCalled();
156
+ });
157
+ it("saves a solution without a custom spatial reference", async () => {
158
+ jest.spyOn(common, "getItemDataAsJson").mockImplementation(() => JSON.parse(JSON.stringify(solution_ca924c)));
159
+ const updateSpy = jest.spyOn(common, "updateItem").mockImplementation((itemInfo, _authentication, _folderId) => {
160
+ expect(itemInfo.id).toEqual("ca924c6db7d247b9a31fa30532fb5913");
161
+ return Promise.resolve(null);
162
+ });
163
+ await state.loadSolution("ca924c6db7d247b9a31fa30532fb5913", MOCK_USER_SESSION);
164
+ await state.saveSolution();
165
+ expect(updateSpy).toHaveBeenCalled();
166
+ });
167
+ });
168
+ it("directly empties the store", async () => {
169
+ jest.spyOn(common, "getItemDataAsJson").mockImplementation(() => JSON.parse(JSON.stringify(solution_ca924c)));
170
+ await state.loadSolution("ca924c6db7d247b9a31fa30532fb5913", MOCK_USER_SESSION);
171
+ expect(state.getStoreInfo("solutionItemId")).toEqual("ca924c6db7d247b9a31fa30532fb5913");
172
+ state._testAccess("_emptyTheStore");
173
+ expect(state.getStoreInfo("solutionItemId")).toEqual("");
174
+ });
175
+ it("gets feature services", async () => {
176
+ jest.spyOn(common, "getItemDataAsJson").mockImplementation(() => JSON.parse(JSON.stringify(solution_ca924c)));
177
+ await state.loadSolution("ca924c6db7d247b9a31fa30532fb5913", MOCK_USER_SESSION);
178
+ const result = state._testAccess("_getFeatureServices", state.getStoreInfo("solutionData").templates);
179
+ expect(result.length).toEqual(5);
180
+ expect(result[0].name).toEqual("Driver_Activity"); // name fetched from `name` prop because `title` empty
181
+ expect(result[0].enabled).toBeFalsy();
182
+ expect(result[1].name).toEqual("OperationsManagement"); // name fetched from higher-priority `title` prop
183
+ });
184
+ it("gets items shared with a group", async () => {
185
+ jest.spyOn(common, "getItemDataAsJson").mockImplementation(() => JSON.parse(JSON.stringify(solution_ca924c)));
186
+ await state.loadSolution("ca924c6db7d247b9a31fa30532fb5913", MOCK_USER_SESSION);
187
+ const result = state._testAccess("_getItemsSharedWithThisGroup", state.getStoreInfo("solutionData").templates[0], state.getStoreInfo("solutionData").templates);
188
+ expect(result.length).toEqual(23);
189
+ expect(result[0]).toEqual({
190
+ "id": "9c1311d827f44fdc9680651420a63484",
191
+ "title": "Material_Use_Reporting.zip",
192
+ "isShared": false,
193
+ "shareItem": false,
194
+ "type": "Form",
195
+ "typeKeywords": [
196
+ "Form",
197
+ "Survey123",
198
+ "Survey123 Connect",
199
+ "xForm"
200
+ ]
201
+ });
202
+ });
203
+ it("gets resource file paths", async () => {
204
+ jest.spyOn(common, "getItemDataAsJson").mockImplementation(() => JSON.parse(JSON.stringify(solution_ca924c)));
205
+ await state.loadSolution("ca924c6db7d247b9a31fa30532fb5913", MOCK_USER_SESSION);
206
+ const result = state._testAccess("_getResourceFilePaths", "ca924c6db7d247b9a31fa30532fb5913", state.getStoreInfo("solutionData").templates[0], MOCK_USER_SESSION.portal);
207
+ expect(result.length).toEqual(2);
208
+ expect(result[0]).toEqual({
209
+ "url": "https://myorg.maps.arcgis.com/sharing/rest/content/items/ca924c6db7d247b9a31fa30532fb5913/resources/79036430a6274e17ae915d0278b8569c_info_metadata/metadata.xml",
210
+ "type": 2,
211
+ "folder": "",
212
+ "filename": "metadata.xml",
213
+ "updateType": 3
214
+ });
215
+ });
216
+ it("gets resource storage name", async () => {
217
+ const resourcePaths = [
218
+ { type: common.EFileType.Data, filename: "def.txt" },
219
+ { type: common.EFileType.Data, filename: "def.doc" },
220
+ { type: common.EFileType.Info, filename: "def" },
221
+ { type: common.EFileType.Metadata, filename: "def" },
222
+ { type: common.EFileType.Resource, filename: "def" },
223
+ { type: common.EFileType.Thumbnail, filename: "def" }
224
+ ];
225
+ const storageNames = resourcePaths.map((path) => state._testAccess("_getResourceStorageName", "abc", path));
226
+ expect(storageNames).toEqual([
227
+ "abc_info_data/def.txt",
228
+ "abc_info_dataz/def.doc.zip",
229
+ "abc_info/def",
230
+ "abc_info_metadata/def",
231
+ "abc/def",
232
+ "abc_info_thumbnail/def"
233
+ ]);
234
+ });
235
+ describe("_getSpatialReferenceInfo", () => {
236
+ it("gets spatial reference info using a string wkid", async () => {
237
+ jest.spyOn(common, "getItemDataAsJson").mockImplementation(() => JSON.parse(JSON.stringify(solution_ca924c)));
238
+ await state.loadSolution("ca924c6db7d247b9a31fa30532fb5913", MOCK_USER_SESSION);
239
+ const featureServices = state._testAccess("_getFeatureServices", state.getStoreInfo("solutionData").templates);
240
+ const result = await state._testAccess("_getSpatialReferenceInfo", featureServices, "2865");
241
+ expect(result).toEqual({
242
+ "enabled": true,
243
+ "services": {
244
+ "Driver_Activity": false,
245
+ "OperationsManagement": false,
246
+ "SnowRoutes": false,
247
+ "ServiceAreas": true,
248
+ "Requests": true
249
+ },
250
+ "spatialReference": "2865"
251
+ });
252
+ });
253
+ it("gets spatial reference info using a numeric wkid", async () => {
254
+ jest.spyOn(common, "getItemDataAsJson").mockImplementation(() => JSON.parse(JSON.stringify(solution_ca924c)));
255
+ await state.loadSolution("ca924c6db7d247b9a31fa30532fb5913", MOCK_USER_SESSION);
256
+ const featureServices = state._testAccess("_getFeatureServices", state.getStoreInfo("solutionData").templates);
257
+ const result = await state._testAccess("_getSpatialReferenceInfo", featureServices, 2865);
258
+ expect(result).toEqual({
259
+ "enabled": true,
260
+ "services": {
261
+ "Driver_Activity": false,
262
+ "OperationsManagement": false,
263
+ "SnowRoutes": false,
264
+ "ServiceAreas": true,
265
+ "Requests": true
266
+ },
267
+ "spatialReference": 2865
268
+ });
269
+ });
270
+ it("gets spatial reference info using no wkid", async () => {
271
+ jest.spyOn(common, "getItemDataAsJson").mockImplementation(() => JSON.parse(JSON.stringify(solution_ca924c)));
272
+ await state.loadSolution("ca924c6db7d247b9a31fa30532fb5913", MOCK_USER_SESSION);
273
+ const featureServices = state._testAccess("_getFeatureServices", state.getStoreInfo("solutionData").templates);
274
+ const result = await state._testAccess("_getSpatialReferenceInfo", featureServices);
275
+ expect(result).toEqual({
276
+ "enabled": false,
277
+ "services": {
278
+ "Driver_Activity": false,
279
+ "OperationsManagement": false,
280
+ "SnowRoutes": false,
281
+ "ServiceAreas": true,
282
+ "Requests": true
283
+ },
284
+ "spatialReference": undefined
285
+ });
286
+ });
287
+ });
288
+ it("prepares a solution for editing", async () => {
289
+ // Get the templates; parse+stringify seems only working way to avoid modifying data file
290
+ const solutionData = JSON.parse(JSON.stringify(solution_ca924c));
291
+ // Provide thumbnail images for the templates
292
+ const sampleImageFile = testUtils.getSampleImageAsFile();
293
+ jest.spyOn(common, "getThumbnailFromStorageItem").mockResolvedValue(sampleImageFile);
294
+ await state._testAccess("_prepareSolutionItemsForEditing", "ca924c6db7d247b9a31fa30532fb5913", solutionData.templates, MOCK_USER_SESSION);
295
+ // Check that the augmentation has been added to each template
296
+ expect(solutionData.templates.filter(t => t.hasOwnProperty("resourceFilePaths")).length).toEqual(solutionData.templates.length);
297
+ expect(solutionData.templates.filter(t => t.hasOwnProperty("thumbnail")).length).toEqual(solutionData.templates.length);
298
+ expect(solutionData.templates.filter(t => t.hasOwnProperty("groupDetails")).length).toEqual(solutionData.templates.length);
299
+ });
300
+ describe("_prepareSolutionItemsForStorage", () => {
301
+ const originalConsoleLog = console.log;
302
+ beforeEach(() => {
303
+ console.log = jest.fn();
304
+ });
305
+ afterEach(() => {
306
+ console.log = originalConsoleLog;
307
+ });
308
+ it("prepares a solution for storage", async () => {
309
+ // Get the templates; parse+stringify seems only working way to avoid modifying data file
310
+ const solutionData = JSON.parse(JSON.stringify(solution_ca924c));
311
+ // Provide thumbnail images for the templates and prepare the templates for editing
312
+ const sampleImageFile = testUtils.getSampleImageAsFile();
313
+ jest.spyOn(common, "getThumbnailFromStorageItem").mockResolvedValue(sampleImageFile);
314
+ await state._testAccess("_prepareSolutionItemsForEditing", "ca924c6db7d247b9a31fa30532fb5913", solutionData.templates, MOCK_USER_SESSION);
315
+ // Provide some resource mods
316
+ const template = solutionData.templates[0];
317
+ template.resourceFilePaths.push({
318
+ blob: sampleImageFile,
319
+ filename: sampleImageFile.name,
320
+ type: common.EFileType.Resource,
321
+ updateType: EUpdateType.Add
322
+ });
323
+ template.resourceFilePaths.push({
324
+ blob: sampleImageFile,
325
+ filename: template.resourceFilePaths[1].filename,
326
+ type: common.EFileType.Thumbnail,
327
+ updateType: EUpdateType.Update
328
+ });
329
+ template.resourceFilePaths.push({
330
+ filename: template.resourceFilePaths[0].filename,
331
+ type: common.EFileType.Metadata,
332
+ updateType: EUpdateType.Remove
333
+ });
334
+ // Run the prep
335
+ jest.spyOn(common, "copyFilesToStorageItem").mockResolvedValue([template.itemId + "_info_dataz/" + sampleImageFile.name]);
336
+ jest.spyOn(common, "removeItemResourceFile").mockResolvedValue({ success: true });
337
+ jest.spyOn(common, "updateItemResourceFile").mockResolvedValue({ success: true, itemId: "abc", owner: "def", folder: "ghi" });
338
+ expect(template.resourceFilePaths.length).toEqual(5);
339
+ await state._testAccess("_prepareSolutionItemsForStorage", "ca924c6db7d247b9a31fa30532fb5913", solutionData.templates, MOCK_USER_SESSION);
340
+ expect(template.resources).toEqual([
341
+ "79036430a6274e17ae915d0278b8569c_info_thumbnail/thumbnail.JPEG",
342
+ "79036430a6274e17ae915d0278b8569c/" + sampleImageFile.name
343
+ ]);
344
+ // Check that the augmentation has been removed from each template
345
+ expect(solutionData.templates.some(t => t.hasOwnProperty("resourceFilePaths"))).toBeFalsy();
346
+ expect(solutionData.templates.some(t => t.hasOwnProperty("thumbnail"))).toBeFalsy();
347
+ expect(solutionData.templates.some(t => t.hasOwnProperty("groupDetails"))).toBeFalsy();
348
+ });
349
+ it("catches errors updating or removing resources while preparing a solution for storage", async () => {
350
+ jest.spyOn(console, "log").mockImplementation(() => { });
351
+ // Get the templates; parse+stringify seems only working way to avoid modifying data file
352
+ const solutionData = JSON.parse(JSON.stringify(solution_ca924c));
353
+ // Provide thumbnail images for the templates and prepare the templates for editing
354
+ const sampleImageFile = testUtils.getSampleImageAsFile();
355
+ jest.spyOn(common, "getThumbnailFromStorageItem").mockResolvedValue(sampleImageFile);
356
+ await state._testAccess("_prepareSolutionItemsForEditing", "ca924c6db7d247b9a31fa30532fb5913", solutionData.templates, MOCK_USER_SESSION);
357
+ // Provide some resource mods
358
+ const template = solutionData.templates[0];
359
+ template.resourceFilePaths.push({
360
+ blob: sampleImageFile,
361
+ filename: template.resourceFilePaths[1].filename,
362
+ type: common.EFileType.Thumbnail,
363
+ updateType: EUpdateType.Update
364
+ });
365
+ template.resourceFilePaths.push({
366
+ filename: template.resourceFilePaths[0].filename,
367
+ type: common.EFileType.Metadata,
368
+ updateType: EUpdateType.Remove
369
+ });
370
+ // Run the prep
371
+ jest.spyOn(console, "log").mockImplementation(() => { }); // hide error messages from _prepareSolutionItemsForStorage
372
+ jest.spyOn(common, "removeItemResourceFile").mockImplementation(() => { throw new Error("Item does not exist or is inaccessible."); });
373
+ jest.spyOn(common, "updateItemResourceFile").mockImplementation(() => { throw new Error("Item does not exist or is inaccessible."); });
374
+ expect(template.resourceFilePaths.length).toEqual(4);
375
+ await state._testAccess("_prepareSolutionItemsForStorage", "ca924c6db7d247b9a31fa30532fb5913", solutionData.templates, MOCK_USER_SESSION);
376
+ expect(template.resources).toEqual([
377
+ "79036430a6274e17ae915d0278b8569c_info_metadata/metadata.xml",
378
+ "79036430a6274e17ae915d0278b8569c_info_thumbnail/thumbnail.JPEG"
379
+ ]);
380
+ // Check that the augmentation has been removed from each template
381
+ expect(solutionData.templates.some(t => t.hasOwnProperty("resourceFilePaths"))).toBeFalsy();
382
+ expect(solutionData.templates.some(t => t.hasOwnProperty("thumbnail"))).toBeFalsy();
383
+ expect(solutionData.templates.some(t => t.hasOwnProperty("groupDetails"))).toBeFalsy();
384
+ });
385
+ });
386
+ describe("_setSpatialReferenceInfo", () => {
387
+ it("handles an enabled custom spatial reference", () => {
388
+ jest.spyOn(common, "setCreateProp").mockImplementation(() => { });
389
+ const spatialReferenceInfo = {
390
+ enabled: true,
391
+ services: {
392
+ "Driver_Activity": false,
393
+ "OperationsManagement": true,
394
+ "Requests": false,
395
+ "ServiceAreas": true,
396
+ "SnowRoutes": false // has "wkid": 4326
397
+ },
398
+ spatialReference: 2865
399
+ };
400
+ const solutionTemplates = JSON.parse(JSON.stringify(solution_ca924c)).templates;
401
+ const updatedWkid = state._testAccess("_setSpatialReferenceInfo", spatialReferenceInfo, solutionTemplates);
402
+ expect(updatedWkid).toEqual(2865);
403
+ });
404
+ it("handles a disabled custom spatial reference", () => {
405
+ jest.spyOn(common, "setCreateProp").mockImplementation(() => { });
406
+ const spatialReferenceInfo = {
407
+ enabled: false,
408
+ services: {
409
+ "Driver_Activity": false,
410
+ "OperationsManagement": true,
411
+ "Requests": false,
412
+ "ServiceAreas": true,
413
+ "SnowRoutes": false // has "wkid": 4326
414
+ },
415
+ spatialReference: 2865
416
+ };
417
+ const solutionTemplates = JSON.parse(JSON.stringify(solution_ca924c)).templates;
418
+ const updatedWkid = state._testAccess("_setSpatialReferenceInfo", spatialReferenceInfo, solutionTemplates);
419
+ expect(updatedWkid).toBeUndefined();
420
+ });
421
+ });
422
+ describe("_splitFilename", () => {
423
+ it("handles filename without prefix", () => {
424
+ const { prefix, suffix } = state._testAccess("_splitFilename", "sample.txt");
425
+ expect(prefix).toBeUndefined();
426
+ expect(suffix).toEqual("sample.txt");
427
+ });
428
+ it("handles filename with single prefix", () => {
429
+ const { prefix, suffix } = state._testAccess("_splitFilename", "folder/sample.txt");
430
+ expect(prefix).toEqual("folder");
431
+ expect(suffix).toEqual("sample.txt");
432
+ });
433
+ it("handles filename with multiple prefixes", () => {
434
+ const { prefix, suffix } = state._testAccess("_splitFilename", "folder/subfolder/sample.txt");
435
+ expect(prefix).toEqual("folder/subfolder");
436
+ expect(suffix).toEqual("sample.txt");
437
+ });
438
+ });
439
+ });
@@ -0,0 +1,135 @@
1
+ /** @license
2
+ * Copyright 2022 Esri
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import * as common from "@esri/solution-common";
17
+ //--------------------------------------------------------------------------------------------------------------------//
18
+ export const PORTAL_URL = "https://myorg.maps.arcgis.com";
19
+ /**
20
+ * Creates a mock UserSession.
21
+ *
22
+ * @param now Time for token; defaults to Date.now
23
+ * @param portalUrl Portal for token; defaults to "https://myorg.maps.arcgis.com"
24
+ *
25
+ * @returns Mock UserSession
26
+ */
27
+ export function createRuntimeMockUserSession(now, portalUrl) {
28
+ if (now === undefined) {
29
+ now = Date.now();
30
+ }
31
+ const tomorrow = new Date(now + 86400000);
32
+ return new common.UserSession({
33
+ clientId: "clientId",
34
+ redirectUri: "https://example-app.com/redirect-uri",
35
+ token: "fake-token",
36
+ tokenExpires: tomorrow,
37
+ refreshToken: "refreshToken",
38
+ refreshTokenExpires: tomorrow,
39
+ refreshTokenTTL: 1440,
40
+ username: "casey",
41
+ password: "123456",
42
+ portal: (portalUrl || PORTAL_URL) + "/sharing/rest"
43
+ });
44
+ }
45
+ /**
46
+ * Creates a mock image file.
47
+ *
48
+ * @param filename Name to give file; defaults to "sampleImage"
49
+ *
50
+ * @returns Buffer usable as a File
51
+ */
52
+ export function getSampleImageAsFile(filename = "sampleImage.png") {
53
+ const pseudoFile = Buffer.from(_imageAsDataUri(), 'base64');
54
+ pseudoFile.name = filename;
55
+ return pseudoFile;
56
+ }
57
+ export function getSampleItemEdit(itemId = "bd4a2dafd7584253a1bc772f2dd510c4") {
58
+ let itemEdit = {
59
+ "itemId": "bd4a2dafd7584253a1bc772f2dd510c4",
60
+ "type": "QuickCapture Project",
61
+ "key": "i7t8659n",
62
+ "resources": [
63
+ "bd4a2dafd7584253a1bc772f2dd510c4/qc.project.json",
64
+ "bd4a2dafd7584253a1bc772f2dd510c4_info_thumbnail/esri_133.png"
65
+ ],
66
+ "dependencies": ["79036430a6274e17ae915d0278b8569c"],
67
+ "groups": ["90766e8ee450438fb507d7d2cd03df20"],
68
+ "estimatedDeploymentCostFactor": 2,
69
+ "relatedItems": [],
70
+ "data": {},
71
+ "item": {
72
+ "id": "{{bd4a2dafd7584253a1bc772f2dd510c4.itemId}}",
73
+ "type": "QuickCapture Project",
74
+ "accessInformation": "Esri",
75
+ "categories": [],
76
+ "culture": "en-us",
77
+ "description": "An ArcGIS QuickCapture project description",
78
+ "extent": [],
79
+ "licenseInfo": "Copyright 2022 Esri",
80
+ "name": null,
81
+ "properties": null,
82
+ "snippet": "An ArcGIS QuickCapture project snippet",
83
+ "tags": [],
84
+ "thumbnail": null,
85
+ "title": "Status Reporter",
86
+ "typeKeywords": [
87
+ "QuickCapture",
88
+ "QuickCapture Project"
89
+ ],
90
+ "url": null,
91
+ "created": 1645216385000,
92
+ "modified": 1645219985000
93
+ },
94
+ "properties": {},
95
+ "resourceFilePaths": [{
96
+ "url": "https://www.arcgis.com/sharing/rest/content/items/ca924c6db7d247b9a31fa30532fb5913/resources/bd4a2dafd7584253a1bc772f2dd510c4/qc.project.json",
97
+ "type": 3,
98
+ "folder": "",
99
+ "filename": "qc.project.json",
100
+ "updateType": 3
101
+ }, {
102
+ "url": "https://www.arcgis.com/sharing/rest/content/items/ca924c6db7d247b9a31fa30532fb5913/resources/bd4a2dafd7584253a1bc772f2dd510c4_info_thumbnail/esri_133.png",
103
+ "type": 4,
104
+ "folder": "",
105
+ "filename": "esri_133.png",
106
+ "updateType": 3
107
+ }],
108
+ "thumbnail": null
109
+ };
110
+ if (itemId !== "bd4a2dafd7584253a1bc772f2dd510c4") {
111
+ itemEdit = JSON.parse(JSON.stringify(itemEdit).replace(/bd4a2dafd7584253a1bc772f2dd510c4/g, itemId));
112
+ }
113
+ return itemEdit;
114
+ }
115
+ //--------------------------------------------------------------------------------------------------------------------//
116
+ function _imageAsDataUri() {
117
+ return "\
118
+ iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAYAAAA7bUf6AAADKklEQVQ4T6XUf1DMeRzH8edu\
119
+ 53ZVZ6vLxmo2Q0Y7rtJZJT8abQmdysjETVEWMxgGOzF2/IhkCqNT8qPyo8PE6fzIj/y4qYlU\
120
+ E6MfIottFcLmRyIq1Ne4neGa+ufG57/354/H+/3H6/0WCYIg8J1P1BNSkJ/PpXO5tLa187q5\
121
+ mTFqL6ZFzMRxgEuP7boh00JCcbB3IGZfFuM8f8PbfSD1IyIR3byI8uFVJoxRk5C4uQvWBfHx\
122
+ VHO44jKqcC0/BKgQ7tbzIS0LhvhDX3d400DkSAUFZ3MwPXyAVCr9F/uKhAaHkpqbQkhGEAa9\
123
+ EZeRcmpVOlCFQVwMbvqpLPA/QoruHnYSV+4V1tHS/vYbcqv6Fv4af6zVtsismnB0FmM9qQZB\
124
+ ZsuNljdMtttN+fIEtMcm0NgqJmtZGevnJmGqqCNxc6JlktjYWNKT9zIxU463jxKjIYmm65ex\
125
+ cfWi7Nga+nSWUV4k4DxchlQuobbCzJYjyRxYkEVVTZUFCZsShlTexnXvEXgN30RHzjZyk1cQ\
126
+ vjIV57FP6a/4B5NBoOxsI+rFbhhN7yjfaGC0Us3pvDMWJDI8gvczPTgVfwOeVhC8NJ7G0nME\
127
+ xf1JbWsREg5gZ99E9qxiNJl+PGn7xP3974myH8WGTXEWZFKAhqZ+7lzLTsX6xB1G/dSbj49f\
128
+ U5O9lbeD1Xy4dAGxqB7pCwMSNwc6nKywFfkSoXDmj107LUjE1BCkwToO7dEzPuoFbn5OFCWZ\
129
+ uX28FqavA1UgWDkhM6+gQ2agRTkam5SXaAa1czrvogUpLb5Kys59/BXox4+rtIhteuM51xUH\
130
+ p07Op6nhdz20ixHJVyMUXIEwHZq8Z8wJ+oWoGO23nPj+6kGgLo0E7Xysx5pxiffl1RMfzGsr\
131
+ Yag7PKgGaQnUP2f8koU4ltSRcz6va9i+VErHPizKNaDfmApt2yFwPuwogcZyWFsFvQpZKDFy\
132
+ 91Qlh/4+ikKh6I58+fH2GIZXgIbS6mKq8+8jOfiIwXWFPDu5C130DNYtm8ejhoavQJfY/3ej\
133
+ blZWkpGegclk5FPzc2ztfqa1o5OoWdFEzo7utsk9noL/e14+AxP0YqryqgPxAAAAAElFTkSu\
134
+ QmCC";
135
+ }
@@ -0,0 +1,14 @@
1
+ /*
2
+ * Copyright (c) 2022 Esri
3
+ * All rights reserved.
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ * Unless required by applicable law or agreed to in writing, software
9
+ * distributed under the License is distributed on an "AS IS" BASIS,
10
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ * See the License for the specific language governing permissions and
12
+ * limitations under the License.
13
+ */
14
+ export {};
@@ -0,0 +1,7 @@
1
+ Built 05/09/2023 13:06:02.97
2
+ HEAD
3
+ commit 4408542c7be6277df4563d0a40f84246e37656db
4
+ Author: John Hauck <jhauck@esri.com>
5
+ Date: Fri May 5 17:28:29 2023 -0600
6
+
7
+ update version
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@esri/solutions-components",
3
- "version": "0.5.3",
3
+ "version": "0.5.4",
4
4
  "description": "Web Components for Esri's Solutions Applications",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.js",
@@ -31,7 +31,7 @@
31
31
  },
32
32
  "devDependencies": {
33
33
  "@esri/eslint-plugin-calcite-components": "^0.2.2",
34
- "@esri/solution-common": "1.5.3",
34
+ "@esri/solution-common": "3.0.1",
35
35
  "@stencil/postcss": "^2.1.0",
36
36
  "@stencil/sass": "^2.0.0",
37
37
  "@stencil/store": "^2.0.1",
@@ -66,6 +66,10 @@
66
66
  "typescript": "^4.8.4"
67
67
  },
68
68
  "dependencies": {
69
+ "@esri/hub-common": "^12.37.1",
70
+ "@esri/hub-initiatives": "^12.4.1",
71
+ "@esri/hub-sites": "^12.6.0",
72
+ "@esri/hub-teams": "^12.4.1",
69
73
  "@pdf-lib/fontkit": "^1.1.1",
70
74
  "@stencil/core": "^2.20.0",
71
75
  "focus-trap": "7.2.0",
@@ -79,11 +83,7 @@
79
83
  "@esri/arcgis-rest-portal": "^3.4.2",
80
84
  "@esri/arcgis-rest-request": "^3.4.2",
81
85
  "@esri/arcgis-rest-service-admin": "^3.4.2",
82
- "@esri/calcite-components": "^1.0.7",
83
- "@esri/hub-common": "9.29.0",
84
- "@esri/hub-initiatives": "9.29.0",
85
- "@esri/hub-sites": "9.29.0",
86
- "@esri/hub-teams": "9.29.0"
86
+ "@esri/calcite-components": "^1.0.7"
87
87
  },
88
88
  "repository": {
89
89
  "type": "git",