@itwin/reports-config-widget-react 0.1.0 → 0.2.1

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 (250) hide show
  1. package/.rush/temp/package-deps_rebuild.json +38 -34
  2. package/.rush/temp/shrinkwrap-deps.json +14 -6
  3. package/CHANGELOG.json +30 -0
  4. package/CHANGELOG.md +17 -1
  5. package/coverage/clover.xml +605 -610
  6. package/coverage/coverage-final.json +28 -27
  7. package/coverage/lcov-report/index.html +31 -31
  8. package/coverage/lcov-report/src/ReportsConfigWidget.ts.html +10 -10
  9. package/coverage/lcov-report/src/index.html +1 -1
  10. package/coverage/lcov-report/src/test/index.html +1 -1
  11. package/coverage/lcov-report/src/test/test-utils.tsx.html +22 -22
  12. package/coverage/lcov-report/src/widget/ReportsConfigUiProvider.tsx.html +7 -7
  13. package/coverage/lcov-report/src/widget/components/ActionPanel.tsx.html +29 -41
  14. package/coverage/lcov-report/src/widget/components/AddMappingsModal.tsx.html +31 -37
  15. package/coverage/lcov-report/src/widget/components/BulkExtractor.ts.html +270 -162
  16. package/coverage/lcov-report/src/widget/components/Constants.ts.html +4 -4
  17. package/coverage/lcov-report/src/widget/components/DeleteModal.tsx.html +21 -21
  18. package/coverage/lcov-report/src/widget/components/ExtractionStates/FailedExtractionState.tsx.html +6 -6
  19. package/coverage/lcov-report/src/widget/components/ExtractionStates/QueuedExtractionState.tsx.html +14 -14
  20. package/coverage/lcov-report/src/widget/components/ExtractionStates/RunningExtractionState.tsx.html +15 -15
  21. package/coverage/lcov-report/src/widget/components/ExtractionStates/StartingExtractionState.tsx.html +14 -14
  22. package/coverage/lcov-report/src/widget/components/ExtractionStates/SucceededExtractionState.tsx.html +22 -19
  23. package/coverage/lcov-report/src/widget/components/ExtractionStates/index.html +43 -43
  24. package/coverage/lcov-report/src/widget/components/ExtractionStatus.tsx.html +57 -57
  25. package/coverage/lcov-report/src/widget/components/ExtractionToast.tsx.html +208 -0
  26. package/coverage/lcov-report/src/widget/components/HorizontalTile.tsx.html +8 -8
  27. package/coverage/lcov-report/src/widget/components/LocalizedTablePaginator.tsx.html +8 -8
  28. package/coverage/lcov-report/src/widget/components/ReportAction.tsx.html +14 -20
  29. package/coverage/lcov-report/src/widget/components/ReportHorizontalTile.tsx.html +30 -33
  30. package/coverage/lcov-report/src/widget/components/ReportMappingHorizontalTile.tsx.html +469 -0
  31. package/coverage/lcov-report/src/widget/components/ReportMappings.tsx.html +183 -231
  32. package/coverage/lcov-report/src/widget/components/Reports.tsx.html +73 -43
  33. package/coverage/lcov-report/src/widget/components/ReportsContainer.tsx.html +10 -10
  34. package/coverage/lcov-report/src/widget/components/SearchBar.tsx.html +10 -10
  35. package/coverage/lcov-report/src/widget/components/SelectIModel.tsx.html +31 -31
  36. package/coverage/lcov-report/src/widget/components/index.html +100 -85
  37. package/coverage/lcov-report/src/widget/components/utils.tsx.html +32 -32
  38. package/coverage/lcov-report/src/widget/context/ReportsApiConfigContext.tsx.html +8 -8
  39. package/coverage/lcov-report/src/widget/context/index.html +1 -1
  40. package/coverage/lcov-report/src/widget/hooks/index.html +1 -1
  41. package/coverage/lcov-report/src/widget/hooks/useValidator.ts.html +7 -7
  42. package/coverage/lcov-report/src/widget/index.html +1 -1
  43. package/coverage/lcov.info +990 -1003
  44. package/jest.config.js +6 -0
  45. package/lib/cjs/test/AddMappingModal.test.d.ts +2 -0
  46. package/lib/cjs/test/AddMappingModal.test.d.ts.map +1 -0
  47. package/lib/cjs/test/AddMappingModal.test.js +277 -0
  48. package/lib/cjs/test/AddMappingModal.test.js.map +1 -0
  49. package/lib/cjs/test/BulkExtractor.test.d.ts +2 -0
  50. package/lib/cjs/test/BulkExtractor.test.d.ts.map +1 -0
  51. package/lib/cjs/test/BulkExtractor.test.js +182 -0
  52. package/lib/cjs/test/BulkExtractor.test.js.map +1 -0
  53. package/lib/cjs/test/DeleteModal.test.d.ts +2 -0
  54. package/lib/cjs/test/DeleteModal.test.d.ts.map +1 -0
  55. package/lib/cjs/test/DeleteModal.test.js +93 -0
  56. package/lib/cjs/test/DeleteModal.test.js.map +1 -0
  57. package/lib/cjs/test/ReportAction.test.js +2 -3
  58. package/lib/cjs/test/ReportAction.test.js.map +1 -1
  59. package/lib/cjs/test/ReportMappingHorizontalTile.test.d.ts +2 -0
  60. package/lib/cjs/test/ReportMappingHorizontalTile.test.d.ts.map +1 -0
  61. package/lib/cjs/test/ReportMappingHorizontalTile.test.js +340 -0
  62. package/lib/cjs/test/ReportMappingHorizontalTile.test.js.map +1 -0
  63. package/lib/cjs/test/ReportMappings.test.js +115 -267
  64. package/lib/cjs/test/ReportMappings.test.js.map +1 -1
  65. package/lib/cjs/test/Reports.test.js +1 -1
  66. package/lib/cjs/test/Reports.test.js.map +1 -1
  67. package/lib/cjs/tsconfig.tsbuildinfo +1 -1
  68. package/lib/cjs/widget/components/ActionPanel.d.ts.map +1 -1
  69. package/lib/cjs/widget/components/ActionPanel.js +4 -5
  70. package/lib/cjs/widget/components/ActionPanel.js.map +1 -1
  71. package/lib/cjs/widget/components/AddMappingsModal.d.ts +2 -2
  72. package/lib/cjs/widget/components/AddMappingsModal.d.ts.map +1 -1
  73. package/lib/cjs/widget/components/AddMappingsModal.js +5 -4
  74. package/lib/cjs/widget/components/AddMappingsModal.js.map +1 -1
  75. package/lib/cjs/widget/components/AddMappingsModal.scss +4 -3
  76. package/lib/cjs/widget/components/BulkExtractor.d.ts +18 -9
  77. package/lib/cjs/widget/components/BulkExtractor.d.ts.map +1 -1
  78. package/lib/cjs/widget/components/BulkExtractor.js +86 -57
  79. package/lib/cjs/widget/components/BulkExtractor.js.map +1 -1
  80. package/lib/cjs/widget/components/DeleteModal.js +1 -1
  81. package/lib/cjs/widget/components/DeleteModal.js.map +1 -1
  82. package/lib/cjs/widget/components/DeleteModal.scss +4 -3
  83. package/lib/cjs/widget/components/ExtractionStates/RunningExtractionState.js +1 -1
  84. package/lib/cjs/widget/components/ExtractionStates/RunningExtractionState.js.map +1 -1
  85. package/lib/cjs/widget/components/ExtractionStates/SucceededExtractionState.d.ts.map +1 -1
  86. package/lib/cjs/widget/components/ExtractionStates/SucceededExtractionState.js +1 -1
  87. package/lib/cjs/widget/components/ExtractionStates/SucceededExtractionState.js.map +1 -1
  88. package/lib/cjs/widget/components/ExtractionStatus.scss +15 -1
  89. package/lib/cjs/widget/components/ExtractionToast.d.ts +11 -0
  90. package/lib/cjs/widget/components/ExtractionToast.d.ts.map +1 -0
  91. package/lib/cjs/widget/components/ExtractionToast.js +33 -0
  92. package/lib/cjs/widget/components/ExtractionToast.js.map +1 -0
  93. package/lib/cjs/widget/components/HorizontalTile.scss +1 -1
  94. package/lib/cjs/widget/components/ReportAction.d.ts.map +1 -1
  95. package/lib/cjs/widget/components/ReportAction.js +3 -3
  96. package/lib/cjs/widget/components/ReportAction.js.map +1 -1
  97. package/lib/cjs/widget/components/ReportAction.scss +2 -2
  98. package/lib/cjs/widget/components/ReportHorizontalTile.d.ts.map +1 -1
  99. package/lib/cjs/widget/components/ReportHorizontalTile.js +1 -2
  100. package/lib/cjs/widget/components/ReportHorizontalTile.js.map +1 -1
  101. package/lib/cjs/widget/components/ReportMappingHorizontalTile.d.ts +13 -0
  102. package/lib/cjs/widget/components/ReportMappingHorizontalTile.d.ts.map +1 -0
  103. package/lib/cjs/widget/components/ReportMappingHorizontalTile.js +82 -0
  104. package/lib/cjs/widget/components/ReportMappingHorizontalTile.js.map +1 -0
  105. package/lib/cjs/widget/components/ReportMappings.d.ts +3 -1
  106. package/lib/cjs/widget/components/ReportMappings.d.ts.map +1 -1
  107. package/lib/cjs/widget/components/ReportMappings.js +39 -40
  108. package/lib/cjs/widget/components/ReportMappings.js.map +1 -1
  109. package/lib/cjs/widget/components/ReportMappings.scss +7 -7
  110. package/lib/cjs/widget/components/Reports.d.ts.map +1 -1
  111. package/lib/cjs/widget/components/Reports.js +13 -6
  112. package/lib/cjs/widget/components/Reports.js.map +1 -1
  113. package/lib/cjs/widget/components/Reports.scss +1 -1
  114. package/lib/cjs/widget/components/ReportsContainer.js +1 -1
  115. package/lib/cjs/widget/components/ReportsContainer.js.map +1 -1
  116. package/lib/cjs/widget/components/ReportsContainer.scss +2 -2
  117. package/lib/cjs/widget/components/SelectIModel.js +2 -2
  118. package/lib/cjs/widget/components/SelectIModel.js.map +1 -1
  119. package/lib/cjs/widget/components/SelectIModel.scss +4 -3
  120. package/lib/cjs/widget/components/utils.js +1 -1
  121. package/lib/cjs/widget/components/utils.js.map +1 -1
  122. package/lib/cjs/widget/components/utils.scss +2 -2
  123. package/lib/esm/test/AddMappingModal.test.d.ts +2 -0
  124. package/lib/esm/test/AddMappingModal.test.d.ts.map +1 -0
  125. package/lib/esm/test/AddMappingModal.test.js +253 -0
  126. package/lib/esm/test/AddMappingModal.test.js.map +1 -0
  127. package/lib/esm/test/BulkExtractor.test.d.ts +2 -0
  128. package/lib/esm/test/BulkExtractor.test.d.ts.map +1 -0
  129. package/lib/esm/test/BulkExtractor.test.js +158 -0
  130. package/lib/esm/test/BulkExtractor.test.js.map +1 -0
  131. package/lib/esm/test/DeleteModal.test.d.ts +2 -0
  132. package/lib/esm/test/DeleteModal.test.d.ts.map +1 -0
  133. package/lib/esm/test/DeleteModal.test.js +69 -0
  134. package/lib/esm/test/DeleteModal.test.js.map +1 -0
  135. package/lib/esm/test/ReportAction.test.js +2 -3
  136. package/lib/esm/test/ReportAction.test.js.map +1 -1
  137. package/lib/esm/test/ReportMappingHorizontalTile.test.d.ts +2 -0
  138. package/lib/esm/test/ReportMappingHorizontalTile.test.d.ts.map +1 -0
  139. package/lib/esm/test/ReportMappingHorizontalTile.test.js +316 -0
  140. package/lib/esm/test/ReportMappingHorizontalTile.test.js.map +1 -0
  141. package/lib/esm/test/ReportMappings.test.js +117 -269
  142. package/lib/esm/test/ReportMappings.test.js.map +1 -1
  143. package/lib/esm/test/Reports.test.js +1 -1
  144. package/lib/esm/test/Reports.test.js.map +1 -1
  145. package/lib/esm/tsconfig.tsbuildinfo +1 -1
  146. package/lib/esm/widget/components/ActionPanel.d.ts.map +1 -1
  147. package/lib/esm/widget/components/ActionPanel.js +4 -5
  148. package/lib/esm/widget/components/ActionPanel.js.map +1 -1
  149. package/lib/esm/widget/components/AddMappingsModal.d.ts +2 -2
  150. package/lib/esm/widget/components/AddMappingsModal.d.ts.map +1 -1
  151. package/lib/esm/widget/components/AddMappingsModal.js +4 -5
  152. package/lib/esm/widget/components/AddMappingsModal.js.map +1 -1
  153. package/lib/esm/widget/components/AddMappingsModal.scss +4 -3
  154. package/lib/esm/widget/components/BulkExtractor.d.ts +18 -9
  155. package/lib/esm/widget/components/BulkExtractor.d.ts.map +1 -1
  156. package/lib/esm/widget/components/BulkExtractor.js +86 -57
  157. package/lib/esm/widget/components/BulkExtractor.js.map +1 -1
  158. package/lib/esm/widget/components/DeleteModal.js +1 -1
  159. package/lib/esm/widget/components/DeleteModal.js.map +1 -1
  160. package/lib/esm/widget/components/DeleteModal.scss +4 -3
  161. package/lib/esm/widget/components/ExtractionStates/RunningExtractionState.js +1 -1
  162. package/lib/esm/widget/components/ExtractionStates/RunningExtractionState.js.map +1 -1
  163. package/lib/esm/widget/components/ExtractionStates/SucceededExtractionState.d.ts.map +1 -1
  164. package/lib/esm/widget/components/ExtractionStates/SucceededExtractionState.js +1 -1
  165. package/lib/esm/widget/components/ExtractionStates/SucceededExtractionState.js.map +1 -1
  166. package/lib/esm/widget/components/ExtractionStatus.scss +15 -1
  167. package/lib/esm/widget/components/ExtractionToast.d.ts +11 -0
  168. package/lib/esm/widget/components/ExtractionToast.d.ts.map +1 -0
  169. package/lib/esm/widget/components/ExtractionToast.js +25 -0
  170. package/lib/esm/widget/components/ExtractionToast.js.map +1 -0
  171. package/lib/esm/widget/components/HorizontalTile.scss +1 -1
  172. package/lib/esm/widget/components/ReportAction.d.ts.map +1 -1
  173. package/lib/esm/widget/components/ReportAction.js +3 -3
  174. package/lib/esm/widget/components/ReportAction.js.map +1 -1
  175. package/lib/esm/widget/components/ReportAction.scss +2 -2
  176. package/lib/esm/widget/components/ReportHorizontalTile.d.ts.map +1 -1
  177. package/lib/esm/widget/components/ReportHorizontalTile.js +1 -2
  178. package/lib/esm/widget/components/ReportHorizontalTile.js.map +1 -1
  179. package/lib/esm/widget/components/ReportMappingHorizontalTile.d.ts +13 -0
  180. package/lib/esm/widget/components/ReportMappingHorizontalTile.d.ts.map +1 -0
  181. package/lib/esm/widget/components/ReportMappingHorizontalTile.js +75 -0
  182. package/lib/esm/widget/components/ReportMappingHorizontalTile.js.map +1 -0
  183. package/lib/esm/widget/components/ReportMappings.d.ts +3 -1
  184. package/lib/esm/widget/components/ReportMappings.d.ts.map +1 -1
  185. package/lib/esm/widget/components/ReportMappings.js +40 -41
  186. package/lib/esm/widget/components/ReportMappings.js.map +1 -1
  187. package/lib/esm/widget/components/ReportMappings.scss +7 -7
  188. package/lib/esm/widget/components/Reports.d.ts.map +1 -1
  189. package/lib/esm/widget/components/Reports.js +15 -8
  190. package/lib/esm/widget/components/Reports.js.map +1 -1
  191. package/lib/esm/widget/components/Reports.scss +1 -1
  192. package/lib/esm/widget/components/ReportsContainer.js +1 -1
  193. package/lib/esm/widget/components/ReportsContainer.js.map +1 -1
  194. package/lib/esm/widget/components/ReportsContainer.scss +2 -2
  195. package/lib/esm/widget/components/SelectIModel.js +2 -2
  196. package/lib/esm/widget/components/SelectIModel.js.map +1 -1
  197. package/lib/esm/widget/components/SelectIModel.scss +4 -3
  198. package/lib/esm/widget/components/utils.js +1 -1
  199. package/lib/esm/widget/components/utils.js.map +1 -1
  200. package/lib/esm/widget/components/utils.scss +2 -2
  201. package/lib/public/locales/en/ReportsConfigWidget.json +5 -0
  202. package/package.json +7 -4
  203. package/public/locales/en/ReportsConfigWidget.json +5 -0
  204. package/reports-config-widget-react.build.error.log +10 -6
  205. package/reports-config-widget-react.build.log +51 -46
  206. package/src/test/AddMappingModal.test.tsx +315 -0
  207. package/src/test/BulkExtractor.test.ts +301 -0
  208. package/src/test/DeleteModal.test.tsx +118 -0
  209. package/src/test/ReportAction.test.tsx +2 -4
  210. package/src/test/ReportMappingHorizontalTile.test.tsx +451 -0
  211. package/src/test/ReportMappings.test.tsx +154 -549
  212. package/src/test/Reports.test.tsx +1 -1
  213. package/src/widget/components/ActionPanel.tsx +19 -23
  214. package/src/widget/components/AddMappingsModal.scss +4 -3
  215. package/src/widget/components/AddMappingsModal.tsx +4 -6
  216. package/src/widget/components/BulkExtractor.ts +97 -61
  217. package/src/widget/components/DeleteModal.scss +4 -3
  218. package/src/widget/components/DeleteModal.tsx +1 -1
  219. package/src/widget/components/ExtractionStates/RunningExtractionState.tsx +1 -1
  220. package/src/widget/components/ExtractionStates/SucceededExtractionState.tsx +1 -0
  221. package/src/widget/components/ExtractionStatus.scss +15 -1
  222. package/src/widget/components/ExtractionToast.tsx +41 -0
  223. package/src/widget/components/HorizontalTile.scss +1 -1
  224. package/src/widget/components/ReportAction.scss +2 -2
  225. package/src/widget/components/ReportAction.tsx +1 -3
  226. package/src/widget/components/ReportHorizontalTile.tsx +1 -2
  227. package/src/widget/components/ReportMappingHorizontalTile.tsx +128 -0
  228. package/src/widget/components/ReportMappings.scss +7 -7
  229. package/src/widget/components/ReportMappings.tsx +89 -105
  230. package/src/widget/components/Reports.scss +1 -1
  231. package/src/widget/components/Reports.tsx +18 -8
  232. package/src/widget/components/ReportsContainer.scss +2 -2
  233. package/src/widget/components/ReportsContainer.tsx +1 -1
  234. package/src/widget/components/SelectIModel.scss +4 -3
  235. package/src/widget/components/SelectIModel.tsx +2 -2
  236. package/src/widget/components/utils.scss +2 -2
  237. package/src/widget/components/utils.tsx +1 -1
  238. package/coverage/lcov-report/src/widget/components/Extraction.tsx.html +0 -1030
  239. package/lib/cjs/widget/components/Extraction.d.ts +0 -28
  240. package/lib/cjs/widget/components/Extraction.d.ts.map +0 -1
  241. package/lib/cjs/widget/components/Extraction.js +0 -190
  242. package/lib/cjs/widget/components/Extraction.js.map +0 -1
  243. package/lib/cjs/widget/components/Extraction.scss +0 -39
  244. package/lib/esm/widget/components/Extraction.d.ts +0 -28
  245. package/lib/esm/widget/components/Extraction.d.ts.map +0 -1
  246. package/lib/esm/widget/components/Extraction.js +0 -166
  247. package/lib/esm/widget/components/Extraction.js.map +0 -1
  248. package/lib/esm/widget/components/Extraction.scss +0 -39
  249. package/src/widget/components/Extraction.scss +0 -39
  250. package/src/widget/components/Extraction.tsx +0 -315
