@webiny/app-website-builder-workflows 0.0.0-unstable.0156a4c312

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 (402) hide show
  1. package/Components/ContentReviews/WbContentReviews.d.ts +2 -0
  2. package/Components/ContentReviews/WbContentReviews.js +41 -0
  3. package/Components/ContentReviews/WbContentReviews.js.map +1 -0
  4. package/Components/ContentReviews/WbContentReviews.smoke.test.d.ts +1 -0
  5. package/Components/ContentReviews/WbContentReviews.smoke.test.js +59 -0
  6. package/Components/ContentReviews/WbContentReviews.smoke.test.js.map +1 -0
  7. package/Components/ContentReviews/WbContentReviews.test.d.ts +1 -0
  8. package/Components/ContentReviews/WbContentReviews.test.js +80 -0
  9. package/Components/ContentReviews/WbContentReviews.test.js.map +1 -0
  10. package/Components/ContentReviews/WbContentReviewsSidebarItem.d.ts +2 -0
  11. package/Components/ContentReviews/WbContentReviewsSidebarItem.js +18 -0
  12. package/Components/ContentReviews/WbContentReviewsSidebarItem.js.map +1 -0
  13. package/Components/ContentReviews/WbContentReviewsSidebarItem.test.d.ts +1 -0
  14. package/Components/ContentReviews/WbContentReviewsSidebarItem.test.js +67 -0
  15. package/Components/ContentReviews/WbContentReviewsSidebarItem.test.js.map +1 -0
  16. package/Components/PageEditor/DisabledPublishButton.d.ts +6 -0
  17. package/Components/PageEditor/DisabledPublishButton.js +17 -0
  18. package/Components/PageEditor/DisabledPublishButton.js.map +1 -0
  19. package/Components/PageEditor/DisabledPublishButton.test.d.ts +1 -0
  20. package/Components/PageEditor/DisabledPublishButton.test.js +67 -0
  21. package/Components/PageEditor/DisabledPublishButton.test.js.map +1 -0
  22. package/Components/PageEditor/PageBasePublishDecorator.d.ts +2 -0
  23. package/Components/PageEditor/PageBasePublishDecorator.js +23 -0
  24. package/Components/PageEditor/PageBasePublishDecorator.js.map +1 -0
  25. package/Components/PageEditor/PageEditorAutoSave.d.ts +2 -0
  26. package/Components/PageEditor/PageEditorAutoSave.js +23 -0
  27. package/Components/PageEditor/PageEditorAutoSave.js.map +1 -0
  28. package/Components/PageEditor/PageEditorAutoSave.test.d.ts +1 -0
  29. package/Components/PageEditor/PageEditorAutoSave.test.js +111 -0
  30. package/Components/PageEditor/PageEditorAutoSave.test.js.map +1 -0
  31. package/Components/PageEditor/PageEditorConfig.d.ts +2 -0
  32. package/Components/PageEditor/PageEditorConfig.js +13 -0
  33. package/Components/PageEditor/PageEditorConfig.js.map +1 -0
  34. package/Components/PageEditor/PageEditorLayout.d.ts +2 -0
  35. package/Components/PageEditor/PageEditorLayout.js +10 -0
  36. package/Components/PageEditor/PageEditorLayout.js.map +1 -0
  37. package/Components/PageEditor/PageEditorLayout.test.d.ts +1 -0
  38. package/Components/PageEditor/PageEditorLayout.test.js +121 -0
  39. package/Components/PageEditor/PageEditorLayout.test.js.map +1 -0
  40. package/Components/PageEditor/PageEditorTopBar.d.ts +2 -0
  41. package/Components/PageEditor/PageEditorTopBar.js +10 -0
  42. package/Components/PageEditor/PageEditorTopBar.js.map +1 -0
  43. package/Components/PageEditor/PageEditorTopBar.test.d.ts +1 -0
  44. package/Components/PageEditor/PageEditorTopBar.test.js +175 -0
  45. package/Components/PageEditor/PageEditorTopBar.test.js.map +1 -0
  46. package/Components/PageEditor/PageNewRevisionDecorator.d.ts +2 -0
  47. package/Components/PageEditor/PageNewRevisionDecorator.js +24 -0
  48. package/Components/PageEditor/PageNewRevisionDecorator.js.map +1 -0
  49. package/Components/PageEditor/PageNewRevisionDecorator.test.d.ts +1 -0
  50. package/Components/PageEditor/PageNewRevisionDecorator.test.js +107 -0
  51. package/Components/PageEditor/PageNewRevisionDecorator.test.js.map +1 -0
  52. package/Components/PageEditor/PageReadOnlySync.d.ts +3 -0
  53. package/Components/PageEditor/PageReadOnlySync.js +23 -0
  54. package/Components/PageEditor/PageReadOnlySync.js.map +1 -0
  55. package/Components/PageEditor/PageReviewBar.d.ts +4 -0
  56. package/Components/PageEditor/PageReviewBar.js +93 -0
  57. package/Components/PageEditor/PageReviewBar.js.map +1 -0
  58. package/Components/PageEditor/PageReviewBar.test.d.ts +1 -0
  59. package/Components/PageEditor/PageReviewBar.test.js +135 -0
  60. package/Components/PageEditor/PageReviewBar.test.js.map +1 -0
  61. package/Components/PageEditor/PageReviewPublishAction.d.ts +2 -0
  62. package/Components/PageEditor/PageReviewPublishAction.js +15 -0
  63. package/Components/PageEditor/PageReviewPublishAction.js.map +1 -0
  64. package/Components/PageEditor/PageReviewPublishButton.d.ts +4 -0
  65. package/Components/PageEditor/PageReviewPublishButton.js +23 -0
  66. package/Components/PageEditor/PageReviewPublishButton.js.map +1 -0
  67. package/Components/PageEditor/PageScheduleDecorator.d.ts +2 -0
  68. package/Components/PageEditor/PageScheduleDecorator.js +23 -0
  69. package/Components/PageEditor/PageScheduleDecorator.js.map +1 -0
  70. package/Components/PageEditor/PageScheduleDecorator.test.d.ts +1 -0
  71. package/Components/PageEditor/PageScheduleDecorator.test.js +75 -0
  72. package/Components/PageEditor/PageScheduleDecorator.test.js.map +1 -0
  73. package/Components/PageEditor/getPageReadOnlyReason.d.ts +4 -0
  74. package/Components/PageEditor/getPageReadOnlyReason.js +20 -0
  75. package/Components/PageEditor/getPageReadOnlyReason.js.map +1 -0
  76. package/Components/PageEditor/getPageReadOnlyReason.test.d.ts +1 -0
  77. package/Components/PageEditor/getPageReadOnlyReason.test.js +122 -0
  78. package/Components/PageEditor/getPageReadOnlyReason.test.js.map +1 -0
  79. package/Components/PageEditor/getPageReviewContext.d.ts +9 -0
  80. package/Components/PageEditor/getPageReviewContext.js +13 -0
  81. package/Components/PageEditor/getPageReviewContext.js.map +1 -0
  82. package/Components/PageEditor/getPageReviewContext.test.d.ts +1 -0
  83. package/Components/PageEditor/getPageReviewContext.test.js +42 -0
  84. package/Components/PageEditor/getPageReviewContext.test.js.map +1 -0
  85. package/Components/PageEditor/pageEditorDocument.d.ts +17 -0
  86. package/Components/PageEditor/pageEditorDocument.js +0 -0
  87. package/Components/PageEditor/pageReviewMatrix.test.d.ts +1 -0
  88. package/Components/PageEditor/pageReviewMatrix.test.js +223 -0
  89. package/Components/PageEditor/pageReviewMatrix.test.js.map +1 -0
  90. package/Components/PageEditor/publishMatrix.test.d.ts +1 -0
  91. package/Components/PageEditor/publishMatrix.test.js +313 -0
  92. package/Components/PageEditor/publishMatrix.test.js.map +1 -0
  93. package/Components/PagesList/PageListReviewGatedActions.d.ts +2 -0
  94. package/Components/PagesList/PageListReviewGatedActions.js +27 -0
  95. package/Components/PagesList/PageListReviewGatedActions.js.map +1 -0
  96. package/Components/PagesList/PageListReviewGatedActions.test.d.ts +1 -0
  97. package/Components/PagesList/PageListReviewGatedActions.test.js +94 -0
  98. package/Components/PagesList/PageListReviewGatedActions.test.js.map +1 -0
  99. package/Components/PagesList/PagesList.d.ts +2 -0
  100. package/Components/PagesList/PagesList.js +8 -0
  101. package/Components/PagesList/PagesList.js.map +1 -0
  102. package/Components/PagesList/PagesList.test.d.ts +1 -0
  103. package/Components/PagesList/PagesList.test.js +47 -0
  104. package/Components/PagesList/PagesList.test.js.map +1 -0
  105. package/Components/PagesList/index.d.ts +1 -0
  106. package/Components/PagesList/index.js +1 -0
  107. package/Components/index.d.ts +2 -0
  108. package/Components/index.js +2 -0
  109. package/LICENSE +21 -0
  110. package/README.md +11 -0
  111. package/Routes/WebsiteBuilderWorkflowsMenu.d.ts +2 -0
  112. package/Routes/WebsiteBuilderWorkflowsMenu.js +23 -0
  113. package/Routes/WebsiteBuilderWorkflowsMenu.js.map +1 -0
  114. package/Routes/WebsiteBuilderWorkflowsMenu.test.d.ts +1 -0
  115. package/Routes/WebsiteBuilderWorkflowsMenu.test.js +141 -0
  116. package/Routes/WebsiteBuilderWorkflowsMenu.test.js.map +1 -0
  117. package/Routes/index.d.ts +1 -0
  118. package/Routes/index.js +1 -0
  119. package/constants.d.ts +1 -0
  120. package/constants.js +4 -0
  121. package/constants.js.map +1 -0
  122. package/editorGlue.wiring.test.d.ts +1 -0
  123. package/editorGlue.wiring.test.js +128 -0
  124. package/editorGlue.wiring.test.js.map +1 -0
  125. package/features/cache/WbReviewCacheSyncHandler.d.ts +8 -0
  126. package/features/cache/WbReviewCacheSyncHandler.js +14 -0
  127. package/features/cache/WbReviewCacheSyncHandler.js.map +1 -0
  128. package/features/cache/WbReviewPageCacheWriter.d.ts +17 -0
  129. package/features/cache/WbReviewPageCacheWriter.js +39 -0
  130. package/features/cache/WbReviewPageCacheWriter.js.map +1 -0
  131. package/features/cache/WbReviewPageCacheWriter.test.d.ts +1 -0
  132. package/features/cache/WbReviewPageCacheWriter.test.js +115 -0
  133. package/features/cache/WbReviewPageCacheWriter.test.js.map +1 -0
  134. package/features/cache/abstractions.d.ts +5 -0
  135. package/features/cache/abstractions.js +5 -0
  136. package/features/cache/abstractions.js.map +1 -0
  137. package/features/cache/feature.d.ts +1 -0
  138. package/features/cache/feature.js +13 -0
  139. package/features/cache/feature.js.map +1 -0
  140. package/features/editorGateway/WbWorkflowEditorGateway/WbWorkflowEditorGateway.d.ts +25 -0
  141. package/features/editorGateway/WbWorkflowEditorGateway/WbWorkflowEditorGateway.js +112 -0
  142. package/features/editorGateway/WbWorkflowEditorGateway/WbWorkflowEditorGateway.js.map +1 -0
  143. package/features/editorGateway/WbWorkflowEditorGateway/WbWorkflowEditorGateway.test.d.ts +1 -0
  144. package/features/editorGateway/WbWorkflowEditorGateway/WbWorkflowEditorGateway.test.js +632 -0
  145. package/features/editorGateway/WbWorkflowEditorGateway/WbWorkflowEditorGateway.test.js.map +1 -0
  146. package/features/editorGateway/feature.d.ts +1 -0
  147. package/features/editorGateway/feature.js +11 -0
  148. package/features/editorGateway/feature.js.map +1 -0
  149. package/features/editorGateway/feature.test.d.ts +1 -0
  150. package/features/editorGateway/feature.test.js +244 -0
  151. package/features/editorGateway/feature.test.js.map +1 -0
  152. package/features/editorGateway/graphql/deleteWebsiteBuilderPageWorkflow.d.ts +1 -0
  153. package/features/editorGateway/graphql/deleteWebsiteBuilderPageWorkflow.js +19 -0
  154. package/features/editorGateway/graphql/deleteWebsiteBuilderPageWorkflow.js.map +1 -0
  155. package/features/editorGateway/graphql/getWebsiteBuilderPageWorkflow.d.ts +1 -0
  156. package/features/editorGateway/graphql/getWebsiteBuilderPageWorkflow.js +19 -0
  157. package/features/editorGateway/graphql/getWebsiteBuilderPageWorkflow.js.map +1 -0
  158. package/features/editorGateway/graphql/inspectWebsiteBuilderPageRouting.d.ts +1 -0
  159. package/features/editorGateway/graphql/inspectWebsiteBuilderPageRouting.js +19 -0
  160. package/features/editorGateway/graphql/inspectWebsiteBuilderPageRouting.js.map +1 -0
  161. package/features/editorGateway/graphql/listWebsiteBuilderPageWorkflowNames.d.ts +1 -0
  162. package/features/editorGateway/graphql/listWebsiteBuilderPageWorkflowNames.js +23 -0
  163. package/features/editorGateway/graphql/listWebsiteBuilderPageWorkflowNames.js.map +1 -0
  164. package/features/editorGateway/graphql/storeWebsiteBuilderPageWorkflow.d.ts +1 -0
  165. package/features/editorGateway/graphql/storeWebsiteBuilderPageWorkflow.js +19 -0
  166. package/features/editorGateway/graphql/storeWebsiteBuilderPageWorkflow.js.map +1 -0
  167. package/features/editorGateway/graphql/websiteBuilderPageFolderExists.d.ts +1 -0
  168. package/features/editorGateway/graphql/websiteBuilderPageFolderExists.js +16 -0
  169. package/features/editorGateway/graphql/websiteBuilderPageFolderExists.js.map +1 -0
  170. package/features/editorMounting/WbWorkflowEditorAppAdapter.d.ts +21 -0
  171. package/features/editorMounting/WbWorkflowEditorAppAdapter.js +45 -0
  172. package/features/editorMounting/WbWorkflowEditorAppAdapter.js.map +1 -0
  173. package/features/editorMounting/WbWorkflowEditorAppAdapter.test.d.ts +1 -0
  174. package/features/editorMounting/WbWorkflowEditorAppAdapter.test.js +115 -0
  175. package/features/editorMounting/WbWorkflowEditorAppAdapter.test.js.map +1 -0
  176. package/features/editorMounting/abstractions.d.ts +5 -0
  177. package/features/editorMounting/abstractions.js +5 -0
  178. package/features/editorMounting/abstractions.js.map +1 -0
  179. package/features/editorMounting/feature.d.ts +3 -0
  180. package/features/editorMounting/feature.js +19 -0
  181. package/features/editorMounting/feature.js.map +1 -0
  182. package/features/editorMounting/feature.test.d.ts +1 -0
  183. package/features/editorMounting/feature.test.js +93 -0
  184. package/features/editorMounting/feature.test.js.map +1 -0
  185. package/features/editorReview/WbPageContentReloader.d.ts +12 -0
  186. package/features/editorReview/WbPageContentReloader.js +40 -0
  187. package/features/editorReview/WbPageContentReloader.js.map +1 -0
  188. package/features/editorReview/WbPageContentReloader.test.d.ts +1 -0
  189. package/features/editorReview/WbPageContentReloader.test.js +222 -0
  190. package/features/editorReview/WbPageContentReloader.test.js.map +1 -0
  191. package/features/editorReview/WbPageReview.d.ts +8 -0
  192. package/features/editorReview/WbPageReview.js +14 -0
  193. package/features/editorReview/WbPageReview.js.map +1 -0
  194. package/features/editorReview/WbPageUnsavedChanges.d.ts +8 -0
  195. package/features/editorReview/WbPageUnsavedChanges.js +12 -0
  196. package/features/editorReview/WbPageUnsavedChanges.js.map +1 -0
  197. package/features/editorReview/WbPageUnsavedChanges.test.d.ts +1 -0
  198. package/features/editorReview/WbPageUnsavedChanges.test.js +33 -0
  199. package/features/editorReview/WbPageUnsavedChanges.test.js.map +1 -0
  200. package/features/editorReview/abstractions.d.ts +5 -0
  201. package/features/editorReview/abstractions.js +5 -0
  202. package/features/editorReview/abstractions.js.map +1 -0
  203. package/features/editorReview/feature.d.ts +3 -0
  204. package/features/editorReview/feature.js +17 -0
  205. package/features/editorReview/feature.js.map +1 -0
  206. package/features/gateway/WbReviewChangeMessageHandler.d.ts +8 -0
  207. package/features/gateway/WbReviewChangeMessageHandler.js +16 -0
  208. package/features/gateway/WbReviewChangeMessageHandler.js.map +1 -0
  209. package/features/gateway/WbReviewContentAdapter/WbReviewContentAdapter.d.ts +13 -0
  210. package/features/gateway/WbReviewContentAdapter/WbReviewContentAdapter.js +35 -0
  211. package/features/gateway/WbReviewContentAdapter/WbReviewContentAdapter.js.map +1 -0
  212. package/features/gateway/WbReviewContentAdapter/WbReviewContentAdapter.test.d.ts +1 -0
  213. package/features/gateway/WbReviewContentAdapter/WbReviewContentAdapter.test.js +47 -0
  214. package/features/gateway/WbReviewContentAdapter/WbReviewContentAdapter.test.js.map +1 -0
  215. package/features/gateway/WbReviewContentAdapter/abstractions.d.ts +5 -0
  216. package/features/gateway/WbReviewContentAdapter/abstractions.js +5 -0
  217. package/features/gateway/WbReviewContentAdapter/abstractions.js.map +1 -0
  218. package/features/gateway/WbReviewGateway/WbReviewGateway.d.ts +51 -0
  219. package/features/gateway/WbReviewGateway/WbReviewGateway.js +216 -0
  220. package/features/gateway/WbReviewGateway/WbReviewGateway.js.map +1 -0
  221. package/features/gateway/WbReviewGateway/WbReviewGateway.test.d.ts +1 -0
  222. package/features/gateway/WbReviewGateway/WbReviewGateway.test.js +647 -0
  223. package/features/gateway/WbReviewGateway/WbReviewGateway.test.js.map +1 -0
  224. package/features/gateway/WbReviewNotificationHandler.d.ts +8 -0
  225. package/features/gateway/WbReviewNotificationHandler.js +16 -0
  226. package/features/gateway/WbReviewNotificationHandler.js.map +1 -0
  227. package/features/gateway/WbReviewRowProvider/WbReviewRowProvider.d.ts +8 -0
  228. package/features/gateway/WbReviewRowProvider/WbReviewRowProvider.js +14 -0
  229. package/features/gateway/WbReviewRowProvider/WbReviewRowProvider.js.map +1 -0
  230. package/features/gateway/WbReviewRowProvider/abstractions.d.ts +5 -0
  231. package/features/gateway/WbReviewRowProvider/abstractions.js +5 -0
  232. package/features/gateway/WbReviewRowProvider/abstractions.js.map +1 -0
  233. package/features/gateway/assertWbPageNamespace.d.ts +1 -0
  234. package/features/gateway/assertWbPageNamespace.js +7 -0
  235. package/features/gateway/assertWbPageNamespace.js.map +1 -0
  236. package/features/gateway/contentReviewsBindings.test.d.ts +1 -0
  237. package/features/gateway/contentReviewsBindings.test.js +159 -0
  238. package/features/gateway/contentReviewsBindings.test.js.map +1 -0
  239. package/features/gateway/feature.d.ts +4 -0
  240. package/features/gateway/feature.js +27 -0
  241. package/features/gateway/feature.js.map +1 -0
  242. package/features/gateway/feature.test.d.ts +1 -0
  243. package/features/gateway/feature.test.js +85 -0
  244. package/features/gateway/feature.test.js.map +1 -0
  245. package/features/gateway/graphql/WbOperationResponse.d.ts +3 -0
  246. package/features/gateway/graphql/WbOperationResponse.js +0 -0
  247. package/features/gateway/graphql/approveWebsiteBuilderPageReviewStep.d.ts +1 -0
  248. package/features/gateway/graphql/approveWebsiteBuilderPageReviewStep.js +22 -0
  249. package/features/gateway/graphql/approveWebsiteBuilderPageReviewStep.js.map +1 -0
  250. package/features/gateway/graphql/cancelWebsiteBuilderPageReview.d.ts +1 -0
  251. package/features/gateway/graphql/cancelWebsiteBuilderPageReview.js +18 -0
  252. package/features/gateway/graphql/cancelWebsiteBuilderPageReview.js.map +1 -0
  253. package/features/gateway/graphql/cancelWebsiteBuilderPageReviewsForDelete.d.ts +1 -0
  254. package/features/gateway/graphql/cancelWebsiteBuilderPageReviewsForDelete.js +26 -0
  255. package/features/gateway/graphql/cancelWebsiteBuilderPageReviewsForDelete.js.map +1 -0
  256. package/features/gateway/graphql/getWebsiteBuilderPageReview.d.ts +1 -0
  257. package/features/gateway/graphql/getWebsiteBuilderPageReview.js +18 -0
  258. package/features/gateway/graphql/getWebsiteBuilderPageReview.js.map +1 -0
  259. package/features/gateway/graphql/getWebsiteBuilderPageReviewStepRun.d.ts +1 -0
  260. package/features/gateway/graphql/getWebsiteBuilderPageReviewStepRun.js +18 -0
  261. package/features/gateway/graphql/getWebsiteBuilderPageReviewStepRun.js.map +1 -0
  262. package/features/gateway/graphql/getWebsiteBuilderPageTargetReview.d.ts +1 -0
  263. package/features/gateway/graphql/getWebsiteBuilderPageTargetReview.js +18 -0
  264. package/features/gateway/graphql/getWebsiteBuilderPageTargetReview.js.map +1 -0
  265. package/features/gateway/graphql/listWebsiteBuilderPageReviewStepCandidates.d.ts +1 -0
  266. package/features/gateway/graphql/listWebsiteBuilderPageReviewStepCandidates.js +18 -0
  267. package/features/gateway/graphql/listWebsiteBuilderPageReviewStepCandidates.js.map +1 -0
  268. package/features/gateway/graphql/listWebsiteBuilderPageReviews.d.ts +1 -0
  269. package/features/gateway/graphql/listWebsiteBuilderPageReviews.js +34 -0
  270. package/features/gateway/graphql/listWebsiteBuilderPageReviews.js.map +1 -0
  271. package/features/gateway/graphql/listWebsiteBuilderPageStepCandidates.d.ts +1 -0
  272. package/features/gateway/graphql/listWebsiteBuilderPageStepCandidates.js +22 -0
  273. package/features/gateway/graphql/listWebsiteBuilderPageStepCandidates.js.map +1 -0
  274. package/features/gateway/graphql/listWebsiteBuilderPageWorkflows.d.ts +1 -0
  275. package/features/gateway/graphql/listWebsiteBuilderPageWorkflows.js +18 -0
  276. package/features/gateway/graphql/listWebsiteBuilderPageWorkflows.js.map +1 -0
  277. package/features/gateway/graphql/reassignWebsiteBuilderPageReviewStep.d.ts +1 -0
  278. package/features/gateway/graphql/reassignWebsiteBuilderPageReviewStep.js +22 -0
  279. package/features/gateway/graphql/reassignWebsiteBuilderPageReviewStep.js.map +1 -0
  280. package/features/gateway/graphql/rejectWebsiteBuilderPageReviewStep.d.ts +1 -0
  281. package/features/gateway/graphql/rejectWebsiteBuilderPageReviewStep.js +22 -0
  282. package/features/gateway/graphql/rejectWebsiteBuilderPageReviewStep.js.map +1 -0
  283. package/features/gateway/graphql/requestWebsiteBuilderPageReview.d.ts +1 -0
  284. package/features/gateway/graphql/requestWebsiteBuilderPageReview.js +26 -0
  285. package/features/gateway/graphql/requestWebsiteBuilderPageReview.js.map +1 -0
  286. package/features/gateway/graphql/restartWebsiteBuilderPageReviewStep.d.ts +1 -0
  287. package/features/gateway/graphql/restartWebsiteBuilderPageReviewStep.js +18 -0
  288. package/features/gateway/graphql/restartWebsiteBuilderPageReviewStep.js.map +1 -0
  289. package/features/gateway/graphql/startWebsiteBuilderPageReviewStep.d.ts +1 -0
  290. package/features/gateway/graphql/startWebsiteBuilderPageReviewStep.js +18 -0
  291. package/features/gateway/graphql/startWebsiteBuilderPageReviewStep.js.map +1 -0
  292. package/features/gateway/graphql/takeOverWebsiteBuilderPageReviewStep.d.ts +1 -0
  293. package/features/gateway/graphql/takeOverWebsiteBuilderPageReviewStep.js +26 -0
  294. package/features/gateway/graphql/takeOverWebsiteBuilderPageReviewStep.js.map +1 -0
  295. package/features/trash/BulkDeletePresenterReviewDecorator.d.ts +14 -0
  296. package/features/trash/BulkDeletePresenterReviewDecorator.js +27 -0
  297. package/features/trash/BulkDeletePresenterReviewDecorator.js.map +1 -0
  298. package/features/trash/BulkDeletePresenterReviewDecorator.test.d.ts +1 -0
  299. package/features/trash/BulkDeletePresenterReviewDecorator.test.js +234 -0
  300. package/features/trash/BulkDeletePresenterReviewDecorator.test.js.map +1 -0
  301. package/features/trash/DeletePageRevisionUseCaseReviewDecorator.d.ts +13 -0
  302. package/features/trash/DeletePageRevisionUseCaseReviewDecorator.js +23 -0
  303. package/features/trash/DeletePageRevisionUseCaseReviewDecorator.js.map +1 -0
  304. package/features/trash/DeletePageRevisionUseCaseReviewDecorator.test.d.ts +1 -0
  305. package/features/trash/DeletePageRevisionUseCaseReviewDecorator.test.js +114 -0
  306. package/features/trash/DeletePageRevisionUseCaseReviewDecorator.test.js.map +1 -0
  307. package/features/trash/DeletePageUseCaseReviewDecorator.d.ts +13 -0
  308. package/features/trash/DeletePageUseCaseReviewDecorator.js +23 -0
  309. package/features/trash/DeletePageUseCaseReviewDecorator.js.map +1 -0
  310. package/features/trash/DeletePageUseCaseReviewDecorator.test.d.ts +1 -0
  311. package/features/trash/DeletePageUseCaseReviewDecorator.test.js +134 -0
  312. package/features/trash/DeletePageUseCaseReviewDecorator.test.js.map +1 -0
  313. package/features/trash/feature.d.ts +1 -0
  314. package/features/trash/feature.js +15 -0
  315. package/features/trash/feature.js.map +1 -0
  316. package/features/trash/feature.test.d.ts +1 -0
  317. package/features/trash/feature.test.js +183 -0
  318. package/features/trash/feature.test.js.map +1 -0
  319. package/hooks/usePage.d.ts +5 -0
  320. package/hooks/usePage.js +15 -0
  321. package/hooks/usePage.js.map +1 -0
  322. package/hooks/usePage.test.d.ts +1 -0
  323. package/hooks/usePage.test.js +49 -0
  324. package/hooks/usePage.test.js.map +1 -0
  325. package/index.d.ts +2 -0
  326. package/index.js +40 -0
  327. package/index.js.map +1 -0
  328. package/index.mount.test.d.ts +1 -0
  329. package/index.mount.test.js +50 -0
  330. package/index.mount.test.js.map +1 -0
  331. package/index.test.d.ts +1 -0
  332. package/index.test.js +523 -0
  333. package/index.test.js.map +1 -0
  334. package/package.json +54 -0
  335. package/pageListChangeStatus.wiring.test.d.ts +1 -0
  336. package/pageListChangeStatus.wiring.test.js +175 -0
  337. package/pageListChangeStatus.wiring.test.js.map +1 -0
  338. package/pageListGlue.wiring.test.d.ts +1 -0
  339. package/pageListGlue.wiring.test.js +220 -0
  340. package/pageListGlue.wiring.test.js.map +1 -0
  341. package/presentation/page/PageGet/WbReviewGetPageFieldSelection.d.ts +8 -0
  342. package/presentation/page/PageGet/WbReviewGetPageFieldSelection.js +16 -0
  343. package/presentation/page/PageGet/WbReviewGetPageFieldSelection.js.map +1 -0
  344. package/presentation/page/PageGet/WbReviewGetPageFieldSelection.test.d.ts +1 -0
  345. package/presentation/page/PageGet/WbReviewGetPageFieldSelection.test.js +19 -0
  346. package/presentation/page/PageGet/WbReviewGetPageFieldSelection.test.js.map +1 -0
  347. package/presentation/page/PageGet/feature.d.ts +1 -0
  348. package/presentation/page/PageGet/feature.js +11 -0
  349. package/presentation/page/PageGet/feature.js.map +1 -0
  350. package/presentation/page/PageList/WbReviewListPagesFieldSelection.d.ts +8 -0
  351. package/presentation/page/PageList/WbReviewListPagesFieldSelection.js +16 -0
  352. package/presentation/page/PageList/WbReviewListPagesFieldSelection.js.map +1 -0
  353. package/presentation/page/PageList/WbReviewListPagesFieldSelection.test.d.ts +1 -0
  354. package/presentation/page/PageList/WbReviewListPagesFieldSelection.test.js +19 -0
  355. package/presentation/page/PageList/WbReviewListPagesFieldSelection.test.js.map +1 -0
  356. package/presentation/page/PageList/WbReviewTableRowMapperDecorator.d.ts +12 -0
  357. package/presentation/page/PageList/WbReviewTableRowMapperDecorator.js +24 -0
  358. package/presentation/page/PageList/WbReviewTableRowMapperDecorator.js.map +1 -0
  359. package/presentation/page/PageList/WbReviewTableRowMapperDecorator.test.d.ts +1 -0
  360. package/presentation/page/PageList/WbReviewTableRowMapperDecorator.test.js +70 -0
  361. package/presentation/page/PageList/WbReviewTableRowMapperDecorator.test.js.map +1 -0
  362. package/presentation/page/PageList/feature.d.ts +1 -0
  363. package/presentation/page/PageList/feature.js +13 -0
  364. package/presentation/page/PageList/feature.js.map +1 -0
  365. package/presentation/page/RevisionList/RevisionListPresenterDecorator.d.ts +15 -0
  366. package/presentation/page/RevisionList/RevisionListPresenterDecorator.js +36 -0
  367. package/presentation/page/RevisionList/RevisionListPresenterDecorator.js.map +1 -0
  368. package/presentation/page/RevisionList/RevisionListPresenterDecorator.test.d.ts +1 -0
  369. package/presentation/page/RevisionList/RevisionListPresenterDecorator.test.js +119 -0
  370. package/presentation/page/RevisionList/RevisionListPresenterDecorator.test.js.map +1 -0
  371. package/presentation/page/RevisionList/feature.d.ts +1 -0
  372. package/presentation/page/RevisionList/feature.js +11 -0
  373. package/presentation/page/RevisionList/feature.js.map +1 -0
  374. package/presentation/page/wbReviewPageSelection.d.ts +1 -0
  375. package/presentation/page/wbReviewPageSelection.js +9 -0
  376. package/presentation/page/wbReviewPageSelection.js.map +1 -0
  377. package/publishAutosave.wiring.test.d.ts +1 -0
  378. package/publishAutosave.wiring.test.js +162 -0
  379. package/publishAutosave.wiring.test.js.map +1 -0
  380. package/routes.d.ts +9 -0
  381. package/routes.js +19 -0
  382. package/routes.js.map +1 -0
  383. package/testing/WbEditorHarness.d.ts +11 -0
  384. package/testing/WbEditorHarness.js +22 -0
  385. package/testing/WbEditorHarness.js.map +1 -0
  386. package/testing/createFakeSession.d.ts +9 -0
  387. package/testing/createFakeSession.js +29 -0
  388. package/testing/createFakeSession.js.map +1 -0
  389. package/testing/createFakeVm.d.ts +3 -0
  390. package/testing/createFakeVm.js +51 -0
  391. package/testing/createFakeVm.js.map +1 -0
  392. package/testing/createFolder.d.ts +2 -0
  393. package/testing/createFolder.js +13 -0
  394. package/testing/createFolder.js.map +1 -0
  395. package/testing/createPageEditor.d.ts +4 -0
  396. package/testing/createPageEditor.js +26 -0
  397. package/testing/createPageEditor.js.map +1 -0
  398. package/testing/registerPageContent.d.ts +20 -0
  399. package/testing/registerPageContent.js +28 -0
  400. package/testing/registerPageContent.js.map +1 -0
  401. package/types.d.ts +9 -0
  402. package/types.js +0 -0
