@esri/solutions-components 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
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",