@@ -12,33 +12,24 @@ import type {
12
12
  } from "@itwin/core-frontend";
13
13
  import { NoRenderApp } from "@itwin/core-frontend";
14
14
  import { ReportsConfigWidget } from "../ReportsConfigWidget";
15
- import { setupServer } from "msw/node";
16
15
  import {
16
+ act,
17
17
  render,
18
18
  screen,
19
19
  TestUtils,
20
20
  waitForElementToBeRemoved,
21
21
  within,
22
22
  } from "./test-utils";
23
- import userEvent from "@testing-library/user-event";
24
23
  import * as moq from "typemoq";
25
- import type { RequestHandler } from "msw";
26
- import { rest } from "msw";
27
24
  import type {
28
- ExtractionStatusSingle,
29
- Mapping,
30
- MappingCollection,
31
25
  MappingSingle,
32
26
  Report,
33
27
  ReportMappingCollection,
34
28
  } from "@itwin/insights-client";
35
- import {
36
- ExtractorState,
37
- } from "@itwin/insights-client";
29
+ import type { ReportMappingAndMapping } from "../widget/components/ReportMappings";
38
30
  import { ReportMappings } from "../widget/components/ReportMappings";
39
- import { Constants, IModelState } from "@itwin/imodels-client-management";
40
- import { REPORTS_CONFIG_BASE_URL } from "../widget/ReportsConfigUiProvider";
41
- import { REFRESH_DELAY } from "../widget/components/Extraction";
31
+ import type { GetSingleIModelParams, IModelOperations, OperationOptions } from "@itwin/imodels-client-management";
32
+ import { IModelState } from "@itwin/imodels-client-management";
42
33
  import type {
43
34
  SelectionManager,
44
35
  SelectionScopesManager,
@@ -48,9 +39,10 @@ import {
48
39
  SelectionChangeEvent,
49
40
  } from "@itwin/presentation-frontend";
50
41
  import type { BeEvent } from "@itwin/core-bentley";
51
-
52
- // For the extraction test
53
- jest.setTimeout(20000);
42
+ import type BulkExtractor from "../widget/components/BulkExtractor";
43
+ import type { ReportMappingHorizontalTileProps } from "../widget/components/ReportMappingHorizontalTile";
44
+ import { Text } from "@itwin/itwinui-react";
45
+ import { EmptyLocalization } from "@itwin/core-common";
54
46
 
55
47
  const mockITwinId = faker.datatype.uuid();
56
48
  // Lets work with two iModels for now.
@@ -181,7 +173,7 @@ const mockReportMappingsFactory = (): ReportMappingCollection => {
181
173
 
182
174
  const mockMappingsFactory = (
183
175
  mockReportMappings: ReportMappingCollection
184
- ): [MappingSingle[], RequestHandler[]] => {
176
+ ): MappingSingle[] => {
185
177
  const mockMappings: MappingSingle[] = mockReportMappings.mappings.map(
186
178
  (mapping, index) => ({
187
179
  mapping: {
@@ -203,34 +195,78 @@ const mockMappingsFactory = (
203
195
  })
204
196
  );
205
197
 
206
- const iModelHandlers: RequestHandler[] = mockMappings.map((mapping) =>
207
- rest.get(
208
- `${REPORTS_CONFIG_BASE_URL}/insights/reporting/datasources/imodels/${mapping.mapping._links.imodel.href
209
- }/mappings/${mapping.mapping.id}`,
210
- async (_req, res, ctx) => {
211
- return res(ctx.delay(), ctx.status(200), ctx.json(mapping));
212
- }
213
- )
214
- );
215
-
216
- return [mockMappings, iModelHandlers];
198
+ return mockMappings;
217
199
  };
218
200
 
219
201
  const connectionMock = moq.Mock.ofType<IModelConnection>();
202
+ const mockBulkExtractor = moq.Mock.ofType<BulkExtractor>();
220
203
  const selectionManagerMock = moq.Mock.ofType<SelectionManager>();
221
204
  const selectionScopesManagerMock = moq.Mock.ofType<SelectionScopesManager>();
205
+ const mockIModelsClient = moq.Mock.ofType<IModelOperations<OperationOptions>>();
206
+
207
+ interface AddMappingsModalProps {
208
+ reportId: string;
209
+ existingMappings: ReportMappingAndMapping[];
210
+ show: boolean;
211
+ returnFn: () => Promise<void>;
212
+ }
213
+
214
+ jest.mock("../widget/components/Constants.ts", () => ({
215
+ STATUS_CHECK_INTERVAL: 10,
216
+ }));
217
+
218
+ jest.mock("../widget/components/ReportMappingHorizontalTile", () => ({
219
+ ReportMappingHorizontalTile: (props: ReportMappingHorizontalTileProps) => {
220
+ return (<div data-testid="horizontal-tile">
221
+ <Text>{props.mapping.mappingName}</Text>
222
+ <Text title={props.mapping.mappingDescription}>{props.mapping.iModelName}</Text>
223
+ </div>);
224
+ },
225
+ }));
222
226
 
223
227
  jest.mock("@itwin/appui-react", () => ({
224
228
  ...jest.requireActual("@itwin/appui-react"),
225
229
  useActiveIModelConnection: () => connectionMock.object,
226
230
  }));
227
231
 
228
- const server = setupServer();
232
+ let returnFn: () => Promise<void>;
233
+ jest.mock("../widget/components/AddMappingsModal", () => ({
234
+ ...jest.requireActual("../widget/components/AddMappingsModal"),
235
+ AddMappingsModal: (props: AddMappingsModalProps) => {
236
+ returnFn = props.returnFn;
237
+ return <div data-testid="add-mappings-modal"/>;
238
+ },
239
+ }));
240
+
241
+ jest.mock("@itwin/imodels-client-management", () => ({
242
+ ...jest.requireActual("@itwin/imodels-client-management"),
243
+ IModelsClient: jest.fn().mockImplementation(() => ({
244
+ iModels: mockIModelsClient.object,
245
+ })),
246
+ toArray: jest.fn().mockImplementation(async () => {
247
+ return mockProjectIModels.iModels;
248
+ }),
249
+ }));
250
+
251
+ const mockGetMapping = jest.fn();
252
+ const mockGetMappings = jest.fn();
253
+ const mockGetReportMappings = jest.fn();
254
+ const mockDeleteReportMapping = jest.fn();
255
+
256
+ jest.mock("@itwin/insights-client", () => ({
257
+ ...jest.requireActual("@itwin/insights-client"),
258
+ MappingsClient: jest.fn().mockImplementation(() => ({
259
+ getMapping: mockGetMapping,
260
+ getMappings: mockGetMappings,
261
+ })),
262
+ ReportsClient: jest.fn().mockImplementation(() => ({
263
+ getReportMappings: mockGetReportMappings,
264
+ deleteReportMapping: mockDeleteReportMapping,
265
+ })),
266
+ }));
229
267
 
230
268
  beforeAll(async () => {
231
- // This is required by the i18n module within iTwin.js
232
- (global as any).XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; // eslint-disable-line @typescript-eslint/no-var-requires
233
- await NoRenderApp.startup();
269
+ await NoRenderApp.startup({localization: new EmptyLocalization()});
234
270
  await Presentation.initialize();
235
271
  const selectionSet = moq.Mock.ofType<SelectionSet>();
236
272
  const onChanged = moq.Mock.ofType<BeEvent<(ev: SelectionSetEvent) => void>>();
@@ -256,134 +292,62 @@ beforeAll(async () => {
256
292
  Presentation.setSelectionManager(selectionManagerMock.object);
257
293
  await TestUtils.initializeUiFramework(connectionMock.object);
258
294
  await ReportsConfigWidget.initialize();
259
- server.listen();
260
295
  });
261
296
 
262
297
  afterAll(() => {
263
298
  TestUtils.terminateUiFramework();
264
- server.close();
265
299
  });
266
300
 
267
301
  afterEach(() => {
268
- server.resetHandlers();
302
+ mockGetMapping.mockReset();
303
+ mockGetMappings.mockReset();
304
+ mockGetReportMappings.mockReset();
305
+ mockDeleteReportMapping.mockReset();
306
+ mockIModelsClient.reset();
307
+ mockBulkExtractor.reset();
269
308
  });
270
309
 
271
310
  describe("Report Mappings View", () => {
272
311
  it("shows all report mappings", async () => {
273
312
  const mockReportMappings = mockReportMappingsFactory();
274
- const [mockMappings, iModelHandlers] =
275
- mockMappingsFactory(mockReportMappings);
276
-
277
- server.use(
278
- rest.get(
279
- `${REPORTS_CONFIG_BASE_URL}/insights/reporting/reports/${mockReportId}/datasources/imodelMappings`,
280
- async (_req, res, ctx) => {
281
- return res(
282
- ctx.delay(),
283
- ctx.status(200),
284
- ctx.json(mockReportMappings)
285
- );
286
- }
287
- ),
288
- rest.get(
289
- `${Constants.api.baseUrl}/${mockIModelId1}`,
290
- async (_req, res, ctx) => {
291
- return res(
292
- ctx.delay(),
293
- ctx.status(200),
294
- ctx.json(mockIModelsResponse[0])
295
- );
296
- }
297
- ),
298
- rest.get(
299
- `${Constants.api.baseUrl}/${mockIModelId2}`,
300
- async (_req, res, ctx) => {
301
- return res(
302
- ctx.delay(),
303
- ctx.status(200),
304
- ctx.json(mockIModelsResponse[1])
305
- );
306
- }
307
- ),
308
- ...iModelHandlers
309
- );
313
+ const mockMappings = mockMappingsFactory(mockReportMappings);
310
314
 
311
- render(<ReportMappings report={mockReport} goBack={jest.fn()} />);
315
+ mockIModelsClient.setup(async (x) => x.getSingle(moq.It.isObjectWith<GetSingleIModelParams>({ iModelId: mockIModelId1 })))
316
+ .returns(async () => mockIModelsResponse[0].iModel);
312
317
 
313
- await waitForElementToBeRemoved(() => screen.getByText(/loading/i));
318
+ mockIModelsClient.setup(async (x) => x.getSingle(moq.It.isObjectWith<GetSingleIModelParams>({ iModelId: mockIModelId2 })))
319
+ .returns(async () => mockIModelsResponse[1].iModel);
314
320
 
315
- const horizontalTiles = screen.getAllByTestId("horizontal-tile");
321
+ mockGetMapping.mockReturnValueOnce(mockMappings[0].mapping).mockReturnValueOnce(mockMappings[1].mapping);
322
+ mockGetReportMappings.mockReturnValueOnce(mockReportMappings.mappings);
316
323
 
317
- expect(horizontalTiles).toHaveLength(mockMappings.length);
324
+ render(<ReportMappings report={mockReport} bulkExtractor={mockBulkExtractor.object} goBack={jest.fn()} />);
318
325
 
319
- for (const [index, horizontalTile] of horizontalTiles.entries()) {
320
- const reportMappingTile = within(horizontalTile);
321
- const mockiModel = mockIModelsResponse.find(
322
- (iModel) =>
323
- iModel.iModel.id === mockMappings[index].mapping._links.imodel.href
324
- );
325
- expect(
326
- reportMappingTile.getByText(
327
- mockMappings[index].mapping.mappingName
328
- )
329
- ).toBeInTheDocument();
330
- expect(
331
- reportMappingTile.getByTitle(
332
- mockMappings[index].mapping.description ?? ""
333
- )
334
- ).toBeInTheDocument();
335
- expect(
336
- reportMappingTile.getByText(mockiModel?.iModel.displayName ?? "")
337
- ).toBeInTheDocument();
338
- }
326
+ await waitForElementToBeRemoved(() => screen.getByText(/loading/i));
327
+
328
+ const horizontalTiles = screen.getAllByTestId("horizontal-tile");
329
+ assertHorizontalTiles(horizontalTiles, mockMappings);
339
330
  });
340
331
 
341
332
  it("search for a report mapping", async () => {
342
333
  const mockReportMappings = mockReportMappingsFactory();
343
- const [mockMappings, iModelHandlers] =
344
- mockMappingsFactory(mockReportMappings);
345
-
346
- server.use(
347
- rest.get(
348
- `${REPORTS_CONFIG_BASE_URL}/insights/reporting/reports/${mockReportId}/datasources/imodelMappings`,
349
- async (_req, res, ctx) => {
350
- return res(
351
- ctx.delay(),
352
- ctx.status(200),
353
- ctx.json(mockReportMappings)
354
- );
355
- }
356
- ),
357
- rest.get(
358
- `${Constants.api.baseUrl}/${mockIModelId1}`,
359
- async (_req, res, ctx) => {
360
- return res(
361
- ctx.delay(),
362
- ctx.status(200),
363
- ctx.json(mockIModelsResponse[0])
364
- );
365
- }
366
- ),
367
- rest.get(
368
- `${Constants.api.baseUrl}/${mockIModelId2}`,
369
- async (_req, res, ctx) => {
370
- return res(
371
- ctx.delay(),
372
- ctx.status(200),
373
- ctx.json(mockIModelsResponse[1])
374
- );
375
- }
376
- ),
377
- ...iModelHandlers
378
- );
334
+ const mockMappings = mockMappingsFactory(mockReportMappings);
335
+
336
+ mockIModelsClient.setup(async (x) => x.getSingle(moq.It.isObjectWith<GetSingleIModelParams>({ iModelId: mockIModelId1 })))
337
+ .returns(async () => mockIModelsResponse[0].iModel);
338
+
339
+ mockIModelsClient.setup(async (x) => x.getSingle(moq.It.isObjectWith<GetSingleIModelParams>({ iModelId: mockIModelId2 })))
340
+ .returns(async () => mockIModelsResponse[1].iModel);
341
+ mockGetMapping.mockReturnValueOnce(mockMappings[0].mapping).mockReturnValueOnce(mockMappings[1].mapping);
342
+ mockGetReportMappings.mockReturnValueOnce(mockReportMappings.mappings);
379
343
 
380
344
  const { user } = render(
381
- <ReportMappings report={mockReport} goBack={jest.fn()} />
345
+ <ReportMappings report={mockReport} bulkExtractor={mockBulkExtractor.object} goBack={jest.fn()} />
382
346
  );
383
347
 
384
348
  await waitForElementToBeRemoved(() => screen.getByText(/loading/i));
385
349
 
386
- const searchButton = within(screen.getByTestId(/search-bar/i)).getByRole(
350
+ const searchButton = within(screen.getByTestId(/rcw-search-bar/i)).getByRole(
387
351
  "button"
388
352
  );
389
353
  await user.click(searchButton);
@@ -419,289 +383,49 @@ describe("Report Mappings View", () => {
419
383
  ).toBeInTheDocument();
420
384
  });
421
385
 
422
- it("remove a report mapping", async () => {
423
- const mockReportMappings = mockReportMappingsFactory();
424
- const [_, iModelHandlers] = mockMappingsFactory(mockReportMappings);
425
-
426
- const mockReportMappingsOriginalSize = mockReportMappings.mappings.length;
427
-
428
- server.use(
429
- rest.get(
430
- `${REPORTS_CONFIG_BASE_URL}/insights/reporting/reports/${mockReportId}/datasources/imodelMappings`,
431
- async (_req, res, ctx) => {
432
- return res(
433
- ctx.delay(),
434
- ctx.status(200),
435
- ctx.json(mockReportMappings)
436
- );
437
- }
438
- ),
439
- rest.get(
440
- `${Constants.api.baseUrl}/${mockIModelId1}`,
441
- async (_req, res, ctx) => {
442
- return res(
443
- ctx.delay(),
444
- ctx.status(200),
445
- ctx.json(mockIModelsResponse[0])
446
- );
447
- }
448
- ),
449
- rest.get(
450
- `${Constants.api.baseUrl}/${mockIModelId2}`,
451
- async (_req, res, ctx) => {
452
- return res(
453
- ctx.delay(),
454
- ctx.status(200),
455
- ctx.json(mockIModelsResponse[1])
456
- );
457
- }
458
- ),
459
- ...iModelHandlers,
460
- rest.delete(
461
- `${REPORTS_CONFIG_BASE_URL}/insights/reporting/reports/${mockReportId}/datasources/imodelMappings/${mockReportMappings.mappings[0].mappingId
462
- }`,
463
- async (_req, res, ctx) => {
464
- mockReportMappings.mappings = mockReportMappings.mappings.filter(
465
- (mapping) =>
466
- mapping.mappingId !== mockReportMappings.mappings[0].mappingId
467
- );
468
- return res(ctx.delay(100), ctx.status(204));
469
- }
470
- )
471
- );
472
-
473
- const { user } = render(
474
- <ReportMappings report={mockReport} goBack={jest.fn()} />
475
- );
476
-
477
- await waitForElementToBeRemoved(() => screen.getByText(/loading/i));
478
-
479
- const firstMenuDropdown = within(
480
- screen.getAllByTestId(/tile-action-button/i)[0]
481
- ).getByRole("button");
482
- await user.click(firstMenuDropdown);
483
- const removeButton = screen.getByRole("menuitem", { name: /remove/i });
484
- await user.click(removeButton);
485
- // Delete modal dialog should appear
486
- expect(screen.getByRole("dialog")).toBeInTheDocument();
487
-
488
- const deleteButton = screen.getByRole("button", {
489
- name: /delete/i,
490
- });
491
-
492
- await user.click(deleteButton);
493
-
494
- await waitForElementToBeRemoved(() =>
495
- screen.getByTestId(/rcw-loading-delete/i)
496
- );
497
- await waitForElementToBeRemoved(() => screen.getByRole("dialog"));
498
-
499
- // Should be one less mapping
500
- expect(screen.getAllByTestId("horizontal-tile")).toHaveLength(
501
- mockReportMappingsOriginalSize - 1
502
- );
503
- });
504
-
505
386
  it("add mapping", async () => {
506
387
  const mockReportMappings = mockReportMappingsFactory();
507
- const [mockMappings, iModelHandlers] =
508
- mockMappingsFactory(mockReportMappings);
388
+ const mockMappings = mockMappingsFactory(mockReportMappings);
509
389
 
510
- // Adding an extra unmapped mapping.
511
- const extraMappingId = faker.datatype.uuid();
512
- const extraMappingName = "mOcKNaMeExTrA";
513
- const extraMappingDescription = "mOcKDeScRiPtIoNeXtRa";
390
+ mockIModelsClient.setup(async (x) => x.getSingle(moq.It.isObjectWith<GetSingleIModelParams>({ iModelId: mockIModelId1 })))
391
+ .returns(async () => mockIModelsResponse[0].iModel);
514
392
 
515
- mockMappings.push({
516
- mapping: {
517
- id: extraMappingId,
518
- mappingName: extraMappingName,
519
- description: extraMappingDescription,
520
- extractionEnabled: false,
521
- createdOn: "",
522
- createdBy: "",
523
- modifiedOn: "",
524
- modifiedBy: "",
525
- _links: {
526
- imodel: {
527
- href: "",
528
- },
529
- },
530
- },
531
- });
393
+ mockIModelsClient.setup(async (x) => x.getSingle(moq.It.isObjectWith<GetSingleIModelParams>({ iModelId: mockIModelId2 })))
394
+ .returns(async () => mockIModelsResponse[1].iModel);
532
395
 
533
- const mockMappingsResponse: MappingCollection = {
534
- // Type guarding
535
- mappings: mockMappings
536
- .map((mapping) => mapping.mapping)
537
- .filter((mapping): mapping is Mapping => !!mapping),
538
- _links: {
539
- next: undefined,
540
- self: {
541
- href: "",
542
- },
543
- },
544
- };
545
-
546
- server.use(
547
- rest.get(
548
- `${REPORTS_CONFIG_BASE_URL}/insights/reporting/reports/${mockReportId}/datasources/imodelMappings`,
549
- async (_req, res, ctx) => {
550
- return res(
551
- ctx.delay(),
552
- ctx.status(200),
553
- ctx.json(mockReportMappings)
554
- );
555
- }
556
- ),
557
- rest.get(`${Constants.api.baseUrl}`, async (_req, res, ctx) => {
558
- return res(ctx.delay(), ctx.status(200), ctx.json(mockProjectIModels));
559
- }),
560
- rest.get(
561
- `${Constants.api.baseUrl}/${mockIModelId1}`,
562
- async (_req, res, ctx) => {
563
- return res(
564
- ctx.delay(),
565
- ctx.status(200),
566
- ctx.json(mockIModelsResponse[0])
567
- );
568
- }
569
- ),
570
- rest.get(
571
- `${Constants.api.baseUrl}/${mockIModelId2}`,
572
- async (_req, res, ctx) => {
573
- return res(
574
- ctx.delay(),
575
- ctx.status(200),
576
- ctx.json(mockIModelsResponse[1])
577
- );
578
- }
579
- ),
580
- rest.get(
581
- `${REPORTS_CONFIG_BASE_URL}/insights/reporting/datasources/imodels/${mockProjectIModels.iModels[0].id}/mappings`,
582
- async (_req, res, ctx) => {
583
- return res(
584
- ctx.delay(),
585
- ctx.status(200),
586
- ctx.json(mockMappingsResponse)
587
- );
588
- }
589
- ),
590
- rest.post(
591
- `${REPORTS_CONFIG_BASE_URL}/insights/reporting/reports/${mockReportId}/datasources/imodelMappings`,
592
- async (_req, res, ctx) => {
593
- return res(
594
- ctx.delay(),
595
- ctx.status(200),
596
- ctx.json(mockReportMappings)
597
- );
598
- }
599
- ),
600
- ...iModelHandlers
601
- );
396
+ mockGetMapping.mockReturnValueOnce(mockMappings[0].mapping).mockReturnValueOnce(mockMappings[1].mapping);
397
+ mockGetReportMappings.mockReturnValueOnce(mockReportMappings.mappings);
602
398
 
603
399
  const { user } = render(
604
- <ReportMappings report={mockReport} goBack={jest.fn()} />
400
+ <ReportMappings report={mockReport} bulkExtractor={mockBulkExtractor.object} goBack={jest.fn()} />
605
401
  );
606
402
 
607
403
  await waitForElementToBeRemoved(() => screen.getByText(/loading/i));
608
404
 
405
+ mockGetMappings.mockReturnValueOnce(mockMappings.map((m: MappingSingle) => m.mapping));
406
+
609
407
  const addMappingButton = screen.getByRole("button", {
610
408
  name: /addmapping/i,
611
409
  });
612
410
 
613
411
  await user.click(addMappingButton);
614
412
 
615
- await waitForElementToBeRemoved(() =>
616
- screen.getByTestId(/rcw-action-loading-spinner/i)
617
- );
618
- // Add modal dialog should appear
619
- const modal = screen.getByRole("dialog");
620
- expect(screen.getByRole("dialog")).toBeInTheDocument();
621
-
622
- const withinModal = within(modal);
623
- expect(withinModal.getByText(/addmappings/i)).toBeInTheDocument();
413
+ const addMappingsModal = await screen.findByTestId("add-mappings-modal");
414
+ expect(addMappingsModal).toBeInTheDocument();
624
415
 
625
- const addButton = withinModal.getByRole("button", {
626
- name: /add/i,
627
- });
628
- // Add button should be disabled
629
- expect(addButton).toBeDisabled();
630
-
631
- // Already mapped mappings are disabled
632
- for (let i = 0; i < mockMappings.length - 1; i++) {
633
- const row = screen.getByRole("row", {
634
- name: new RegExp(
635
- `${mockMappings[i].mapping.mappingName} ${mockMappings[i].mapping.description}`,
636
- "i"
637
- ),
638
- });
639
-
640
- const checkbox = within(row).getByRole("checkbox");
641
- expect(checkbox).toBeDisabled();
642
- }
643
-
644
- // Click on checkbox on new mapping
645
- const unmappedRow = screen.getByRole("row", {
646
- name: new RegExp(
647
- `${mockMappings[mockMappings.length - 1].mapping.mappingName
648
- } ${mockMappings[mockMappings.length - 1].mapping.description}`,
649
- "i"
650
- ),
416
+ await act(async () => {
417
+ await returnFn();
651
418
  });
652
419
 
653
- const enabledCheckbox = within(unmappedRow).getByRole("checkbox");
654
-
655
- await user.click(enabledCheckbox);
420
+ const horizontalTiles = screen.getAllByTestId("horizontal-tile");
421
+ assertHorizontalTiles(horizontalTiles, mockMappings);
656
422
 
657
- await user.click(addButton);
658
- // Modal should go away
659
- await waitForElementToBeRemoved(() =>
660
- screen.getByTestId(/rcw-action-loading-spinner/i)
661
- );
662
- await waitForElementToBeRemoved(() => screen.getByRole("dialog"));
423
+ expect(mockGetReportMappings).toBeCalledTimes(2);
663
424
  });
664
425
 
665
426
  it("odata feed url", async () => {
666
- const mockReportMappings = mockReportMappingsFactory();
667
- const [_, iModelHandlers] = mockMappingsFactory(mockReportMappings);
668
-
669
- server.use(
670
- rest.get(
671
- `${REPORTS_CONFIG_BASE_URL}/insights/reporting/reports/${mockReportId}/datasources/imodelMappings`,
672
- async (_req, res, ctx) => {
673
- return res(
674
- ctx.delay(),
675
- ctx.status(200),
676
- ctx.json(mockReportMappings)
677
- );
678
- }
679
- ),
680
- rest.get(
681
- `${Constants.api.baseUrl}/${mockIModelId1}`,
682
- async (_req, res, ctx) => {
683
- return res(
684
- ctx.delay(),
685
- ctx.status(200),
686
- ctx.json(mockIModelsResponse[0])
687
- );
688
- }
689
- ),
690
- rest.get(
691
- `${Constants.api.baseUrl}/${mockIModelId2}`,
692
- async (_req, res, ctx) => {
693
- return res(
694
- ctx.delay(),
695
- ctx.status(200),
696
- ctx.json(mockIModelsResponse[1])
697
- );
698
- }
699
- ),
700
- ...iModelHandlers
701
- );
702
-
703
427
  const { user } = render(
704
- <ReportMappings report={mockReport} goBack={jest.fn()} />
428
+ <ReportMappings report={mockReport} bulkExtractor={mockBulkExtractor.object} goBack={jest.fn()} />
705
429
  );
706
430
 
707
431
  await waitForElementToBeRemoved(() => screen.getByText(/loading/i));
@@ -724,174 +448,55 @@ describe("Report Mappings View", () => {
724
448
  expect(screen.getByText(/copiedtoclipboard/i)).toBeInTheDocument();
725
449
  });
726
450
 
727
- it("full extraction", async () => {
451
+ it("update all datasets", async () => {
728
452
  const mockReportMappings = mockReportMappingsFactory();
729
- const [_, iModelHandlers] = mockMappingsFactory(mockReportMappings);
730
-
731
- const delay = REFRESH_DELAY + 1000;
453
+ const mockMappings = mockMappingsFactory(mockReportMappings);
732
454
 
733
- // Faking timers currently makes all promise based queries from RTL become unpredictable.
734
- // https://github.com/testing-library/dom-testing-library/issues/988
735
- // Should come back to this later.
736
- // Consequently, this test will be a bit slower.
737
- // jest.useFakeTimers()
455
+ mockIModelsClient.setup(async (x) => x.getSingle(moq.It.isObjectWith<GetSingleIModelParams>({ iModelId: mockIModelId1 })))
456
+ .returns(async () => mockIModelsResponse[0].iModel);
738
457
 
739
- Element.prototype.scrollIntoView = jest.fn();
458
+ mockIModelsClient.setup(async (x) => x.getSingle(moq.It.isObjectWith<GetSingleIModelParams>({ iModelId: mockIModelId2 })))
459
+ .returns(async () => mockIModelsResponse[1].iModel);
740
460
 
741
- const mockIModel = mockIModelsResponse[0].iModel;
742
- const mockRunId = faker.datatype.uuid();
461
+ mockGetMapping.mockReturnValueOnce(mockMappings[0].mapping).mockReturnValueOnce(mockMappings[1].mapping);
462
+ mockGetReportMappings.mockReturnValueOnce(mockReportMappings.mappings);
743
463
 
744
- const mockExtractionResponse = {
745
- run: {
746
- id: mockRunId,
747
- _links: {
748
- status: {
749
- href: "",
750
- },
751
- },
752
- },
753
- };
754
-
755
- let mockStatusResponse: ExtractionStatusSingle = {
756
- status: {
757
- state: ExtractorState.Queued,
758
- reason: "",
759
- containsIssues: false,
760
- _links: {
761
- logs: {
762
- href: "",
763
- },
764
- },
765
- },
766
- };
767
-
768
- server.use(
769
- rest.get(
770
- `${REPORTS_CONFIG_BASE_URL}/insights/reporting/reports/${mockReportId}/datasources/imodelMappings`,
771
- async (_req, res, ctx) => {
772
- return res(
773
- ctx.delay(),
774
- ctx.status(200),
775
- ctx.json(mockReportMappings)
776
- );
777
- }
778
- ),
779
- rest.get(
780
- `${Constants.api.baseUrl}/${mockIModelId1}`,
781
- async (_req, res, ctx) => {
782
- return res(
783
- ctx.delay(),
784
- ctx.status(200),
785
- ctx.json(mockIModelsResponse[0])
786
- );
787
- }
788
- ),
789
- rest.get(
790
- `${Constants.api.baseUrl}/${mockIModelId2}`,
791
- async (_req, res, ctx) => {
792
- return res(
793
- ctx.delay(),
794
- ctx.status(200),
795
- ctx.json(mockIModelsResponse[1])
796
- );
797
- }
798
- ),
799
- ...iModelHandlers,
800
- rest.post(
801
- `${REPORTS_CONFIG_BASE_URL}/insights/reporting/datasources/imodels/${mockIModel.id}/extraction/run`,
802
- async (_req, res, ctx) => {
803
- return res(
804
- ctx.delay(800),
805
- ctx.status(200),
806
- ctx.json(mockExtractionResponse)
807
- );
808
- }
809
- ),
810
- rest.get(
811
- `${REPORTS_CONFIG_BASE_URL}/insights/reporting/datasources/extraction/status/${mockRunId}`,
812
- async (_req, res, ctx) => {
813
- return res(
814
- ctx.delay(),
815
- ctx.status(200),
816
- ctx.json(mockStatusResponse)
817
- );
818
- }
819
- )
820
- );
464
+ const iModels = mockIModelsResponse.map((iModel) => iModel.iModel.id);
465
+ mockBulkExtractor.setup(async (x) => x.runIModelExtractions(iModels)).returns(async () => Promise.resolve());
821
466
 
822
- render(<ReportMappings report={mockReport} goBack={jest.fn()} />);
823
-
824
- // https://github.com/testing-library/user-event/issues/833
825
- const user = userEvent.setup({ delay: null });
467
+ const { user } = render(<ReportMappings report={mockReport} bulkExtractor={mockBulkExtractor.object} goBack={jest.fn()} />);
826
468
 
827
469
  await waitForElementToBeRemoved(() => screen.getByText(/loading/i));
828
470
 
829
- const comboBox = screen.getByRole("combobox", {
830
- name: /updatedataset/i,
831
- });
832
- await user.type(comboBox, mockIModel.displayName);
833
-
834
- const option = screen.getByRole("menuitem", {
835
- name: mockIModel.displayName,
836
- });
837
-
838
- await user.click(option);
471
+ const extractAllButton = screen.getByText(/UpdateAllDatasets/i);
472
+ expect(extractAllButton).toBeInTheDocument();
839
473
 
840
- // Combobox should have correct status
841
- const extractionComponent = screen.getByTestId("extraction-combo-box");
842
- expect(
843
- within(extractionComponent).getByDisplayValue(mockIModel.displayName)
844
- ).toBeInTheDocument();
845
- // Should be two in the document. One in the status and the other in the list.
846
- // TODO Assert that it is in the correct HorizontalTile
847
- const startingStates = await screen.findAllByTitle(/starting/i);
848
- expect(startingStates).toHaveLength(2);
849
-
850
- const loadingStates = await screen.findAllByTitle(/loading/i);
851
- expect(loadingStates).toHaveLength(2);
852
-
853
- // act(() => {
854
- // jest.advanceTimersByTime(2000)
855
- // });
856
- const queuedStates = await screen.findAllByTitle(/queued/i, undefined, {
857
- timeout: delay,
858
- });
859
- expect(queuedStates).toHaveLength(2);
860
-
861
- mockStatusResponse = {
862
- status: {
863
- state: ExtractorState.Running,
864
- reason: "",
865
- containsIssues: false,
866
- _links: {
867
- logs: {
868
- href: "",
869
- },
870
- },
871
- },
872
- };
873
-
874
- const runningStates = await screen.findAllByTitle(/running/i, undefined, {
875
- timeout: delay,
876
- });
877
- expect(runningStates).toHaveLength(2);
474
+ await user.click(extractAllButton);
475
+ mockBulkExtractor.verify(async (x) => x.runIModelExtractions(iModels), moq.Times.once());
476
+ });
878
477
 
879
- mockStatusResponse = {
880
- status: {
881
- state: ExtractorState.Succeeded,
882
- reason: "",
883
- containsIssues: false,
884
- _links: {
885
- logs: {
886
- href: "",
887
- },
888
- },
889
- },
890
- };
478
+ const assertHorizontalTiles = (horizontalTiles: HTMLElement[], mockMappings: MappingSingle[]) => {
479
+ expect(horizontalTiles).toHaveLength(mockMappings.length);
891
480
 
892
- const succeededStates = await screen.findAllByTitle(/success/i, undefined, {
893
- timeout: delay,
894
- });
895
- expect(succeededStates).toHaveLength(2);
896
- });
481
+ for (const [index, horizontalTile] of horizontalTiles.entries()) {
482
+ const reportMappingTile = within(horizontalTile);
483
+ const mockiModel = mockIModelsResponse.find(
484
+ (iModel) =>
485
+ iModel.iModel.id === mockMappings[index].mapping._links.imodel.href
486
+ );
487
+ expect(
488
+ reportMappingTile.getByText(
489
+ mockMappings[index].mapping.mappingName
490
+ )
491
+ ).toBeInTheDocument();
492
+ expect(
493
+ reportMappingTile.getByTitle(
494
+ mockMappings[index].mapping.description ?? ""
495
+ )
496
+ ).toBeInTheDocument();
497
+ expect(
498
+ reportMappingTile.getByText(mockiModel?.iModel.displayName ?? "")
499
+ ).toBeInTheDocument();
500
+ }
501
+ };
897
502
  });