@@ -0,0 +1,234 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { Container } from "@webiny/di";
3
+ import { GraphQLOperationError } from "@webiny/app/errors/index.js";
4
+ import { Confirmation } from "@webiny/app-admin/features/confirmation/abstractions.js";
5
+ import { Notifications } from "@webiny/app-admin/features/notifications/abstractions.js";
6
+ import { Page } from "@webiny/app-website-builder/domain/Page/Page.js";
7
+ import { DeletePageUseCase } from "@webiny/app-website-builder/features/pages/deletePage/abstractions.js";
8
+ import { BulkDeletePresenter } from "@webiny/app-website-builder/presentation/pages/bulkActions/abstractions.js";
9
+ import { ReviewErrorCode } from "@webiny/app-workflows/review/domain/ReviewErrorCode.js";
10
+ import { REVIEW_TOAST_DURATION, REVIEW_TOAST_POSITION } from "@webiny/app-workflows/review/toasts/constants.js";
11
+ import { ActiveReviewGuard } from "@webiny/app-workflows/review/trash/ActiveReviewGuard/abstractions.js";
12
+ import { ActiveReviewBlockCollector } from "@webiny/app-workflows/review/trash/ActiveReviewBlockCollector/ActiveReviewBlockCollector.js";
13
+ import { ActiveReviewGuard as ActiveReviewGuard_js_ActiveReviewGuard } from "@webiny/app-workflows/review/trash/ActiveReviewGuard/ActiveReviewGuard.js";
14
+ import { createTrashUseCaseFakes } from "@webiny/app-workflows/review/testing/createTrashUseCaseFakes.js";
15
+ import { registerTrashUseCaseFakes } from "@webiny/app-workflows/review/testing/registerTrashUseCaseFakes.js";
16
+ import { DeletePageUseCaseReviewDecorator } from "./DeletePageUseCaseReviewDecorator.js";
17
+ import { BulkDeletePresenterReviewDecorator } from "./BulkDeletePresenterReviewDecorator.js";
18
+ function page(entryId) {
19
+ return Page.create({
20
+ id: `${entryId}#0001`,
21
+ entryId,
22
+ properties: {
23
+ title: `Title ${entryId}`
24
+ }
25
+ });
26
+ }
27
+ function createRefusal(entryId) {
28
+ return new GraphQLOperationError({
29
+ message: "This content has a review in progress.",
30
+ code: ReviewErrorCode.ActiveReviewOnTrash,
31
+ data: {
32
+ model: "wb.page",
33
+ action: "trash",
34
+ reviews: [
35
+ {
36
+ reviewId: `review-${entryId}`,
37
+ model: "wb.page",
38
+ targetId: entryId,
39
+ targetRevisionId: `${entryId}#0001`,
40
+ title: `Title ${entryId}`,
41
+ stepPosition: 1,
42
+ stepCount: 2,
43
+ stepName: "Editor"
44
+ }
45
+ ]
46
+ }
47
+ });
48
+ }
49
+ describe("BulkDeletePresenterReviewDecorator (forwarding)", ()=>{
50
+ function setupForwarding() {
51
+ const decoratee = {
52
+ vm: {
53
+ processing: false,
54
+ results: []
55
+ },
56
+ execute: vi.fn(async (_items)=>void 0)
57
+ };
58
+ const useCases = createTrashUseCaseFakes();
59
+ const guard = {
60
+ run: vi.fn(),
61
+ runBulk: vi.fn(async (params)=>{
62
+ await params.run(params.items, false);
63
+ await params.run(params.items, true);
64
+ })
65
+ };
66
+ const container = new Container();
67
+ container.registerInstance(ActiveReviewGuard, guard);
68
+ registerTrashUseCaseFakes(container, useCases);
69
+ container.registerInstance(BulkDeletePresenter, decoratee);
70
+ container.registerDecorator(BulkDeletePresenterReviewDecorator);
71
+ return {
72
+ decoratee,
73
+ guard,
74
+ useCases,
75
+ presenter: container.resolve(BulkDeletePresenter)
76
+ };
77
+ }
78
+ it("hands the items, the page id and a run callback to the guard, and no use cases (R353)", async ()=>{
79
+ const { guard, presenter } = setupForwarding();
80
+ const items = [
81
+ page("p1"),
82
+ page("p2")
83
+ ];
84
+ await presenter.execute(items);
85
+ expect(guard.runBulk).toHaveBeenCalledTimes(1);
86
+ const params = guard.runBulk.mock.calls[0][0];
87
+ expect(params.items).toBe(items);
88
+ expect(params).not.toHaveProperty("useCases");
89
+ expect(params.getTargetId(items[0])).toBe("p1");
90
+ });
91
+ it("runs the decoratee with the batch only, for the first run and the retry", async ()=>{
92
+ const { decoratee, presenter } = setupForwarding();
93
+ const items = [
94
+ page("p1")
95
+ ];
96
+ await presenter.execute(items);
97
+ expect(decoratee.execute).toHaveBeenCalledTimes(2);
98
+ expect(decoratee.execute).toHaveBeenNthCalledWith(1, items);
99
+ expect(decoratee.execute).toHaveBeenNthCalledWith(2, items);
100
+ });
101
+ it("delegates the view model to the decoratee", ()=>{
102
+ const { decoratee, presenter } = setupForwarding();
103
+ expect(presenter.vm).toBe(decoratee.vm);
104
+ });
105
+ });
106
+ describe("BulkDeletePresenterReviewDecorator (with the real guard and the per-page decorator)", ()=>{
107
+ function setupIntegrated(decision) {
108
+ let release = ()=>void 0;
109
+ const gate = new Promise((resolve)=>{
110
+ release = resolve;
111
+ });
112
+ const confirm = vi.fn(async (_name, _params, execute)=>{
113
+ if ("deferred" === decision) await gate;
114
+ return execute ? execute(void 0) : void 0;
115
+ });
116
+ const blocked = new Set([
117
+ "p1",
118
+ "p3"
119
+ ]);
120
+ const deleted = [];
121
+ const failed = [];
122
+ const deletePage = {
123
+ execute: vi.fn(async (params)=>{
124
+ const entryId = params.id.split("#")[0];
125
+ if (blocked.has(entryId)) throw createRefusal(entryId);
126
+ deleted.push(entryId);
127
+ return true;
128
+ })
129
+ };
130
+ const useCases = createTrashUseCaseFakes();
131
+ useCases.cancelReviewsForDelete.execute.mockImplementation(async (params)=>{
132
+ blocked.delete(params.targetId);
133
+ return [];
134
+ });
135
+ const container = new Container();
136
+ container.registerInstance(Confirmation, {
137
+ confirm
138
+ });
139
+ const notifications = {
140
+ notify: vi.fn(),
141
+ success: vi.fn(),
142
+ warning: vi.fn()
143
+ };
144
+ container.registerInstance(Notifications, notifications);
145
+ container.register(ActiveReviewBlockCollector).inSingletonScope();
146
+ container.register(ActiveReviewGuard_js_ActiveReviewGuard).inSingletonScope();
147
+ registerTrashUseCaseFakes(container, useCases);
148
+ container.registerInstance(DeletePageUseCase, deletePage);
149
+ container.registerDecorator(DeletePageUseCaseReviewDecorator);
150
+ const decoratee = {
151
+ vm: {
152
+ processing: false,
153
+ results: []
154
+ },
155
+ execute: vi.fn(async (items)=>{
156
+ const useCase = container.resolve(DeletePageUseCase);
157
+ for (const item of items){
158
+ const result = await useCase.execute({
159
+ id: item.id,
160
+ permanently: false
161
+ });
162
+ if (false === result) failed.push(item.entryId);
163
+ }
164
+ })
165
+ };
166
+ container.registerInstance(BulkDeletePresenter, decoratee);
167
+ container.registerDecorator(BulkDeletePresenterReviewDecorator);
168
+ return {
169
+ confirm,
170
+ release,
171
+ deleted,
172
+ failed,
173
+ decoratee,
174
+ useCases,
175
+ notifications,
176
+ presenter: container.resolve(BulkDeletePresenter)
177
+ };
178
+ }
179
+ const items = [
180
+ page("p1"),
181
+ page("p2"),
182
+ page("p3")
183
+ ];
184
+ it("collects every refused page, warns once and retries only the blocked pages", async ()=>{
185
+ const { confirm, deleted, failed, decoratee, useCases, notifications, presenter } = setupIntegrated("confirm");
186
+ await presenter.execute(items);
187
+ expect(notifications.warning).toHaveBeenCalledTimes(1);
188
+ expect(notifications.warning).toHaveBeenCalledWith(expect.objectContaining({
189
+ title: "1 of 3 items done. 2 still need your confirmation.",
190
+ position: REVIEW_TOAST_POSITION,
191
+ duration: REVIEW_TOAST_DURATION,
192
+ dismissible: true
193
+ }));
194
+ expect(confirm).toHaveBeenCalledTimes(1);
195
+ const dialogParams = confirm.mock.calls[0][1];
196
+ expect(dialogParams.reviews.map((review)=>review.reviewId)).toEqual([
197
+ "review-p1",
198
+ "review-p3"
199
+ ]);
200
+ expect(useCases.cancelReviewsForDelete.execute).toHaveBeenCalledTimes(2);
201
+ expect(useCases.cancelReviewsForDelete.execute).toHaveBeenCalledWith({
202
+ namespace: "wb.page",
203
+ targetId: "p1",
204
+ targetRevisionId: null,
205
+ action: "trash"
206
+ });
207
+ expect(decoratee.execute).toHaveBeenCalledTimes(2);
208
+ expect(decoratee.execute.mock.calls[1][0].map((item)=>item.entryId)).toEqual([
209
+ "p1",
210
+ "p3"
211
+ ]);
212
+ expect(failed).toEqual([
213
+ "p1",
214
+ "p3"
215
+ ]);
216
+ expect(deleted).toEqual([
217
+ "p2",
218
+ "p1",
219
+ "p3"
220
+ ]);
221
+ });
222
+ it("resolves execute only after the warning flow has ended (R228)", async ()=>{
223
+ const { confirm, release, presenter } = setupIntegrated("deferred");
224
+ const settled = vi.fn();
225
+ const promise = presenter.execute(items).then(settled);
226
+ await vi.waitFor(()=>expect(confirm).toHaveBeenCalled());
227
+ expect(settled).not.toHaveBeenCalled();
228
+ release();
229
+ await promise;
230
+ expect(settled).toHaveBeenCalledTimes(1);
231
+ });
232
+ });
233
+
234
+ //# sourceMappingURL=BulkDeletePresenterReviewDecorator.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/trash/BulkDeletePresenterReviewDecorator.test.js","sources":["../../../src/features/trash/BulkDeletePresenterReviewDecorator.test.ts"],"sourcesContent":["import { describe } from \"vitest\";\nimport { expect } from \"vitest\";\nimport { it } from \"vitest\";\nimport { vi } from \"vitest\";\nimport { Container } from \"@webiny/di\";\nimport { GraphQLOperationError } from \"@webiny/app/errors/index.js\";\nimport { Confirmation } from \"@webiny/app-admin/features/confirmation/abstractions.js\";\nimport { Notifications } from \"@webiny/app-admin/features/notifications/abstractions.js\";\nimport { Page } from \"@webiny/app-website-builder/domain/Page/Page.js\";\nimport { DeletePageUseCase } from \"@webiny/app-website-builder/features/pages/deletePage/abstractions.js\";\nimport { BulkDeletePresenter } from \"@webiny/app-website-builder/presentation/pages/bulkActions/abstractions.js\";\nimport { ReviewErrorCode } from \"@webiny/app-workflows/review/domain/ReviewErrorCode.js\";\nimport { REVIEW_TOAST_DURATION } from \"@webiny/app-workflows/review/toasts/constants.js\";\nimport { REVIEW_TOAST_POSITION } from \"@webiny/app-workflows/review/toasts/constants.js\";\nimport { ActiveReviewGuard as GuardAbstraction } from \"@webiny/app-workflows/review/trash/ActiveReviewGuard/abstractions.js\";\nimport { ActiveReviewBlockCollector } from \"@webiny/app-workflows/review/trash/ActiveReviewBlockCollector/ActiveReviewBlockCollector.js\";\nimport { ActiveReviewGuard } from \"@webiny/app-workflows/review/trash/ActiveReviewGuard/ActiveReviewGuard.js\";\nimport { createTrashUseCaseFakes } from \"@webiny/app-workflows/review/testing/createTrashUseCaseFakes.js\";\nimport { registerTrashUseCaseFakes } from \"@webiny/app-workflows/review/testing/registerTrashUseCaseFakes.js\";\nimport { DeletePageUseCaseReviewDecorator } from \"./DeletePageUseCaseReviewDecorator.js\";\nimport { BulkDeletePresenterReviewDecorator } from \"./BulkDeletePresenterReviewDecorator.js\";\n\ninterface DeleteParams {\n id: string;\n permanently: boolean;\n}\n\nfunction page(entryId: string): Page {\n return Page.create({\n id: `${entryId}#0001`,\n entryId,\n properties: { title: `Title ${entryId}` }\n });\n}\n\nfunction createRefusal(entryId: string) {\n return new GraphQLOperationError({\n message: \"This content has a review in progress.\",\n code: ReviewErrorCode.ActiveReviewOnTrash,\n data: {\n model: \"wb.page\",\n action: \"trash\",\n reviews: [\n {\n reviewId: `review-${entryId}`,\n model: \"wb.page\",\n targetId: entryId,\n targetRevisionId: `${entryId}#0001`,\n title: `Title ${entryId}`,\n stepPosition: 1,\n stepCount: 2,\n stepName: \"Editor\"\n }\n ]\n }\n });\n}\n\ndescribe(\"BulkDeletePresenterReviewDecorator (forwarding)\", () => {\n function setupForwarding() {\n const decoratee = {\n vm: { processing: false, results: [] },\n execute: vi.fn(async (_items: Page[]) => undefined)\n };\n const useCases = createTrashUseCaseFakes();\n const guard = {\n run: vi.fn(),\n runBulk: vi.fn(async <TItem>(params: GuardAbstraction.BulkParams<TItem>) => {\n await params.run(params.items, false);\n await params.run(params.items, true);\n })\n };\n\n const container = new Container();\n container.registerInstance(\n GuardAbstraction,\n guard as unknown as GuardAbstraction.Interface\n );\n registerTrashUseCaseFakes(container, useCases);\n container.registerInstance(BulkDeletePresenter, decoratee);\n container.registerDecorator(BulkDeletePresenterReviewDecorator);\n\n return {\n decoratee,\n guard,\n useCases,\n presenter: container.resolve(BulkDeletePresenter)\n };\n }\n\n it(\"hands the items, the page id and a run callback to the guard, and no use cases (R353)\", async () => {\n const { guard, presenter } = setupForwarding();\n const items = [page(\"p1\"), page(\"p2\")];\n\n await presenter.execute(items);\n\n expect(guard.runBulk).toHaveBeenCalledTimes(1);\n const params = guard.runBulk.mock.calls[0][0];\n expect(params.items).toBe(items);\n expect(params).not.toHaveProperty(\"useCases\");\n expect(params.getTargetId(items[0])).toBe(\"p1\");\n });\n\n it(\"runs the decoratee with the batch only, for the first run and the retry\", async () => {\n const { decoratee, presenter } = setupForwarding();\n const items = [page(\"p1\")];\n\n await presenter.execute(items);\n\n expect(decoratee.execute).toHaveBeenCalledTimes(2);\n expect(decoratee.execute).toHaveBeenNthCalledWith(1, items);\n expect(decoratee.execute).toHaveBeenNthCalledWith(2, items);\n });\n\n it(\"delegates the view model to the decoratee\", () => {\n const { decoratee, presenter } = setupForwarding();\n\n expect(presenter.vm).toBe(decoratee.vm);\n });\n});\n\ndescribe(\"BulkDeletePresenterReviewDecorator (with the real guard and the per-page decorator)\", () => {\n function setupIntegrated(decision: \"confirm\" | \"deferred\") {\n let release: () => void = () => undefined;\n const gate = new Promise<void>(resolve => {\n release = resolve;\n });\n const confirm = vi.fn(\n async (\n _name: string,\n _params: unknown,\n execute?: (data: unknown) => Promise<unknown>\n ) => {\n if (decision === \"deferred\") {\n await gate;\n }\n return execute ? execute(undefined) : undefined;\n }\n );\n const blocked = new Set([\"p1\", \"p3\"]);\n const deleted: string[] = [];\n const failed: string[] = [];\n const deletePage = {\n execute: vi.fn(async (params: DeleteParams) => {\n const entryId = params.id.split(\"#\")[0];\n if (blocked.has(entryId)) {\n throw createRefusal(entryId);\n }\n deleted.push(entryId);\n return true;\n })\n };\n const useCases = createTrashUseCaseFakes();\n useCases.cancelReviewsForDelete.execute.mockImplementation(async params => {\n blocked.delete(params.targetId);\n return [];\n });\n\n const container = new Container();\n container.registerInstance(Confirmation, { confirm } as unknown as Confirmation.Interface);\n // The real guard reports the first-pass count through Notifications (Task 33).\n const notifications = { notify: vi.fn(), success: vi.fn(), warning: vi.fn() };\n container.registerInstance(\n Notifications,\n notifications as unknown as Notifications.Interface\n );\n container.register(ActiveReviewBlockCollector).inSingletonScope();\n container.register(ActiveReviewGuard).inSingletonScope();\n registerTrashUseCaseFakes(container, useCases);\n container.registerInstance(DeletePageUseCase, deletePage);\n container.registerDecorator(DeletePageUseCaseReviewDecorator);\n\n // Stands in for the base presenter: a per-page series that calls the decorated use case.\n const decoratee = {\n vm: { processing: false, results: [] },\n execute: vi.fn(async (items: Page[]) => {\n const useCase = container.resolve(DeletePageUseCase);\n for (const item of items) {\n // Like the base presenter: a false result is \"not deleted\", reported as failed.\n const result = await useCase.execute({ id: item.id, permanently: false });\n if (result === false) {\n failed.push(item.entryId);\n }\n }\n })\n };\n container.registerInstance(BulkDeletePresenter, decoratee);\n container.registerDecorator(BulkDeletePresenterReviewDecorator);\n\n return {\n confirm,\n release,\n deleted,\n failed,\n decoratee,\n useCases,\n notifications,\n presenter: container.resolve(BulkDeletePresenter)\n };\n }\n\n const items = [page(\"p1\"), page(\"p2\"), page(\"p3\")];\n\n it(\"collects every refused page, warns once and retries only the blocked pages\", async () => {\n const { confirm, deleted, failed, decoratee, useCases, notifications, presenter } =\n setupIntegrated(\"confirm\");\n\n await presenter.execute(items);\n\n // First pass: p2 was done, p1 and p3 were refused (Q28, Task 33).\n expect(notifications.warning).toHaveBeenCalledTimes(1);\n expect(notifications.warning).toHaveBeenCalledWith(\n expect.objectContaining({\n title: \"1 of 3 items done. 2 still need your confirmation.\",\n position: REVIEW_TOAST_POSITION,\n duration: REVIEW_TOAST_DURATION,\n dismissible: true\n })\n );\n\n expect(confirm).toHaveBeenCalledTimes(1);\n const dialogParams = confirm.mock.calls[0][1] as GuardAbstraction.DialogParams;\n expect(dialogParams.reviews.map(review => review.reviewId)).toEqual([\n \"review-p1\",\n \"review-p3\"\n ]);\n expect(useCases.cancelReviewsForDelete.execute).toHaveBeenCalledTimes(2);\n expect(useCases.cancelReviewsForDelete.execute).toHaveBeenCalledWith({\n namespace: \"wb.page\",\n targetId: \"p1\",\n targetRevisionId: null,\n action: \"trash\"\n });\n expect(decoratee.execute).toHaveBeenCalledTimes(2);\n expect(decoratee.execute.mock.calls[1][0].map(item => item.entryId)).toEqual([\"p1\", \"p3\"]);\n expect(failed).toEqual([\"p1\", \"p3\"]);\n expect(deleted).toEqual([\"p2\", \"p1\", \"p3\"]);\n });\n\n it(\"resolves execute only after the warning flow has ended (R228)\", async () => {\n const { confirm, release, presenter } = setupIntegrated(\"deferred\");\n const settled = vi.fn();\n\n const promise = presenter.execute(items).then(settled);\n\n await vi.waitFor(() => expect(confirm).toHaveBeenCalled());\n expect(settled).not.toHaveBeenCalled();\n release();\n await promise;\n expect(settled).toHaveBeenCalledTimes(1);\n });\n});\n"],"names":["page","entryId","Page","createRefusal","GraphQLOperationError","ReviewErrorCode","describe","setupForwarding","decoratee","vi","_items","undefined","useCases","createTrashUseCaseFakes","guard","params","container","Container","GuardAbstraction","registerTrashUseCaseFakes","BulkDeletePresenter","BulkDeletePresenterReviewDecorator","it","presenter","items","expect","setupIntegrated","decision","release","gate","Promise","resolve","confirm","_name","_params","execute","blocked","Set","deleted","failed","deletePage","Confirmation","notifications","Notifications","ActiveReviewBlockCollector","ActiveReviewGuard","DeletePageUseCase","DeletePageUseCaseReviewDecorator","useCase","item","result","REVIEW_TOAST_POSITION","REVIEW_TOAST_DURATION","dialogParams","review","settled","promise"],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { DeletePageRevisionUseCase } from "@webiny/app-website-builder/features/pages/deletePageRevision/abstractions.js";
2
+ import type { DeletePageRevisionParams } from "@webiny/app-website-builder/features/pages/deletePageRevision/abstractions.js";
3
+ import { ActiveReviewGuard } from "@webiny/app-workflows/review/trash/ActiveReviewGuard/abstractions.js";
4
+ declare class DeletePageRevisionUseCaseReviewDecoratorImpl implements DeletePageRevisionUseCase.Interface {
5
+ private guard;
6
+ private decoratee;
7
+ constructor(guard: ActiveReviewGuard.Interface, decoratee: DeletePageRevisionUseCase.Interface);
8
+ execute(params: DeletePageRevisionParams): Promise<boolean>;
9
+ }
10
+ export declare const DeletePageRevisionUseCaseReviewDecorator: typeof DeletePageRevisionUseCaseReviewDecoratorImpl & {
11
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/app-website-builder/features/pages/deletePageRevision/abstractions.js").IDeletePageRevisionUseCase>;
12
+ };
13
+ export {};
@@ -0,0 +1,23 @@
1
+ import { DeletePageRevisionUseCase } from "@webiny/app-website-builder/features/pages/deletePageRevision/abstractions.js";
2
+ import { ActiveReviewGuard } from "@webiny/app-workflows/review/trash/ActiveReviewGuard/abstractions.js";
3
+ class DeletePageRevisionUseCaseReviewDecoratorImpl {
4
+ constructor(guard, decoratee){
5
+ this.guard = guard;
6
+ this.decoratee = decoratee;
7
+ }
8
+ async execute(params) {
9
+ return this.guard.run({
10
+ action: ()=>this.decoratee.execute(params),
11
+ revisionId: params.id
12
+ });
13
+ }
14
+ }
15
+ const DeletePageRevisionUseCaseReviewDecorator = DeletePageRevisionUseCase.createDecorator({
16
+ decorator: DeletePageRevisionUseCaseReviewDecoratorImpl,
17
+ dependencies: [
18
+ ActiveReviewGuard
19
+ ]
20
+ });
21
+ export { DeletePageRevisionUseCaseReviewDecorator };
22
+
23
+ //# sourceMappingURL=DeletePageRevisionUseCaseReviewDecorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/trash/DeletePageRevisionUseCaseReviewDecorator.js","sources":["../../../src/features/trash/DeletePageRevisionUseCaseReviewDecorator.ts"],"sourcesContent":["import { DeletePageRevisionUseCase } from \"@webiny/app-website-builder/features/pages/deletePageRevision/abstractions.js\";\nimport type { DeletePageRevisionParams } from \"@webiny/app-website-builder/features/pages/deletePageRevision/abstractions.js\";\nimport { ActiveReviewGuard } from \"@webiny/app-workflows/review/trash/ActiveReviewGuard/abstractions.js\";\n\nclass DeletePageRevisionUseCaseReviewDecoratorImpl implements DeletePageRevisionUseCase.Interface {\n constructor(\n private guard: ActiveReviewGuard.Interface,\n private decoratee: DeletePageRevisionUseCase.Interface\n ) {}\n\n async execute(params: DeletePageRevisionParams): Promise<boolean> {\n return this.guard.run({\n action: () => this.decoratee.execute(params),\n revisionId: params.id\n });\n }\n}\n\nexport const DeletePageRevisionUseCaseReviewDecorator = DeletePageRevisionUseCase.createDecorator({\n decorator: DeletePageRevisionUseCaseReviewDecoratorImpl,\n dependencies: [ActiveReviewGuard]\n});\n"],"names":["DeletePageRevisionUseCaseReviewDecoratorImpl","guard","decoratee","params","DeletePageRevisionUseCaseReviewDecorator","DeletePageRevisionUseCase","ActiveReviewGuard"],"mappings":";;AAIA,MAAMA;IACF,YACYC,KAAkC,EAClCC,SAA8C,CACxD;aAFUD,KAAK,GAALA;aACAC,SAAS,GAATA;IACT;IAEH,MAAM,QAAQC,MAAgC,EAAoB;QAC9D,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;YAClB,QAAQ,IAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAACA;YACrC,YAAYA,OAAO,EAAE;QACzB;IACJ;AACJ;AAEO,MAAMC,2CAA2CC,0BAA0B,eAAe,CAAC;IAC9F,WAAWL;IACX,cAAc;QAACM;KAAkB;AACrC"}
@@ -0,0 +1,114 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { Container } from "@webiny/di";
3
+ import { GraphQLOperationError } from "@webiny/app/errors/index.js";
4
+ import { Confirmation } from "@webiny/app-admin/features/confirmation/abstractions.js";
5
+ import { Notifications } from "@webiny/app-admin/features/notifications/abstractions.js";
6
+ import { DeletePageRevisionUseCase } from "@webiny/app-website-builder/features/pages/deletePageRevision/abstractions.js";
7
+ import { ReviewErrorCode } from "@webiny/app-workflows/review/domain/ReviewErrorCode.js";
8
+ import { ActiveReviewBlockCollector } from "@webiny/app-workflows/review/trash/ActiveReviewBlockCollector/ActiveReviewBlockCollector.js";
9
+ import { ActiveReviewGuard } from "@webiny/app-workflows/review/trash/ActiveReviewGuard/ActiveReviewGuard.js";
10
+ import { createTrashUseCaseFakes } from "@webiny/app-workflows/review/testing/createTrashUseCaseFakes.js";
11
+ import { registerTrashUseCaseFakes } from "@webiny/app-workflows/review/testing/registerTrashUseCaseFakes.js";
12
+ import { DeletePageRevisionUseCaseReviewDecorator } from "./DeletePageRevisionUseCaseReviewDecorator.js";
13
+ function createRefusal() {
14
+ return new GraphQLOperationError({
15
+ message: "This content has a review in progress.",
16
+ code: ReviewErrorCode.ActiveReviewOnTrash,
17
+ data: {
18
+ model: "wb.page",
19
+ action: "delete",
20
+ reviews: [
21
+ {
22
+ reviewId: "review-2",
23
+ model: "wb.page",
24
+ targetId: "page-1",
25
+ targetRevisionId: "page-1#0002",
26
+ title: "Home page",
27
+ stepPosition: 2,
28
+ stepCount: 2,
29
+ stepName: "Legal"
30
+ }
31
+ ]
32
+ }
33
+ });
34
+ }
35
+ function setup(decision = "confirm") {
36
+ const confirm = vi.fn(async (_name, _params, execute)=>{
37
+ if ("dismiss" === decision) return false;
38
+ return execute ? execute(void 0) : void 0;
39
+ });
40
+ const decoratee = {
41
+ execute: vi.fn()
42
+ };
43
+ const useCases = createTrashUseCaseFakes();
44
+ const container = new Container();
45
+ container.registerInstance(Confirmation, {
46
+ confirm
47
+ });
48
+ container.registerInstance(Notifications, {
49
+ notify: vi.fn(),
50
+ success: vi.fn(),
51
+ warning: vi.fn()
52
+ });
53
+ container.register(ActiveReviewBlockCollector).inSingletonScope();
54
+ container.register(ActiveReviewGuard).inSingletonScope();
55
+ registerTrashUseCaseFakes(container, useCases);
56
+ container.registerInstance(DeletePageRevisionUseCase, decoratee);
57
+ container.registerDecorator(DeletePageRevisionUseCaseReviewDecorator);
58
+ return {
59
+ confirm,
60
+ decoratee,
61
+ useCases,
62
+ useCase: container.resolve(DeletePageRevisionUseCase)
63
+ };
64
+ }
65
+ describe("DeletePageRevisionUseCaseReviewDecorator", ()=>{
66
+ it("passes through to the decoratee when the delete succeeds", async ()=>{
67
+ const { confirm, decoratee, useCase } = setup();
68
+ decoratee.execute.mockResolvedValue(true);
69
+ const result = await useCase.execute({
70
+ id: "page-1#0002"
71
+ });
72
+ expect(result).toBe(true);
73
+ expect(decoratee.execute).toHaveBeenCalledWith({
74
+ id: "page-1#0002"
75
+ });
76
+ expect(confirm).not.toHaveBeenCalled();
77
+ });
78
+ it("on the server refusal cancels only that revision's reviews, then repeats the delete (R235)", async ()=>{
79
+ const { decoratee, useCases, useCase } = setup();
80
+ decoratee.execute.mockRejectedValueOnce(createRefusal()).mockResolvedValueOnce(true);
81
+ const result = await useCase.execute({
82
+ id: "page-1#0002"
83
+ });
84
+ expect(result).toBe(true);
85
+ expect(useCases.cancelReviewsForDelete.execute).toHaveBeenCalledTimes(1);
86
+ expect(useCases.cancelReviewsForDelete.execute).toHaveBeenCalledWith({
87
+ namespace: "wb.page",
88
+ targetId: "page-1",
89
+ targetRevisionId: "page-1#0002",
90
+ action: "delete"
91
+ });
92
+ expect(decoratee.execute).toHaveBeenCalledTimes(2);
93
+ });
94
+ it("resolves false when the warning is dismissed", async ()=>{
95
+ const { decoratee, useCases, useCase } = setup("dismiss");
96
+ decoratee.execute.mockRejectedValue(createRefusal());
97
+ const result = await useCase.execute({
98
+ id: "page-1#0002"
99
+ });
100
+ expect(result).toBe(false);
101
+ expect(useCases.cancelReviewsForDelete.execute).not.toHaveBeenCalled();
102
+ });
103
+ it("rethrows any other error unchanged", async ()=>{
104
+ const { decoratee, useCase } = setup();
105
+ const failure = new Error("Network down");
106
+ decoratee.execute.mockRejectedValue(failure);
107
+ const error = await useCase.execute({
108
+ id: "page-1#0002"
109
+ }).catch((e)=>e);
110
+ expect(error).toBe(failure);
111
+ });
112
+ });
113
+
114
+ //# sourceMappingURL=DeletePageRevisionUseCaseReviewDecorator.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/trash/DeletePageRevisionUseCaseReviewDecorator.test.js","sources":["../../../src/features/trash/DeletePageRevisionUseCaseReviewDecorator.test.ts"],"sourcesContent":["import { describe } from \"vitest\";\nimport { expect } from \"vitest\";\nimport { it } from \"vitest\";\nimport { vi } from \"vitest\";\nimport { Container } from \"@webiny/di\";\nimport { GraphQLOperationError } from \"@webiny/app/errors/index.js\";\nimport { Confirmation } from \"@webiny/app-admin/features/confirmation/abstractions.js\";\nimport { Notifications } from \"@webiny/app-admin/features/notifications/abstractions.js\";\nimport { DeletePageRevisionUseCase } from \"@webiny/app-website-builder/features/pages/deletePageRevision/abstractions.js\";\nimport { ReviewErrorCode } from \"@webiny/app-workflows/review/domain/ReviewErrorCode.js\";\nimport { ActiveReviewBlockCollector } from \"@webiny/app-workflows/review/trash/ActiveReviewBlockCollector/ActiveReviewBlockCollector.js\";\nimport { ActiveReviewGuard } from \"@webiny/app-workflows/review/trash/ActiveReviewGuard/ActiveReviewGuard.js\";\nimport { createTrashUseCaseFakes } from \"@webiny/app-workflows/review/testing/createTrashUseCaseFakes.js\";\nimport { registerTrashUseCaseFakes } from \"@webiny/app-workflows/review/testing/registerTrashUseCaseFakes.js\";\nimport { DeletePageRevisionUseCaseReviewDecorator } from \"./DeletePageRevisionUseCaseReviewDecorator.js\";\n\nfunction createRefusal() {\n return new GraphQLOperationError({\n message: \"This content has a review in progress.\",\n code: ReviewErrorCode.ActiveReviewOnTrash,\n data: {\n model: \"wb.page\",\n action: \"delete\",\n reviews: [\n {\n reviewId: \"review-2\",\n model: \"wb.page\",\n targetId: \"page-1\",\n targetRevisionId: \"page-1#0002\",\n title: \"Home page\",\n stepPosition: 2,\n stepCount: 2,\n stepName: \"Legal\"\n }\n ]\n }\n });\n}\n\nfunction setup(decision: \"confirm\" | \"dismiss\" = \"confirm\") {\n const confirm = vi.fn(\n async (_name: string, _params: unknown, execute?: (data: unknown) => Promise<unknown>) => {\n if (decision === \"dismiss\") {\n return false;\n }\n return execute ? execute(undefined) : undefined;\n }\n );\n const decoratee = { execute: vi.fn() };\n const useCases = createTrashUseCaseFakes();\n\n const container = new Container();\n container.registerInstance(Confirmation, { confirm } as unknown as Confirmation.Interface);\n container.registerInstance(Notifications, {\n notify: vi.fn(),\n success: vi.fn(),\n warning: vi.fn()\n } as unknown as Notifications.Interface);\n container.register(ActiveReviewBlockCollector).inSingletonScope();\n container.register(ActiveReviewGuard).inSingletonScope();\n registerTrashUseCaseFakes(container, useCases);\n container.registerInstance(DeletePageRevisionUseCase, decoratee);\n container.registerDecorator(DeletePageRevisionUseCaseReviewDecorator);\n\n return {\n confirm,\n decoratee,\n useCases,\n useCase: container.resolve(DeletePageRevisionUseCase)\n };\n}\n\ndescribe(\"DeletePageRevisionUseCaseReviewDecorator\", () => {\n it(\"passes through to the decoratee when the delete succeeds\", async () => {\n const { confirm, decoratee, useCase } = setup();\n decoratee.execute.mockResolvedValue(true);\n\n const result = await useCase.execute({ id: \"page-1#0002\" });\n\n expect(result).toBe(true);\n expect(decoratee.execute).toHaveBeenCalledWith({ id: \"page-1#0002\" });\n expect(confirm).not.toHaveBeenCalled();\n });\n\n it(\"on the server refusal cancels only that revision's reviews, then repeats the delete (R235)\", async () => {\n const { decoratee, useCases, useCase } = setup();\n decoratee.execute.mockRejectedValueOnce(createRefusal()).mockResolvedValueOnce(true);\n\n const result = await useCase.execute({ id: \"page-1#0002\" });\n\n expect(result).toBe(true);\n expect(useCases.cancelReviewsForDelete.execute).toHaveBeenCalledTimes(1);\n expect(useCases.cancelReviewsForDelete.execute).toHaveBeenCalledWith({\n namespace: \"wb.page\",\n targetId: \"page-1\",\n targetRevisionId: \"page-1#0002\",\n action: \"delete\"\n });\n expect(decoratee.execute).toHaveBeenCalledTimes(2);\n });\n\n it(\"resolves false when the warning is dismissed\", async () => {\n const { decoratee, useCases, useCase } = setup(\"dismiss\");\n decoratee.execute.mockRejectedValue(createRefusal());\n\n const result = await useCase.execute({ id: \"page-1#0002\" });\n\n expect(result).toBe(false);\n expect(useCases.cancelReviewsForDelete.execute).not.toHaveBeenCalled();\n });\n\n it(\"rethrows any other error unchanged\", async () => {\n const { decoratee, useCase } = setup();\n const failure = new Error(\"Network down\");\n decoratee.execute.mockRejectedValue(failure);\n\n const error = await useCase.execute({ id: \"page-1#0002\" }).catch(e => e);\n\n expect(error).toBe(failure);\n });\n});\n"],"names":["createRefusal","GraphQLOperationError","ReviewErrorCode","setup","decision","confirm","vi","_name","_params","execute","undefined","decoratee","useCases","createTrashUseCaseFakes","container","Container","Confirmation","Notifications","ActiveReviewBlockCollector","ActiveReviewGuard","registerTrashUseCaseFakes","DeletePageRevisionUseCase","DeletePageRevisionUseCaseReviewDecorator","describe","it","useCase","result","expect","failure","Error","error","e"],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { DeletePageUseCase } from "@webiny/app-website-builder/features/pages/deletePage/abstractions.js";
2
+ import type { DeletePageParams } from "@webiny/app-website-builder/features/pages/deletePage/abstractions.js";
3
+ import { ActiveReviewGuard } from "@webiny/app-workflows/review/trash/ActiveReviewGuard/abstractions.js";
4
+ declare class DeletePageUseCaseReviewDecoratorImpl implements DeletePageUseCase.Interface {
5
+ private guard;
6
+ private decoratee;
7
+ constructor(guard: ActiveReviewGuard.Interface, decoratee: DeletePageUseCase.Interface);
8
+ execute(params: DeletePageParams): Promise<boolean>;
9
+ }
10
+ export declare const DeletePageUseCaseReviewDecorator: typeof DeletePageUseCaseReviewDecoratorImpl & {
11
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/app-website-builder/features/pages/deletePage/abstractions.js").IDeletePageUseCase>;
12
+ };
13
+ export {};
@@ -0,0 +1,23 @@
1
+ import { DeletePageUseCase } from "@webiny/app-website-builder/features/pages/deletePage/abstractions.js";
2
+ import { ActiveReviewGuard } from "@webiny/app-workflows/review/trash/ActiveReviewGuard/abstractions.js";
3
+ class DeletePageUseCaseReviewDecoratorImpl {
4
+ constructor(guard, decoratee){
5
+ this.guard = guard;
6
+ this.decoratee = decoratee;
7
+ }
8
+ async execute(params) {
9
+ return this.guard.run({
10
+ action: ()=>this.decoratee.execute(params),
11
+ revisionId: null
12
+ });
13
+ }
14
+ }
15
+ const DeletePageUseCaseReviewDecorator = DeletePageUseCase.createDecorator({
16
+ decorator: DeletePageUseCaseReviewDecoratorImpl,
17
+ dependencies: [
18
+ ActiveReviewGuard
19
+ ]
20
+ });
21
+ export { DeletePageUseCaseReviewDecorator };
22
+
23
+ //# sourceMappingURL=DeletePageUseCaseReviewDecorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/trash/DeletePageUseCaseReviewDecorator.js","sources":["../../../src/features/trash/DeletePageUseCaseReviewDecorator.ts"],"sourcesContent":["import { DeletePageUseCase } from \"@webiny/app-website-builder/features/pages/deletePage/abstractions.js\";\nimport type { DeletePageParams } from \"@webiny/app-website-builder/features/pages/deletePage/abstractions.js\";\nimport { ActiveReviewGuard } from \"@webiny/app-workflows/review/trash/ActiveReviewGuard/abstractions.js\";\n\nclass DeletePageUseCaseReviewDecoratorImpl implements DeletePageUseCase.Interface {\n constructor(\n private guard: ActiveReviewGuard.Interface,\n private decoratee: DeletePageUseCase.Interface\n ) {}\n\n async execute(params: DeletePageParams): Promise<boolean> {\n return this.guard.run({\n action: () => this.decoratee.execute(params),\n revisionId: null\n });\n }\n}\n\nexport const DeletePageUseCaseReviewDecorator = DeletePageUseCase.createDecorator({\n decorator: DeletePageUseCaseReviewDecoratorImpl,\n dependencies: [ActiveReviewGuard]\n});\n"],"names":["DeletePageUseCaseReviewDecoratorImpl","guard","decoratee","params","DeletePageUseCaseReviewDecorator","DeletePageUseCase","ActiveReviewGuard"],"mappings":";;AAIA,MAAMA;IACF,YACYC,KAAkC,EAClCC,SAAsC,CAChD;aAFUD,KAAK,GAALA;aACAC,SAAS,GAATA;IACT;IAEH,MAAM,QAAQC,MAAwB,EAAoB;QACtD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;YAClB,QAAQ,IAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAACA;YACrC,YAAY;QAChB;IACJ;AACJ;AAEO,MAAMC,mCAAmCC,kBAAkB,eAAe,CAAC;IAC9E,WAAWL;IACX,cAAc;QAACM;KAAkB;AACrC"}
@@ -0,0 +1,134 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { Container } from "@webiny/di";
3
+ import { GraphQLOperationError } from "@webiny/app/errors/index.js";
4
+ import { Confirmation } from "@webiny/app-admin/features/confirmation/abstractions.js";
5
+ import { Notifications } from "@webiny/app-admin/features/notifications/abstractions.js";
6
+ import { DeletePageUseCase } from "@webiny/app-website-builder/features/pages/deletePage/abstractions.js";
7
+ import { ReviewErrorCode } from "@webiny/app-workflows/review/domain/ReviewErrorCode.js";
8
+ import { ActiveReviewBlockCollector } from "@webiny/app-workflows/review/trash/ActiveReviewBlockCollector/ActiveReviewBlockCollector.js";
9
+ import { ActiveReviewGuard } from "@webiny/app-workflows/review/trash/ActiveReviewGuard/ActiveReviewGuard.js";
10
+ import { createTrashUseCaseFakes } from "@webiny/app-workflows/review/testing/createTrashUseCaseFakes.js";
11
+ import { registerTrashUseCaseFakes } from "@webiny/app-workflows/review/testing/registerTrashUseCaseFakes.js";
12
+ import { DeletePageUseCaseReviewDecorator } from "./DeletePageUseCaseReviewDecorator.js";
13
+ function createRefusal() {
14
+ return new GraphQLOperationError({
15
+ message: "This content has a review in progress.",
16
+ code: ReviewErrorCode.ActiveReviewOnTrash,
17
+ data: {
18
+ model: "wb.page",
19
+ action: "trash",
20
+ reviews: [
21
+ {
22
+ reviewId: "review-1",
23
+ model: "wb.page",
24
+ targetId: "page-1",
25
+ targetRevisionId: "page-1#0002",
26
+ title: "Home page",
27
+ stepPosition: 1,
28
+ stepCount: 2,
29
+ stepName: "Editor"
30
+ }
31
+ ]
32
+ }
33
+ });
34
+ }
35
+ function setup(decision = "confirm") {
36
+ const confirm = vi.fn(async (_name, _params, execute)=>{
37
+ if ("dismiss" === decision) return false;
38
+ return execute ? execute(void 0) : void 0;
39
+ });
40
+ const decoratee = {
41
+ execute: vi.fn()
42
+ };
43
+ const useCases = createTrashUseCaseFakes();
44
+ const container = new Container();
45
+ container.registerInstance(Confirmation, {
46
+ confirm
47
+ });
48
+ container.registerInstance(Notifications, {
49
+ notify: vi.fn(),
50
+ success: vi.fn(),
51
+ warning: vi.fn()
52
+ });
53
+ container.register(ActiveReviewBlockCollector).inSingletonScope();
54
+ container.register(ActiveReviewGuard).inSingletonScope();
55
+ registerTrashUseCaseFakes(container, useCases);
56
+ container.registerInstance(DeletePageUseCase, decoratee);
57
+ container.registerDecorator(DeletePageUseCaseReviewDecorator);
58
+ return {
59
+ confirm,
60
+ decoratee,
61
+ useCases,
62
+ useCase: container.resolve(DeletePageUseCase)
63
+ };
64
+ }
65
+ describe("DeletePageUseCaseReviewDecorator", ()=>{
66
+ it("passes through to the decoratee when the trash succeeds", async ()=>{
67
+ const { confirm, decoratee, useCases, useCase } = setup();
68
+ decoratee.execute.mockResolvedValue(true);
69
+ const result = await useCase.execute({
70
+ id: "page-1#0002",
71
+ permanently: false
72
+ });
73
+ expect(result).toBe(true);
74
+ expect(decoratee.execute).toHaveBeenCalledWith({
75
+ id: "page-1#0002",
76
+ permanently: false
77
+ });
78
+ expect(confirm).not.toHaveBeenCalled();
79
+ expect(useCases.cancelReviewsForDelete.execute).not.toHaveBeenCalled();
80
+ });
81
+ it("on the server refusal warns, cancels every revision of the page once and repeats the trash", async ()=>{
82
+ const { confirm, decoratee, useCases, useCase } = setup();
83
+ decoratee.execute.mockRejectedValueOnce(createRefusal()).mockResolvedValueOnce(true);
84
+ const result = await useCase.execute({
85
+ id: "page-1#0002",
86
+ permanently: false
87
+ });
88
+ expect(result).toBe(true);
89
+ expect(confirm).toHaveBeenCalledTimes(1);
90
+ expect(useCases.cancelReviewsForDelete.execute).toHaveBeenCalledTimes(1);
91
+ expect(useCases.cancelReviewsForDelete.execute).toHaveBeenCalledWith({
92
+ namespace: "wb.page",
93
+ targetId: "page-1",
94
+ targetRevisionId: null,
95
+ action: "trash"
96
+ });
97
+ expect(decoratee.execute).toHaveBeenCalledTimes(2);
98
+ });
99
+ it("resolves false when the warning is dismissed, with nothing cancelled or repeated", async ()=>{
100
+ const { decoratee, useCases, useCase } = setup("dismiss");
101
+ decoratee.execute.mockRejectedValue(createRefusal());
102
+ const result = await useCase.execute({
103
+ id: "page-1#0002",
104
+ permanently: false
105
+ });
106
+ expect(result).toBe(false);
107
+ expect(useCases.cancelReviewsForDelete.execute).not.toHaveBeenCalled();
108
+ expect(decoratee.execute).toHaveBeenCalledTimes(1);
109
+ });
110
+ it("rethrows any other error unchanged", async ()=>{
111
+ const { confirm, decoratee, useCase } = setup();
112
+ const failure = new Error("Network down");
113
+ decoratee.execute.mockRejectedValue(failure);
114
+ const error = await useCase.execute({
115
+ id: "page-1#0002",
116
+ permanently: false
117
+ }).catch((e)=>e);
118
+ expect(error).toBe(failure);
119
+ expect(confirm).not.toHaveBeenCalled();
120
+ });
121
+ it("propagates a second refusal after the repeat", async ()=>{
122
+ const { confirm, decoratee, useCase } = setup();
123
+ const second = createRefusal();
124
+ decoratee.execute.mockRejectedValueOnce(createRefusal()).mockRejectedValueOnce(second);
125
+ const error = await useCase.execute({
126
+ id: "page-1#0002",
127
+ permanently: false
128
+ }).catch((e)=>e);
129
+ expect(error).toBe(second);
130
+ expect(confirm).toHaveBeenCalledTimes(1);
131
+ });
132
+ });
133
+
134
+ //# sourceMappingURL=DeletePageUseCaseReviewDecorator.test.js.map