@webiny/app-headless-cms-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.
- package/Components/CmsEntriesList/CmsReviewMoveEntryAction.d.ts +2 -0
- package/Components/CmsEntriesList/CmsReviewMoveEntryAction.js +43 -0
- package/Components/CmsEntriesList/CmsReviewMoveEntryAction.js.map +1 -0
- package/Components/CmsEntriesList/CmsReviewMoveEntryAction.test.d.ts +1 -0
- package/Components/CmsEntriesList/CmsReviewMoveEntryAction.test.js +118 -0
- package/Components/CmsEntriesList/CmsReviewMoveEntryAction.test.js.map +1 -0
- package/Components/CmsEntriesList/CmsReviewScheduleEntryAction.d.ts +2 -0
- package/Components/CmsEntriesList/CmsReviewScheduleEntryAction.js +22 -0
- package/Components/CmsEntriesList/CmsReviewScheduleEntryAction.js.map +1 -0
- package/Components/CmsEntriesList/CmsReviewScheduleEntryAction.test.d.ts +1 -0
- package/Components/CmsEntriesList/CmsReviewScheduleEntryAction.test.js +98 -0
- package/Components/CmsEntriesList/CmsReviewScheduleEntryAction.test.js.map +1 -0
- package/Components/ContentEntryForm/CmsEntryReviewBar.d.ts +2 -0
- package/Components/ContentEntryForm/CmsEntryReviewBar.js +32 -0
- package/Components/ContentEntryForm/CmsEntryReviewBar.js.map +1 -0
- package/Components/ContentEntryForm/CmsEntryReviewBar.test.d.ts +1 -0
- package/Components/ContentEntryForm/CmsEntryReviewBar.test.js +128 -0
- package/Components/ContentEntryForm/CmsEntryReviewBar.test.js.map +1 -0
- package/Components/ContentEntryForm/CmsEntryReviewBlockedActions.d.ts +2 -0
- package/Components/ContentEntryForm/CmsEntryReviewBlockedActions.js +46 -0
- package/Components/ContentEntryForm/CmsEntryReviewBlockedActions.js.map +1 -0
- package/Components/ContentEntryForm/CmsEntryReviewBlockedActions.test.d.ts +1 -0
- package/Components/ContentEntryForm/CmsEntryReviewBlockedActions.test.js +222 -0
- package/Components/ContentEntryForm/CmsEntryReviewBlockedActions.test.js.map +1 -0
- package/Components/ContentEntryForm/CmsEntryReviewFormLock.d.ts +2 -0
- package/Components/ContentEntryForm/CmsEntryReviewFormLock.js +32 -0
- package/Components/ContentEntryForm/CmsEntryReviewFormLock.js.map +1 -0
- package/Components/ContentEntryForm/CmsEntryReviewFormLock.test.d.ts +1 -0
- package/Components/ContentEntryForm/CmsEntryReviewFormLock.test.js +94 -0
- package/Components/ContentEntryForm/CmsEntryReviewFormLock.test.js.map +1 -0
- package/Components/ContentEntryForm/CmsEntryReviewNewRevision.d.ts +2 -0
- package/Components/ContentEntryForm/CmsEntryReviewNewRevision.js +56 -0
- package/Components/ContentEntryForm/CmsEntryReviewNewRevision.js.map +1 -0
- package/Components/ContentEntryForm/CmsEntryReviewNewRevision.test.d.ts +1 -0
- package/Components/ContentEntryForm/CmsEntryReviewNewRevision.test.js +186 -0
- package/Components/ContentEntryForm/CmsEntryReviewNewRevision.test.js.map +1 -0
- package/Components/ContentEntryForm/CmsEntryReviewScheduleMenuItem.d.ts +2 -0
- package/Components/ContentEntryForm/CmsEntryReviewScheduleMenuItem.js +26 -0
- package/Components/ContentEntryForm/CmsEntryReviewScheduleMenuItem.js.map +1 -0
- package/Components/ContentEntryForm/CmsEntryReviewScheduleMenuItem.test.d.ts +1 -0
- package/Components/ContentEntryForm/CmsEntryReviewScheduleMenuItem.test.js +78 -0
- package/Components/ContentEntryForm/CmsEntryReviewScheduleMenuItem.test.js.map +1 -0
- package/Components/ContentEntryForm/getModelFieldLabels.d.ts +3 -0
- package/Components/ContentEntryForm/getModelFieldLabels.js +8 -0
- package/Components/ContentEntryForm/getModelFieldLabels.js.map +1 -0
- package/Components/ContentEntryForm/index.d.ts +5 -0
- package/Components/ContentEntryForm/index.js +5 -0
- package/Components/ContentReviews/CmsContentReviews.d.ts +2 -0
- package/Components/ContentReviews/CmsContentReviews.js +11 -0
- package/Components/ContentReviews/CmsContentReviews.js.map +1 -0
- package/Components/ContentReviews/CmsContentReviews.test.d.ts +1 -0
- package/Components/ContentReviews/CmsContentReviews.test.js +214 -0
- package/Components/ContentReviews/CmsContentReviews.test.js.map +1 -0
- package/Components/ContentReviews/CmsContentReviewsMount.d.ts +4 -0
- package/Components/ContentReviews/CmsContentReviewsMount.js +44 -0
- package/Components/ContentReviews/CmsContentReviewsMount.js.map +1 -0
- package/Components/ContentReviews/CmsContentReviewsSidebarItem.d.ts +2 -0
- package/Components/ContentReviews/CmsContentReviewsSidebarItem.js +20 -0
- package/Components/ContentReviews/CmsContentReviewsSidebarItem.js.map +1 -0
- package/Components/ContentReviews/CmsContentReviewsSidebarItem.test.d.ts +1 -0
- package/Components/ContentReviews/CmsContentReviewsSidebarItem.test.js +83 -0
- package/Components/ContentReviews/CmsContentReviewsSidebarItem.test.js.map +1 -0
- package/Components/ModelDelete/ModelBoundToWorkflowErrorData.d.ts +8 -0
- package/Components/ModelDelete/ModelBoundToWorkflowErrorData.js +0 -0
- package/Components/ModelDelete/ModelDeleteWorkflowCopy.d.ts +10 -0
- package/Components/ModelDelete/ModelDeleteWorkflowCopy.js +0 -0
- package/Components/ModelDelete/ModelDeleteWorkflowError.d.ts +2 -0
- package/Components/ModelDelete/ModelDeleteWorkflowError.js +34 -0
- package/Components/ModelDelete/ModelDeleteWorkflowError.js.map +1 -0
- package/Components/ModelDelete/ModelDeleteWorkflowError.test.d.ts +1 -0
- package/Components/ModelDelete/ModelDeleteWorkflowError.test.js +73 -0
- package/Components/ModelDelete/ModelDeleteWorkflowError.test.js.map +1 -0
- package/Components/ModelDelete/getModelDeleteWorkflowCopy.d.ts +3 -0
- package/Components/ModelDelete/getModelDeleteWorkflowCopy.js +17 -0
- package/Components/ModelDelete/getModelDeleteWorkflowCopy.js.map +1 -0
- package/Components/ModelDelete/getModelDeleteWorkflowCopy.test.d.ts +1 -0
- package/Components/ModelDelete/getModelDeleteWorkflowCopy.test.js +28 -0
- package/Components/ModelDelete/getModelDeleteWorkflowCopy.test.js.map +1 -0
- package/Components/ignoreAction.d.ts +1 -0
- package/Components/ignoreAction.js +4 -0
- package/Components/ignoreAction.js.map +1 -0
- package/LICENSE +21 -0
- package/README.md +11 -0
- package/Routes/CmsWorkflowEditor.d.ts +2 -0
- package/Routes/CmsWorkflowEditor.js +23 -0
- package/Routes/CmsWorkflowEditor.js.map +1 -0
- package/Routes/CmsWorkflowEditor.test.d.ts +1 -0
- package/Routes/CmsWorkflowEditor.test.js +141 -0
- package/Routes/CmsWorkflowEditor.test.js.map +1 -0
- package/Routes/index.d.ts +1 -0
- package/Routes/index.js +1 -0
- package/features/cache/CmsReviewCacheSyncHandler.d.ts +8 -0
- package/features/cache/CmsReviewCacheSyncHandler.js +14 -0
- package/features/cache/CmsReviewCacheSyncHandler.js.map +1 -0
- package/features/cache/CmsReviewCacheWriter.d.ts +14 -0
- package/features/cache/CmsReviewCacheWriter.js +39 -0
- package/features/cache/CmsReviewCacheWriter.js.map +1 -0
- package/features/cache/CmsReviewCacheWriter.test.d.ts +1 -0
- package/features/cache/CmsReviewCacheWriter.test.js +207 -0
- package/features/cache/CmsReviewCacheWriter.test.js.map +1 -0
- package/features/cache/CmsReviewEntriesCacheProviderDecorator.d.ts +12 -0
- package/features/cache/CmsReviewEntriesCacheProviderDecorator.js +17 -0
- package/features/cache/CmsReviewEntriesCacheProviderDecorator.js.map +1 -0
- package/features/cache/CmsReviewEntriesCacheProviderDecorator.test.d.ts +1 -0
- package/features/cache/CmsReviewEntriesCacheProviderDecorator.test.js +129 -0
- package/features/cache/CmsReviewEntriesCacheProviderDecorator.test.js.map +1 -0
- package/features/cache/ReviewPreservingEntriesCache.d.ts +18 -0
- package/features/cache/ReviewPreservingEntriesCache.js +54 -0
- package/features/cache/ReviewPreservingEntriesCache.js.map +1 -0
- package/features/cache/abstractions.d.ts +5 -0
- package/features/cache/abstractions.js +5 -0
- package/features/cache/abstractions.js.map +1 -0
- package/features/editorGateway/CmsWorkflowEditorGateway/CmsWorkflowEditorGateway.d.ts +26 -0
- package/features/editorGateway/CmsWorkflowEditorGateway/CmsWorkflowEditorGateway.js +104 -0
- package/features/editorGateway/CmsWorkflowEditorGateway/CmsWorkflowEditorGateway.js.map +1 -0
- package/features/editorGateway/CmsWorkflowEditorGateway/CmsWorkflowEditorGateway.test.d.ts +1 -0
- package/features/editorGateway/CmsWorkflowEditorGateway/CmsWorkflowEditorGateway.test.js +589 -0
- package/features/editorGateway/CmsWorkflowEditorGateway/CmsWorkflowEditorGateway.test.js.map +1 -0
- package/features/editorGateway/feature.d.ts +1 -0
- package/features/editorGateway/feature.js +11 -0
- package/features/editorGateway/feature.js.map +1 -0
- package/features/editorGateway/feature.test.d.ts +1 -0
- package/features/editorGateway/feature.test.js +272 -0
- package/features/editorGateway/feature.test.js.map +1 -0
- package/features/editorGateway/graphql/cmsEntryFolderExists.d.ts +1 -0
- package/features/editorGateway/graphql/cmsEntryFolderExists.js +16 -0
- package/features/editorGateway/graphql/cmsEntryFolderExists.js.map +1 -0
- package/features/editorGateway/graphql/deleteCmsEntryWorkflow.d.ts +1 -0
- package/features/editorGateway/graphql/deleteCmsEntryWorkflow.js +19 -0
- package/features/editorGateway/graphql/deleteCmsEntryWorkflow.js.map +1 -0
- package/features/editorGateway/graphql/getCmsEntryWorkflow.d.ts +1 -0
- package/features/editorGateway/graphql/getCmsEntryWorkflow.js +19 -0
- package/features/editorGateway/graphql/getCmsEntryWorkflow.js.map +1 -0
- package/features/editorGateway/graphql/inspectCmsEntryRouting.d.ts +1 -0
- package/features/editorGateway/graphql/inspectCmsEntryRouting.js +19 -0
- package/features/editorGateway/graphql/inspectCmsEntryRouting.js.map +1 -0
- package/features/editorGateway/graphql/listCmsEntryWorkflowModels.d.ts +1 -0
- package/features/editorGateway/graphql/listCmsEntryWorkflowModels.js +29 -0
- package/features/editorGateway/graphql/listCmsEntryWorkflowModels.js.map +1 -0
- package/features/editorGateway/graphql/storeCmsEntryWorkflow.d.ts +1 -0
- package/features/editorGateway/graphql/storeCmsEntryWorkflow.js +19 -0
- package/features/editorGateway/graphql/storeCmsEntryWorkflow.js.map +1 -0
- package/features/editorMounting/CmsWorkflowEditorAppAdapter.d.ts +25 -0
- package/features/editorMounting/CmsWorkflowEditorAppAdapter.js +51 -0
- package/features/editorMounting/CmsWorkflowEditorAppAdapter.js.map +1 -0
- package/features/editorMounting/CmsWorkflowEditorAppAdapter.test.d.ts +1 -0
- package/features/editorMounting/CmsWorkflowEditorAppAdapter.test.js +185 -0
- package/features/editorMounting/CmsWorkflowEditorAppAdapter.test.js.map +1 -0
- package/features/editorMounting/abstractions.d.ts +5 -0
- package/features/editorMounting/abstractions.js +5 -0
- package/features/editorMounting/abstractions.js.map +1 -0
- package/features/editorMounting/feature.d.ts +3 -0
- package/features/editorMounting/feature.js +19 -0
- package/features/editorMounting/feature.js.map +1 -0
- package/features/editorMounting/feature.test.d.ts +1 -0
- package/features/editorMounting/feature.test.js +100 -0
- package/features/editorMounting/feature.test.js.map +1 -0
- package/features/editorReview/CmsEntryReview.d.ts +8 -0
- package/features/editorReview/CmsEntryReview.js +14 -0
- package/features/editorReview/CmsEntryReview.js.map +1 -0
- package/features/editorReview/abstractions.d.ts +5 -0
- package/features/editorReview/abstractions.js +5 -0
- package/features/editorReview/abstractions.js.map +1 -0
- package/features/editorReview/feature.d.ts +3 -0
- package/features/editorReview/feature.js +17 -0
- package/features/editorReview/feature.js.map +1 -0
- package/features/editorReview/feature.test.d.ts +1 -0
- package/features/editorReview/feature.test.js +46 -0
- package/features/editorReview/feature.test.js.map +1 -0
- package/features/editorReview/useCmsEntryReview.d.ts +2 -0
- package/features/editorReview/useCmsEntryReview.js +8 -0
- package/features/editorReview/useCmsEntryReview.js.map +1 -0
- package/features/feature.d.ts +1 -0
- package/features/feature.js +15 -0
- package/features/feature.js.map +1 -0
- package/features/gateway/CmsReviewChangeMessageHandler.d.ts +8 -0
- package/features/gateway/CmsReviewChangeMessageHandler.js +16 -0
- package/features/gateway/CmsReviewChangeMessageHandler.js.map +1 -0
- package/features/gateway/CmsReviewContentAdapter/CmsReviewContentAdapter.d.ts +16 -0
- package/features/gateway/CmsReviewContentAdapter/CmsReviewContentAdapter.js +39 -0
- package/features/gateway/CmsReviewContentAdapter/CmsReviewContentAdapter.js.map +1 -0
- package/features/gateway/CmsReviewContentAdapter/CmsReviewContentAdapter.test.d.ts +1 -0
- package/features/gateway/CmsReviewContentAdapter/CmsReviewContentAdapter.test.js +83 -0
- package/features/gateway/CmsReviewContentAdapter/CmsReviewContentAdapter.test.js.map +1 -0
- package/features/gateway/CmsReviewContentAdapter/abstractions.d.ts +5 -0
- package/features/gateway/CmsReviewContentAdapter/abstractions.js +5 -0
- package/features/gateway/CmsReviewContentAdapter/abstractions.js.map +1 -0
- package/features/gateway/CmsReviewGateway/CmsReviewGateway.d.ts +52 -0
- package/features/gateway/CmsReviewGateway/CmsReviewGateway.js +221 -0
- package/features/gateway/CmsReviewGateway/CmsReviewGateway.js.map +1 -0
- package/features/gateway/CmsReviewGateway/CmsReviewGateway.test.d.ts +1 -0
- package/features/gateway/CmsReviewGateway/CmsReviewGateway.test.js +689 -0
- package/features/gateway/CmsReviewGateway/CmsReviewGateway.test.js.map +1 -0
- package/features/gateway/CmsReviewNotificationHandler.d.ts +8 -0
- package/features/gateway/CmsReviewNotificationHandler.js +16 -0
- package/features/gateway/CmsReviewNotificationHandler.js.map +1 -0
- package/features/gateway/CmsReviewRowProvider/CmsReviewRowProvider.d.ts +8 -0
- package/features/gateway/CmsReviewRowProvider/CmsReviewRowProvider.js +14 -0
- package/features/gateway/CmsReviewRowProvider/CmsReviewRowProvider.js.map +1 -0
- package/features/gateway/CmsReviewRowProvider/abstractions.d.ts +5 -0
- package/features/gateway/CmsReviewRowProvider/abstractions.js +5 -0
- package/features/gateway/CmsReviewRowProvider/abstractions.js.map +1 -0
- package/features/gateway/contentReviewsBindings.test.d.ts +1 -0
- package/features/gateway/contentReviewsBindings.test.js +125 -0
- package/features/gateway/contentReviewsBindings.test.js.map +1 -0
- package/features/gateway/feature.d.ts +4 -0
- package/features/gateway/feature.js +27 -0
- package/features/gateway/feature.js.map +1 -0
- package/features/gateway/feature.test.d.ts +1 -0
- package/features/gateway/feature.test.js +79 -0
- package/features/gateway/feature.test.js.map +1 -0
- package/features/gateway/graphql/CmsOperationResponse.d.ts +3 -0
- package/features/gateway/graphql/CmsOperationResponse.js +0 -0
- package/features/gateway/graphql/approveCmsEntryReviewStep.d.ts +1 -0
- package/features/gateway/graphql/approveCmsEntryReviewStep.js +18 -0
- package/features/gateway/graphql/approveCmsEntryReviewStep.js.map +1 -0
- package/features/gateway/graphql/cancelCmsEntryReview.d.ts +1 -0
- package/features/gateway/graphql/cancelCmsEntryReview.js +18 -0
- package/features/gateway/graphql/cancelCmsEntryReview.js.map +1 -0
- package/features/gateway/graphql/cancelCmsEntryReviewsForDelete.d.ts +1 -0
- package/features/gateway/graphql/cancelCmsEntryReviewsForDelete.js +28 -0
- package/features/gateway/graphql/cancelCmsEntryReviewsForDelete.js.map +1 -0
- package/features/gateway/graphql/getCmsEntryReview.d.ts +1 -0
- package/features/gateway/graphql/getCmsEntryReview.js +18 -0
- package/features/gateway/graphql/getCmsEntryReview.js.map +1 -0
- package/features/gateway/graphql/getCmsEntryReviewStepRun.d.ts +1 -0
- package/features/gateway/graphql/getCmsEntryReviewStepRun.js +18 -0
- package/features/gateway/graphql/getCmsEntryReviewStepRun.js.map +1 -0
- package/features/gateway/graphql/getCmsEntryTargetReview.d.ts +1 -0
- package/features/gateway/graphql/getCmsEntryTargetReview.js +18 -0
- package/features/gateway/graphql/getCmsEntryTargetReview.js.map +1 -0
- package/features/gateway/graphql/listCmsEntryBlockingReviews.d.ts +1 -0
- package/features/gateway/graphql/listCmsEntryBlockingReviews.js +18 -0
- package/features/gateway/graphql/listCmsEntryBlockingReviews.js.map +1 -0
- package/features/gateway/graphql/listCmsEntryReviewStepCandidates.d.ts +1 -0
- package/features/gateway/graphql/listCmsEntryReviewStepCandidates.js +18 -0
- package/features/gateway/graphql/listCmsEntryReviewStepCandidates.js.map +1 -0
- package/features/gateway/graphql/listCmsEntryReviews.d.ts +1 -0
- package/features/gateway/graphql/listCmsEntryReviews.js +34 -0
- package/features/gateway/graphql/listCmsEntryReviews.js.map +1 -0
- package/features/gateway/graphql/listCmsEntryStepCandidates.d.ts +1 -0
- package/features/gateway/graphql/listCmsEntryStepCandidates.js +28 -0
- package/features/gateway/graphql/listCmsEntryStepCandidates.js.map +1 -0
- package/features/gateway/graphql/listCmsEntryWorkflows.d.ts +1 -0
- package/features/gateway/graphql/listCmsEntryWorkflows.js +18 -0
- package/features/gateway/graphql/listCmsEntryWorkflows.js.map +1 -0
- package/features/gateway/graphql/reassignCmsEntryReviewStep.d.ts +1 -0
- package/features/gateway/graphql/reassignCmsEntryReviewStep.js +18 -0
- package/features/gateway/graphql/reassignCmsEntryReviewStep.js.map +1 -0
- package/features/gateway/graphql/rejectCmsEntryReviewStep.d.ts +1 -0
- package/features/gateway/graphql/rejectCmsEntryReviewStep.js +18 -0
- package/features/gateway/graphql/rejectCmsEntryReviewStep.js.map +1 -0
- package/features/gateway/graphql/requestCmsEntryReview.d.ts +1 -0
- package/features/gateway/graphql/requestCmsEntryReview.js +28 -0
- package/features/gateway/graphql/requestCmsEntryReview.js.map +1 -0
- package/features/gateway/graphql/restartCmsEntryReviewStep.d.ts +1 -0
- package/features/gateway/graphql/restartCmsEntryReviewStep.js +18 -0
- package/features/gateway/graphql/restartCmsEntryReviewStep.js.map +1 -0
- package/features/gateway/graphql/startCmsEntryReviewStep.d.ts +1 -0
- package/features/gateway/graphql/startCmsEntryReviewStep.js +18 -0
- package/features/gateway/graphql/startCmsEntryReviewStep.js.map +1 -0
- package/features/gateway/graphql/takeOverCmsEntryReviewStep.d.ts +1 -0
- package/features/gateway/graphql/takeOverCmsEntryReviewStep.js +22 -0
- package/features/gateway/graphql/takeOverCmsEntryReviewStep.js.map +1 -0
- package/features/trash/BulkDeletePresenterReviewDecorator.d.ts +20 -0
- package/features/trash/BulkDeletePresenterReviewDecorator.js +81 -0
- package/features/trash/BulkDeletePresenterReviewDecorator.js.map +1 -0
- package/features/trash/BulkDeletePresenterReviewDecorator.test.d.ts +1 -0
- package/features/trash/BulkDeletePresenterReviewDecorator.test.js +693 -0
- package/features/trash/BulkDeletePresenterReviewDecorator.test.js.map +1 -0
- package/features/trash/DeleteEntryRevisionUseCaseReviewDecorator.d.ts +13 -0
- package/features/trash/DeleteEntryRevisionUseCaseReviewDecorator.js +23 -0
- package/features/trash/DeleteEntryRevisionUseCaseReviewDecorator.js.map +1 -0
- package/features/trash/DeleteEntryRevisionUseCaseReviewDecorator.test.d.ts +1 -0
- package/features/trash/DeleteEntryRevisionUseCaseReviewDecorator.test.js +123 -0
- package/features/trash/DeleteEntryRevisionUseCaseReviewDecorator.test.js.map +1 -0
- package/features/trash/DeleteEntryUseCaseReviewDecorator.d.ts +13 -0
- package/features/trash/DeleteEntryUseCaseReviewDecorator.js +23 -0
- package/features/trash/DeleteEntryUseCaseReviewDecorator.js.map +1 -0
- package/features/trash/DeleteEntryUseCaseReviewDecorator.test.d.ts +1 -0
- package/features/trash/DeleteEntryUseCaseReviewDecorator.test.js +139 -0
- package/features/trash/DeleteEntryUseCaseReviewDecorator.test.js.map +1 -0
- package/features/trash/PermanentlyDeleteEntryUseCaseReviewDecorator.d.ts +13 -0
- package/features/trash/PermanentlyDeleteEntryUseCaseReviewDecorator.js +23 -0
- package/features/trash/PermanentlyDeleteEntryUseCaseReviewDecorator.js.map +1 -0
- package/features/trash/PermanentlyDeleteEntryUseCaseReviewDecorator.test.d.ts +1 -0
- package/features/trash/PermanentlyDeleteEntryUseCaseReviewDecorator.test.js +122 -0
- package/features/trash/PermanentlyDeleteEntryUseCaseReviewDecorator.test.js.map +1 -0
- package/features/trash/feature.d.ts +1 -0
- package/features/trash/feature.js +17 -0
- package/features/trash/feature.js.map +1 -0
- package/features/trash/feature.test.d.ts +1 -0
- package/features/trash/feature.test.js +213 -0
- package/features/trash/feature.test.js.map +1 -0
- package/index.d.ts +2 -0
- package/index.editor.test.d.ts +1 -0
- package/index.editor.test.js +149 -0
- package/index.editor.test.js.map +1 -0
- package/index.js +41 -0
- package/index.js.map +1 -0
- package/index.lists.test.d.ts +1 -0
- package/index.lists.test.js +172 -0
- package/index.lists.test.js.map +1 -0
- package/index.mount.test.d.ts +1 -0
- package/index.mount.test.js +49 -0
- package/index.mount.test.js.map +1 -0
- package/index.test.d.ts +1 -0
- package/index.test.js +414 -0
- package/index.test.js.map +1 -0
- package/package.json +54 -0
- package/presentation/CmsEntryContentReloader.d.ts +8 -0
- package/presentation/CmsEntryContentReloader.js +20 -0
- package/presentation/CmsEntryContentReloader.js.map +1 -0
- package/presentation/CmsEntryContentReloader.test.d.ts +1 -0
- package/presentation/CmsEntryContentReloader.test.js +118 -0
- package/presentation/CmsEntryContentReloader.test.js.map +1 -0
- package/presentation/CmsEntryFormPresenterReviewDecorator.d.ts +27 -0
- package/presentation/CmsEntryFormPresenterReviewDecorator.js +167 -0
- package/presentation/CmsEntryFormPresenterReviewDecorator.js.map +1 -0
- package/presentation/CmsEntryFormPresenterReviewDecorator.test.d.ts +1 -0
- package/presentation/CmsEntryFormPresenterReviewDecorator.test.js +601 -0
- package/presentation/CmsEntryFormPresenterReviewDecorator.test.js.map +1 -0
- package/presentation/CmsEntryUnsavedChanges.d.ts +7 -0
- package/presentation/CmsEntryUnsavedChanges.js +12 -0
- package/presentation/CmsEntryUnsavedChanges.js.map +1 -0
- package/presentation/CmsEntryUnsavedChanges.test.d.ts +1 -0
- package/presentation/CmsEntryUnsavedChanges.test.js +23 -0
- package/presentation/CmsEntryUnsavedChanges.test.js.map +1 -0
- package/presentation/CmsReviewFieldSelections.test.d.ts +1 -0
- package/presentation/CmsReviewFieldSelections.test.js +27 -0
- package/presentation/CmsReviewFieldSelections.test.js.map +1 -0
- package/presentation/CmsReviewGetEntryFieldSelection.d.ts +8 -0
- package/presentation/CmsReviewGetEntryFieldSelection.js +16 -0
- package/presentation/CmsReviewGetEntryFieldSelection.js.map +1 -0
- package/presentation/CmsReviewListEntriesFieldSelection.d.ts +8 -0
- package/presentation/CmsReviewListEntriesFieldSelection.js +16 -0
- package/presentation/CmsReviewListEntriesFieldSelection.js.map +1 -0
- package/presentation/CmsReviewTableRowMapperDecorator.d.ts +11 -0
- package/presentation/CmsReviewTableRowMapperDecorator.js +24 -0
- package/presentation/CmsReviewTableRowMapperDecorator.js.map +1 -0
- package/presentation/CmsReviewTableRowMapperDecorator.test.d.ts +1 -0
- package/presentation/CmsReviewTableRowMapperDecorator.test.js +120 -0
- package/presentation/CmsReviewTableRowMapperDecorator.test.js.map +1 -0
- package/presentation/CmsRevisionsListPresenterDecorator.d.ts +24 -0
- package/presentation/CmsRevisionsListPresenterDecorator.js +66 -0
- package/presentation/CmsRevisionsListPresenterDecorator.js.map +1 -0
- package/presentation/CmsRevisionsListPresenterDecorator.test.d.ts +1 -0
- package/presentation/CmsRevisionsListPresenterDecorator.test.js +174 -0
- package/presentation/CmsRevisionsListPresenterDecorator.test.js.map +1 -0
- package/presentation/contentReviews/CmsContentReviewsPresenter.d.ts +28 -0
- package/presentation/contentReviews/CmsContentReviewsPresenter.js +103 -0
- package/presentation/contentReviews/CmsContentReviewsPresenter.js.map +1 -0
- package/presentation/contentReviews/CmsContentReviewsPresenter.test.d.ts +1 -0
- package/presentation/contentReviews/CmsContentReviewsPresenter.test.js +238 -0
- package/presentation/contentReviews/CmsContentReviewsPresenter.test.js.map +1 -0
- package/presentation/contentReviews/abstractions.d.ts +31 -0
- package/presentation/contentReviews/abstractions.js +5 -0
- package/presentation/contentReviews/abstractions.js.map +1 -0
- package/presentation/contentReviews/feature.d.ts +3 -0
- package/presentation/contentReviews/feature.js +17 -0
- package/presentation/contentReviews/feature.js.map +1 -0
- package/presentation/contentReviews/toContentTypes.d.ts +3 -0
- package/presentation/contentReviews/toContentTypes.js +14 -0
- package/presentation/contentReviews/toContentTypes.js.map +1 -0
- package/presentation/contentReviews/toContentTypes.test.d.ts +1 -0
- package/presentation/contentReviews/toContentTypes.test.js +20 -0
- package/presentation/contentReviews/toContentTypes.test.js.map +1 -0
- package/presentation/feature.d.ts +1 -0
- package/presentation/feature.js +19 -0
- package/presentation/feature.js.map +1 -0
- package/presentation/getCmsEntryReviewContext.d.ts +4 -0
- package/presentation/getCmsEntryReviewContext.js +12 -0
- package/presentation/getCmsEntryReviewContext.js.map +1 -0
- package/presentation/getCmsEntryReviewInitParams.d.ts +13 -0
- package/presentation/getCmsEntryReviewInitParams.js +18 -0
- package/presentation/getCmsEntryReviewInitParams.js.map +1 -0
- package/presentation/getCmsEntryReviewInitParams.test.d.ts +1 -0
- package/presentation/getCmsEntryReviewInitParams.test.js +69 -0
- package/presentation/getCmsEntryReviewInitParams.test.js.map +1 -0
- package/routes.d.ts +11 -0
- package/routes.js +21 -0
- package/routes.js.map +1 -0
- package/testing/createEntry.d.ts +3 -0
- package/testing/createEntry.js +22 -0
- package/testing/createEntry.js.map +1 -0
- package/testing/createEntrySession.d.ts +9 -0
- package/testing/createEntrySession.js +29 -0
- package/testing/createEntrySession.js.map +1 -0
- package/testing/createFolder.d.ts +2 -0
- package/testing/createFolder.js +13 -0
- package/testing/createFolder.js.map +1 -0
- package/testing/createFormVm.d.ts +2 -0
- package/testing/createFormVm.js +22 -0
- package/testing/createFormVm.js.map +1 -0
- package/testing/models.d.ts +4 -0
- package/testing/models.js +23 -0
- package/testing/models.js.map +1 -0
- package/testing/renderEditorTree.d.ts +17 -0
- package/testing/renderEditorTree.js +93 -0
- package/testing/renderEditorTree.js.map +1 -0
- package/testing/reviewStates.d.ts +17 -0
- package/testing/reviewStates.js +65 -0
- package/testing/reviewStates.js.map +1 -0
- package/types.d.ts +10 -0
- package/types.js +0 -0
- package/utils/appName.d.ts +4 -0
- package/utils/appName.js +13 -0
- package/utils/appName.js.map +1 -0
- package/utils/isReviewableModel.d.ts +2 -0
- package/utils/isReviewableModel.js +7 -0
- package/utils/isReviewableModel.js.map +1 -0
- package/utils/renderModelIcon.d.ts +3 -0
- package/utils/renderModelIcon.js +19 -0
- package/utils/renderModelIcon.js.map +1 -0
- package/utils/renderModelIconOrFallback.d.ts +3 -0
- package/utils/renderModelIconOrFallback.js +17 -0
- package/utils/renderModelIconOrFallback.js.map +1 -0
|
@@ -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 type { Result } from \"@webiny/app-admin/components/BulkActions/Worker.js\";\nimport { Confirmation } from \"@webiny/app-admin/features/confirmation/abstractions.js\";\nimport { Notifications } from \"@webiny/app-admin/features/notifications/abstractions.js\";\nimport { DeleteEntryUseCase } from \"@webiny/app-headless-cms/features/contentEntry/deleteEntry/abstractions.js\";\nimport { BulkDeletePresenter } from \"@webiny/app-headless-cms/presentation/contentEntries/bulkActions/abstractions.js\";\nimport { CmsModelContext } from \"@webiny/app-headless-cms/features/contentEntry/abstractions.js\";\nimport type { CmsContentEntry } from \"@webiny/app-headless-cms/types.js\";\nimport type { CmsModel } from \"@webiny/app-headless-cms/types.js\";\nimport { ReviewErrorCode } from \"@webiny/app-workflows/review/domain/ReviewErrorCode.js\";\nimport { createBlockingReview } from \"@webiny/app-workflows/review/testing/reviewFixtures.js\";\nimport { NO_ACCESS_MESSAGE } from \"@webiny/app-workflows/review/presentation/noAccessMessage.js\";\nimport { GENERIC_ERROR } from \"@webiny/app-workflows/review/presentation/actionDialog/reviewErrorMessages.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 { DeleteEntryUseCaseReviewDecorator } from \"./DeleteEntryUseCaseReviewDecorator.js\";\nimport { BulkDeletePresenterReviewDecorator } from \"./BulkDeletePresenterReviewDecorator.js\";\n\ninterface DeleteParams {\n id: string;\n}\n\nconst MODEL = { modelId: \"article\", singularApiName: \"Article\" } as CmsModel;\n\nfunction entry(entryId: string): CmsContentEntry {\n return { id: `${entryId}#0001`, entryId, meta: { title: entryId } } as CmsContentEntry;\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: \"cms.article\",\n action: \"trash\",\n reviews: [\n {\n reviewId: `review-${entryId}`,\n model: \"cms.article\",\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\nfunction createNotifications() {\n return { notify: vi.fn(), success: vi.fn(), warning: vi.fn(), error: vi.fn() };\n}\n\nfunction createModelContext(model: CmsModel = MODEL) {\n return { getModel: vi.fn(() => model), setModel: vi.fn() };\n}\n\ndescribe(\"BulkDeletePresenterReviewDecorator (forwarding)\", () => {\n function setupForwarding() {\n const decoratee = {\n vm: { processing: false, results: [] },\n execute: vi.fn(async (_items: CmsContentEntry[], _allSelected: boolean) => true)\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 confirmBlocking: vi.fn()\n };\n\n const container = new Container();\n container.registerInstance(\n Notifications,\n createNotifications() as unknown as Notifications.Interface\n );\n container.registerInstance(CmsModelContext, createModelContext());\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 { decoratee, guard, useCases, presenter: container.resolve(BulkDeletePresenter) };\n }\n\n it(\"hands the items, the entry id and a run callback to the guard, and no use cases (R353)\", async () => {\n const { guard, presenter } = setupForwarding();\n const items = [entry(\"e1\"), entry(\"e2\")];\n\n await presenter.execute(items, false);\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(\"e1\");\n });\n\n it(\"runs the series per item on the first run and on the retry when not all rows are selected\", async () => {\n const { decoratee, guard, useCases, presenter } = setupForwarding();\n const items = [entry(\"e1\")];\n\n await presenter.execute(items, false);\n\n expect(decoratee.execute).toHaveBeenNthCalledWith(1, items, false);\n expect(decoratee.execute).toHaveBeenNthCalledWith(2, items, false);\n expect(guard.runBulk).toHaveBeenCalledTimes(1);\n expect(useCases.listBlockingReviews.execute).not.toHaveBeenCalled();\n expect(guard.confirmBlocking).not.toHaveBeenCalled();\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-item 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([\"e1\", \"e3\"]);\n const deleted: string[] = [];\n const failed: string[] = [];\n const deleteEntry = {\n execute: vi.fn(async (params: DeleteParams) => {\n if (blocked.has(params.id)) {\n throw createRefusal(params.id);\n }\n deleted.push(params.id);\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 container.register(ActiveReviewBlockCollector).inSingletonScope();\n container.register(ActiveReviewGuard).inSingletonScope();\n registerTrashUseCaseFakes(container, useCases);\n container.registerInstance(DeleteEntryUseCase, deleteEntry);\n container.registerDecorator(DeleteEntryUseCaseReviewDecorator);\n\n // Stands in for the base presenter: a per-item series that calls the decorated use case.\n const decoratee = {\n vm: { processing: false, results: [] as Result[] },\n execute: vi.fn(async (items: CmsContentEntry[], _allSelected: boolean) => {\n const useCase = container.resolve(DeleteEntryUseCase);\n decoratee.vm.results = [];\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({ model: MODEL, id: item.entryId });\n if (result === false) {\n failed.push(item.entryId);\n decoratee.vm.results.push({ title: item.entryId, status: \"failure\" });\n } else {\n decoratee.vm.results.push({ title: item.entryId, status: \"success\" });\n }\n }\n return true;\n })\n };\n // The real guard reports the first-pass count through Notifications (Task 33).\n const notifications = createNotifications();\n container.registerInstance(\n Notifications,\n notifications as unknown as Notifications.Interface\n );\n container.registerInstance(CmsModelContext, createModelContext());\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 presenter: container.resolve(BulkDeletePresenter)\n };\n }\n\n const items = [entry(\"e1\"), entry(\"e2\"), entry(\"e3\")];\n\n it(\"collects every refused item, warns once and retries only the blocked items\", async () => {\n const { confirm, deleted, failed, decoratee, useCases, presenter } =\n setupIntegrated(\"confirm\");\n\n await presenter.execute(items, false);\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-e1\",\n \"review-e3\"\n ]);\n expect(useCases.cancelReviewsForDelete.execute).toHaveBeenCalledTimes(2);\n expect(decoratee.execute).toHaveBeenCalledTimes(2);\n expect(decoratee.execute.mock.calls[1][0].map(item => item.entryId)).toEqual([\"e1\", \"e3\"]);\n expect(decoratee.execute.mock.calls[1][1]).toBe(false);\n expect(failed).toEqual([\"e1\", \"e3\"]);\n expect(deleted).toEqual([\"e2\", \"e1\", \"e3\"]);\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, false).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\ndescribe(\"BulkDeletePresenterReviewDecorator (all selected: pre-check by ids)\", () => {\n function setupPrecheck(model: CmsModel = MODEL) {\n const decoratee = {\n vm: { processing: false, results: [] },\n execute: vi.fn(async (_items: CmsContentEntry[], _allSelected: boolean) => true)\n };\n const useCases = createTrashUseCaseFakes();\n const notifications = createNotifications();\n const guard = {\n run: vi.fn(),\n runBulk: vi.fn(),\n confirmBlocking: vi.fn(async (params: GuardAbstraction.ConfirmBlockingParams) => {\n await params.afterCancel();\n return true;\n })\n };\n\n const container = new Container();\n container.registerInstance(\n Notifications,\n notifications as unknown as Notifications.Interface\n );\n container.registerInstance(CmsModelContext, createModelContext(model));\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 useCases,\n notifications,\n guard,\n presenter: container.resolve(BulkDeletePresenter)\n };\n }\n\n const items = [entry(\"e1\"), entry(\"e2\"), entry(\"e3\")];\n\n it(\"asks for the blocking reviews of the entry ids and runs the bulk task when none block\", async () => {\n const { decoratee, useCases, guard, presenter } = setupPrecheck();\n\n await presenter.execute(items, true);\n\n expect(useCases.listBlockingReviews.execute).toHaveBeenCalledTimes(1);\n expect(useCases.listBlockingReviews.execute).toHaveBeenCalledWith({\n namespace: \"cms.article\",\n targetIds: [\"e1\", \"e2\", \"e3\"]\n });\n expect(decoratee.execute).toHaveBeenCalledTimes(1);\n expect(decoratee.execute).toHaveBeenCalledWith(items, true);\n expect(guard.confirmBlocking).not.toHaveBeenCalled();\n expect(guard.runBulk).not.toHaveBeenCalled();\n });\n\n it(\"takes the namespace from the model context, not from the rows\", async () => {\n const pageModel = { modelId: \"page\", singularApiName: \"Page\" } as CmsModel;\n const { useCases, presenter } = setupPrecheck(pageModel);\n\n await presenter.execute(items, true);\n\n expect(useCases.listBlockingReviews.execute.mock.calls[0][0].namespace).toBe(\"cms.page\");\n });\n\n it(\"opens the warning with the blocking reviews and runs the bulk task after the cancel\", async () => {\n const { decoratee, useCases, guard, presenter } = setupPrecheck();\n const reviews = [\n createBlockingReview({ reviewId: \"review-e1\", targetId: \"e1\" }),\n createBlockingReview({ reviewId: \"review-e3\", targetId: \"e3\" })\n ];\n useCases.listBlockingReviews.execute.mockResolvedValue(reviews);\n\n await presenter.execute(items, true);\n\n expect(guard.confirmBlocking).toHaveBeenCalledTimes(1);\n const params = guard.confirmBlocking.mock.calls[0][0];\n expect(params.reviews).toEqual(reviews);\n expect(params.action).toBe(\"trash\");\n expect(params).not.toHaveProperty(\"useCases\");\n expect(decoratee.execute).toHaveBeenCalledTimes(1);\n expect(decoratee.execute).toHaveBeenCalledWith(items, true);\n });\n\n it(\"does not start the bulk task before the warning is confirmed\", async () => {\n const { decoratee, useCases, guard, presenter } = setupPrecheck();\n useCases.listBlockingReviews.execute.mockResolvedValue([\n createBlockingReview({ reviewId: \"review-e1\", targetId: \"e1\" })\n ]);\n guard.confirmBlocking.mockImplementation(async () => {\n expect(decoratee.execute).not.toHaveBeenCalled();\n return false;\n });\n\n await presenter.execute(items, true);\n\n expect(guard.confirmBlocking).toHaveBeenCalledTimes(1);\n expect(decoratee.execute).not.toHaveBeenCalled();\n });\n\n it(\"runs nothing when the warning is dismissed\", async () => {\n const { decoratee, useCases, notifications, guard, presenter } = setupPrecheck();\n useCases.listBlockingReviews.execute.mockResolvedValue([\n createBlockingReview({ reviewId: \"review-e1\", targetId: \"e1\" })\n ]);\n guard.confirmBlocking.mockResolvedValue(false);\n\n await presenter.execute(items, true);\n\n expect(decoratee.execute).not.toHaveBeenCalled();\n expect(notifications.error).not.toHaveBeenCalled();\n });\n\n it(\"lets a failing cancel propagate and does not start the bulk task\", async () => {\n const { decoratee, useCases, guard, presenter } = setupPrecheck();\n useCases.listBlockingReviews.execute.mockResolvedValue([\n createBlockingReview({ reviewId: \"review-e1\", targetId: \"e1\" })\n ]);\n const failure = new Error(\"Could not cancel\");\n guard.confirmBlocking.mockRejectedValue(failure);\n\n const error = await presenter.execute(items, true).catch(e => e);\n\n expect(error).toBe(failure);\n expect(decoratee.execute).not.toHaveBeenCalled();\n });\n\n it(\"checks 450 ids in three sequential calls of 200, 200 and 50\", async () => {\n const { useCases, presenter } = setupPrecheck();\n const many: CmsContentEntry[] = [];\n for (let index = 1; index <= 450; index++) {\n many.push(entry(`e${index}`));\n }\n let inFlight = 0;\n let maxInFlight = 0;\n useCases.listBlockingReviews.execute.mockImplementation(async () => {\n inFlight++;\n maxInFlight = Math.max(maxInFlight, inFlight);\n await Promise.resolve();\n inFlight--;\n return [];\n });\n\n await presenter.execute(many, true);\n\n expect(useCases.listBlockingReviews.execute).toHaveBeenCalledTimes(3);\n const sizes = useCases.listBlockingReviews.execute.mock.calls.map(call => {\n return call[0].targetIds.length;\n });\n expect(sizes).toEqual([200, 200, 50]);\n expect(useCases.listBlockingReviews.execute.mock.calls[0][0].targetIds[0]).toBe(\"e1\");\n expect(useCases.listBlockingReviews.execute.mock.calls[1][0].targetIds[0]).toBe(\"e201\");\n expect(useCases.listBlockingReviews.execute.mock.calls[2][0].targetIds[0]).toBe(\"e401\");\n expect(maxInFlight).toBe(1);\n });\n\n it(\"sends exactly 200 ids in one call\", async () => {\n const { useCases, presenter } = setupPrecheck();\n const exact: CmsContentEntry[] = [];\n for (let index = 1; index <= 200; index++) {\n exact.push(entry(`e${index}`));\n }\n\n await presenter.execute(exact, true);\n\n expect(useCases.listBlockingReviews.execute).toHaveBeenCalledTimes(1);\n expect(useCases.listBlockingReviews.execute.mock.calls[0][0].targetIds).toHaveLength(200);\n });\n\n it(\"sends each entry id once when several revisions of an entry are loaded\", async () => {\n const { useCases, presenter } = setupPrecheck();\n const rows = [\n entry(\"e1\"),\n { ...entry(\"e1\"), id: \"e1#0002\" } as CmsContentEntry,\n entry(\"e2\")\n ];\n\n await presenter.execute(rows, true);\n\n expect(useCases.listBlockingReviews.execute.mock.calls[0][0].targetIds).toEqual([\n \"e1\",\n \"e2\"\n ]);\n });\n\n it(\"collects the reviews of every chunk into one warning\", async () => {\n const { useCases, guard, presenter } = setupPrecheck();\n const many: CmsContentEntry[] = [];\n for (let index = 1; index <= 250; index++) {\n many.push(entry(`e${index}`));\n }\n useCases.listBlockingReviews.execute\n .mockResolvedValueOnce([\n createBlockingReview({ reviewId: \"review-e5\", targetId: \"e5\" })\n ])\n .mockResolvedValueOnce([\n createBlockingReview({ reviewId: \"review-e230\", targetId: \"e230\" })\n ]);\n\n await presenter.execute(many, true);\n\n expect(guard.confirmBlocking).toHaveBeenCalledTimes(1);\n const params = guard.confirmBlocking.mock.calls[0][0];\n expect(params.reviews.map(review => review.targetId)).toEqual([\"e5\", \"e230\"]);\n });\n\n it(\"shows the generic error toast and runs nothing when the pre-check fails\", async () => {\n const { decoratee, useCases, notifications, guard, presenter } = setupPrecheck();\n useCases.listBlockingReviews.execute.mockRejectedValue(new Error(\"Network down\"));\n\n await presenter.execute(items, true);\n\n expect(notifications.error).toHaveBeenCalledTimes(1);\n expect(notifications.error).toHaveBeenCalledWith({\n title: GENERIC_ERROR,\n position: REVIEW_TOAST_POSITION,\n duration: REVIEW_TOAST_DURATION,\n dismissible: true\n });\n expect(guard.confirmBlocking).not.toHaveBeenCalled();\n expect(decoratee.execute).not.toHaveBeenCalled();\n });\n\n it(\"shows the no-access text for a not authorized error\", async () => {\n const { decoratee, useCases, notifications, presenter } = setupPrecheck();\n useCases.listBlockingReviews.execute.mockRejectedValue(\n new GraphQLOperationError({\n message: \"Not authorized.\",\n code: ReviewErrorCode.NotAuthorized,\n data: null\n })\n );\n\n await presenter.execute(items, true);\n\n expect(notifications.error.mock.calls[0][0].title).toBe(NO_ACCESS_MESSAGE);\n expect(decoratee.execute).not.toHaveBeenCalled();\n });\n\n it(\"stops at the first failing chunk and runs nothing\", async () => {\n const { decoratee, useCases, notifications, guard, presenter } = setupPrecheck();\n const many: CmsContentEntry[] = [];\n for (let index = 1; index <= 450; index++) {\n many.push(entry(`e${index}`));\n }\n useCases.listBlockingReviews.execute\n .mockResolvedValueOnce([\n createBlockingReview({ reviewId: \"review-e5\", targetId: \"e5\" })\n ])\n .mockRejectedValueOnce(new Error(\"Network down\"));\n\n await presenter.execute(many, true);\n\n expect(useCases.listBlockingReviews.execute).toHaveBeenCalledTimes(2);\n expect(notifications.error).toHaveBeenCalledTimes(1);\n expect(guard.confirmBlocking).not.toHaveBeenCalled();\n expect(decoratee.execute).not.toHaveBeenCalled();\n });\n\n it(\"does not check anything when no row is selected\", async () => {\n const { decoratee, useCases, guard, presenter } = setupPrecheck();\n\n await presenter.execute([], true);\n\n expect(useCases.listBlockingReviews.execute).not.toHaveBeenCalled();\n expect(guard.confirmBlocking).not.toHaveBeenCalled();\n expect(decoratee.execute).toHaveBeenCalledWith([], true);\n });\n});\n\ndescribe(\"BulkDeletePresenterReviewDecorator (result: did the bulk trash start)\", () => {\n function setupResult() {\n const decoratee = {\n vm: { processing: false, results: [] },\n execute: vi.fn(async (_items: CmsContentEntry[], _allSelected: boolean) => true)\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 }),\n confirmBlocking: vi.fn(async (params: GuardAbstraction.ConfirmBlockingParams) => {\n await params.afterCancel();\n return true;\n })\n };\n\n const container = new Container();\n container.registerInstance(\n Notifications,\n createNotifications() as unknown as Notifications.Interface\n );\n container.registerInstance(CmsModelContext, createModelContext());\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 { decoratee, useCases, guard, presenter: container.resolve(BulkDeletePresenter) };\n }\n\n const items = [entry(\"e1\"), entry(\"e2\")];\n\n it(\"is true after a per-item run\", async () => {\n const { presenter } = setupResult();\n\n const started = await presenter.execute(items, false);\n\n expect(started).toBe(true);\n });\n\n it(\"is true when nothing blocks and the bulk task started\", async () => {\n const { presenter } = setupResult();\n\n const started = await presenter.execute(items, true);\n\n expect(started).toBe(true);\n });\n\n it(\"is the result of the bulk task when nothing blocks\", async () => {\n const { decoratee, presenter } = setupResult();\n decoratee.execute.mockResolvedValue(false);\n\n const started = await presenter.execute(items, true);\n\n expect(started).toBe(false);\n });\n\n it(\"is true when the warning was confirmed and the bulk task started\", async () => {\n const { useCases, presenter } = setupResult();\n useCases.listBlockingReviews.execute.mockResolvedValue([\n createBlockingReview({ reviewId: \"review-e1\", targetId: \"e1\" })\n ]);\n\n const started = await presenter.execute(items, true);\n\n expect(started).toBe(true);\n });\n\n it(\"is false when the warning was dismissed\", async () => {\n const { useCases, guard, presenter } = setupResult();\n useCases.listBlockingReviews.execute.mockResolvedValue([\n createBlockingReview({ reviewId: \"review-e1\", targetId: \"e1\" })\n ]);\n guard.confirmBlocking.mockResolvedValue(false);\n\n const started = await presenter.execute(items, true);\n\n expect(started).toBe(false);\n });\n\n it(\"is false when the pre-check failed\", async () => {\n const { useCases, presenter } = setupResult();\n useCases.listBlockingReviews.execute.mockRejectedValue(new Error(\"Network down\"));\n\n const started = await presenter.execute(items, true);\n\n expect(started).toBe(false);\n });\n});\n\ndescribe(\"BulkDeletePresenterReviewDecorator (all selected, with the real guard)\", () => {\n function setupReal(decision: \"confirm\" | \"dismiss\") {\n const confirm = vi.fn(\n async (\n _name: string,\n _params: unknown,\n execute?: (data: unknown) => Promise<unknown>\n ) => {\n if (decision === \"dismiss\") {\n return false;\n }\n return execute ? execute(undefined) : undefined;\n }\n );\n const order: string[] = [];\n const useCases = createTrashUseCaseFakes();\n useCases.listBlockingReviews.execute.mockResolvedValue([\n createBlockingReview({ reviewId: \"review-e1\", targetId: \"e1\" }),\n createBlockingReview({ reviewId: \"review-e3\", targetId: \"e3\" })\n ]);\n useCases.cancelReviewsForDelete.execute.mockImplementation(async params => {\n order.push(`cancel:${params.targetId}`);\n return [];\n });\n const decoratee = {\n vm: { processing: false, results: [] },\n execute: vi.fn(async (_items: CmsContentEntry[], _allSelected: boolean) => {\n order.push(\"bulk\");\n return true;\n })\n };\n\n const container = new Container();\n container.registerInstance(Confirmation, { confirm } as unknown as Confirmation.Interface);\n container.registerInstance(\n Notifications,\n createNotifications() as unknown as Notifications.Interface\n );\n container.registerInstance(CmsModelContext, createModelContext());\n container.register(ActiveReviewBlockCollector).inSingletonScope();\n container.register(ActiveReviewGuard).inSingletonScope();\n registerTrashUseCaseFakes(container, useCases);\n container.registerInstance(BulkDeletePresenter, decoratee);\n container.registerDecorator(BulkDeletePresenterReviewDecorator);\n\n return {\n confirm,\n order,\n useCases,\n decoratee,\n presenter: container.resolve(BulkDeletePresenter)\n };\n }\n\n const items = [entry(\"e1\"), entry(\"e2\"), entry(\"e3\")];\n\n it(\"warns, cancels each blocked entry without a revision, then starts the bulk task for every row\", async () => {\n const { confirm, order, useCases, decoratee, presenter } = setupReal(\"confirm\");\n\n await presenter.execute(items, true);\n\n expect(confirm).toHaveBeenCalledTimes(1);\n const dialogParams = confirm.mock.calls[0][1] as GuardAbstraction.DialogParams;\n expect(dialogParams.action).toBe(\"trash\");\n expect(dialogParams.reviews.map(review => review.reviewId)).toEqual([\n \"review-e1\",\n \"review-e3\"\n ]);\n expect(useCases.cancelReviewsForDelete.execute.mock.calls.map(call => call[0])).toEqual([\n { namespace: \"cms.article\", targetId: \"e1\", targetRevisionId: null, action: \"trash\" },\n { namespace: \"cms.article\", targetId: \"e3\", targetRevisionId: null, action: \"trash\" }\n ]);\n expect(decoratee.execute).toHaveBeenCalledTimes(1);\n expect(decoratee.execute).toHaveBeenCalledWith(items, true);\n expect(order).toEqual([\"cancel:e1\", \"cancel:e3\", \"bulk\"]);\n });\n\n it(\"cancels nothing and starts nothing when the warning is dismissed\", async () => {\n const { useCases, decoratee, presenter } = setupReal(\"dismiss\");\n\n await presenter.execute(items, true);\n\n expect(useCases.cancelReviewsForDelete.execute).not.toHaveBeenCalled();\n expect(decoratee.execute).not.toHaveBeenCalled();\n });\n\n it(\"rejects and starts no bulk task when a cancel fails\", async () => {\n const { useCases, decoratee, presenter } = setupReal(\"confirm\");\n const failure = new Error(\"Could not cancel\");\n useCases.cancelReviewsForDelete.execute.mockRejectedValue(failure);\n\n const error = await presenter.execute(items, true).catch(e => e);\n\n expect(error).toBe(failure);\n expect(decoratee.execute).not.toHaveBeenCalled();\n });\n});\n"],"names":["MODEL","entry","entryId","createRefusal","GraphQLOperationError","ReviewErrorCode","createNotifications","vi","createModelContext","model","describe","setupForwarding","decoratee","_items","_allSelected","useCases","createTrashUseCaseFakes","guard","params","container","Container","Notifications","CmsModelContext","GuardAbstraction","registerTrashUseCaseFakes","BulkDeletePresenter","BulkDeletePresenterReviewDecorator","it","presenter","items","expect","setupIntegrated","decision","release","undefined","gate","Promise","resolve","confirm","_name","_params","execute","blocked","Set","deleted","failed","deleteEntry","Confirmation","ActiveReviewBlockCollector","ActiveReviewGuard","DeleteEntryUseCase","DeleteEntryUseCaseReviewDecorator","useCase","item","result","notifications","dialogParams","review","settled","promise","setupPrecheck","pageModel","reviews","createBlockingReview","failure","Error","error","e","many","index","inFlight","maxInFlight","Math","sizes","call","exact","rows","GENERIC_ERROR","REVIEW_TOAST_POSITION","REVIEW_TOAST_DURATION","NO_ACCESS_MESSAGE","setupResult","started","setupReal","order"],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { DeleteEntryRevisionUseCase } from "@webiny/app-headless-cms/features/contentEntry/deleteEntryRevision/abstractions.js";
|
|
2
|
+
import type { IDeleteEntryRevisionParams } from "@webiny/app-headless-cms/features/contentEntry/deleteEntryRevision/abstractions.js";
|
|
3
|
+
import { ActiveReviewGuard } from "@webiny/app-workflows/review/trash/ActiveReviewGuard/abstractions.js";
|
|
4
|
+
declare class DeleteEntryRevisionUseCaseReviewDecoratorImpl implements DeleteEntryRevisionUseCase.Interface {
|
|
5
|
+
private guard;
|
|
6
|
+
private decoratee;
|
|
7
|
+
constructor(guard: ActiveReviewGuard.Interface, decoratee: DeleteEntryRevisionUseCase.Interface);
|
|
8
|
+
execute(params: IDeleteEntryRevisionParams): Promise<boolean>;
|
|
9
|
+
}
|
|
10
|
+
export declare const DeleteEntryRevisionUseCaseReviewDecorator: typeof DeleteEntryRevisionUseCaseReviewDecoratorImpl & {
|
|
11
|
+
__abstraction: import("@webiny/di").Abstraction<import("@webiny/app-headless-cms/features/contentEntry/deleteEntryRevision/abstractions.js").IDeleteEntryRevisionUseCase>;
|
|
12
|
+
};
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { DeleteEntryRevisionUseCase } from "@webiny/app-headless-cms/features/contentEntry/deleteEntryRevision/abstractions.js";
|
|
2
|
+
import { ActiveReviewGuard } from "@webiny/app-workflows/review/trash/ActiveReviewGuard/abstractions.js";
|
|
3
|
+
class DeleteEntryRevisionUseCaseReviewDecoratorImpl {
|
|
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.revisionId
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
const DeleteEntryRevisionUseCaseReviewDecorator = DeleteEntryRevisionUseCase.createDecorator({
|
|
16
|
+
decorator: DeleteEntryRevisionUseCaseReviewDecoratorImpl,
|
|
17
|
+
dependencies: [
|
|
18
|
+
ActiveReviewGuard
|
|
19
|
+
]
|
|
20
|
+
});
|
|
21
|
+
export { DeleteEntryRevisionUseCaseReviewDecorator };
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=DeleteEntryRevisionUseCaseReviewDecorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/trash/DeleteEntryRevisionUseCaseReviewDecorator.js","sources":["../../../src/features/trash/DeleteEntryRevisionUseCaseReviewDecorator.ts"],"sourcesContent":["import { DeleteEntryRevisionUseCase } from \"@webiny/app-headless-cms/features/contentEntry/deleteEntryRevision/abstractions.js\";\nimport type { IDeleteEntryRevisionParams } from \"@webiny/app-headless-cms/features/contentEntry/deleteEntryRevision/abstractions.js\";\nimport { ActiveReviewGuard } from \"@webiny/app-workflows/review/trash/ActiveReviewGuard/abstractions.js\";\n\nclass DeleteEntryRevisionUseCaseReviewDecoratorImpl\n implements DeleteEntryRevisionUseCase.Interface\n{\n constructor(\n private guard: ActiveReviewGuard.Interface,\n private decoratee: DeleteEntryRevisionUseCase.Interface\n ) {}\n\n async execute(params: IDeleteEntryRevisionParams): Promise<boolean> {\n return this.guard.run({\n action: () => this.decoratee.execute(params),\n revisionId: params.revisionId\n });\n }\n}\n\nexport const DeleteEntryRevisionUseCaseReviewDecorator = DeleteEntryRevisionUseCase.createDecorator(\n {\n decorator: DeleteEntryRevisionUseCaseReviewDecoratorImpl,\n dependencies: [ActiveReviewGuard]\n }\n);\n"],"names":["DeleteEntryRevisionUseCaseReviewDecoratorImpl","guard","decoratee","params","DeleteEntryRevisionUseCaseReviewDecorator","DeleteEntryRevisionUseCase","ActiveReviewGuard"],"mappings":";;AAIA,MAAMA;IAGF,YACYC,KAAkC,EAClCC,SAA+C,CACzD;aAFUD,KAAK,GAALA;aACAC,SAAS,GAATA;IACT;IAEH,MAAM,QAAQC,MAAkC,EAAoB;QAChE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;YAClB,QAAQ,IAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAACA;YACrC,YAAYA,OAAO,UAAU;QACjC;IACJ;AACJ;AAEO,MAAMC,4CAA4CC,2BAA2B,eAAe,CAC/F;IACI,WAAWL;IACX,cAAc;QAACM;KAAkB;AACrC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,123 @@
|
|
|
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 { DeleteEntryRevisionUseCase } from "@webiny/app-headless-cms/features/contentEntry/deleteEntryRevision/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 { DeleteEntryRevisionUseCaseReviewDecorator } from "./DeleteEntryRevisionUseCaseReviewDecorator.js";
|
|
13
|
+
const MODEL = {
|
|
14
|
+
modelId: "article",
|
|
15
|
+
singularApiName: "Article"
|
|
16
|
+
};
|
|
17
|
+
function createRefusal() {
|
|
18
|
+
return new GraphQLOperationError({
|
|
19
|
+
message: "This content has a review in progress.",
|
|
20
|
+
code: ReviewErrorCode.ActiveReviewOnTrash,
|
|
21
|
+
data: {
|
|
22
|
+
model: "cms.article",
|
|
23
|
+
action: "delete",
|
|
24
|
+
reviews: [
|
|
25
|
+
{
|
|
26
|
+
reviewId: "review-2",
|
|
27
|
+
model: "cms.article",
|
|
28
|
+
targetId: "entry-1",
|
|
29
|
+
targetRevisionId: "entry-1#0002",
|
|
30
|
+
title: "Launch article",
|
|
31
|
+
stepPosition: 1,
|
|
32
|
+
stepCount: 2,
|
|
33
|
+
stepName: "Editor"
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function setup(decision = "confirm") {
|
|
40
|
+
const confirm = vi.fn(async (_name, _params, execute)=>{
|
|
41
|
+
if ("dismiss" === decision) return false;
|
|
42
|
+
return execute ? execute(void 0) : void 0;
|
|
43
|
+
});
|
|
44
|
+
const decoratee = {
|
|
45
|
+
execute: vi.fn()
|
|
46
|
+
};
|
|
47
|
+
const useCases = createTrashUseCaseFakes();
|
|
48
|
+
const container = new Container();
|
|
49
|
+
container.registerInstance(Confirmation, {
|
|
50
|
+
confirm
|
|
51
|
+
});
|
|
52
|
+
container.registerInstance(Notifications, {
|
|
53
|
+
notify: vi.fn(),
|
|
54
|
+
success: vi.fn(),
|
|
55
|
+
warning: vi.fn()
|
|
56
|
+
});
|
|
57
|
+
container.register(ActiveReviewBlockCollector).inSingletonScope();
|
|
58
|
+
container.register(ActiveReviewGuard).inSingletonScope();
|
|
59
|
+
registerTrashUseCaseFakes(container, useCases);
|
|
60
|
+
container.registerInstance(DeleteEntryRevisionUseCase, decoratee);
|
|
61
|
+
container.registerDecorator(DeleteEntryRevisionUseCaseReviewDecorator);
|
|
62
|
+
return {
|
|
63
|
+
confirm,
|
|
64
|
+
decoratee,
|
|
65
|
+
useCases,
|
|
66
|
+
useCase: container.resolve(DeleteEntryRevisionUseCase)
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
describe("DeleteEntryRevisionUseCaseReviewDecorator", ()=>{
|
|
70
|
+
it("passes through to the decoratee when the delete succeeds", async ()=>{
|
|
71
|
+
const { confirm, decoratee, useCase } = setup();
|
|
72
|
+
decoratee.execute.mockResolvedValue(true);
|
|
73
|
+
const result = await useCase.execute({
|
|
74
|
+
model: MODEL,
|
|
75
|
+
revisionId: "entry-1#0002"
|
|
76
|
+
});
|
|
77
|
+
expect(result).toBe(true);
|
|
78
|
+
expect(decoratee.execute).toHaveBeenCalledWith({
|
|
79
|
+
model: MODEL,
|
|
80
|
+
revisionId: "entry-1#0002"
|
|
81
|
+
});
|
|
82
|
+
expect(confirm).not.toHaveBeenCalled();
|
|
83
|
+
});
|
|
84
|
+
it("on the server refusal cancels only that revision's reviews, then repeats the delete", async ()=>{
|
|
85
|
+
const { decoratee, useCases, useCase } = setup();
|
|
86
|
+
decoratee.execute.mockRejectedValueOnce(createRefusal()).mockResolvedValueOnce(true);
|
|
87
|
+
const result = await useCase.execute({
|
|
88
|
+
model: MODEL,
|
|
89
|
+
revisionId: "entry-1#0002"
|
|
90
|
+
});
|
|
91
|
+
expect(result).toBe(true);
|
|
92
|
+
expect(useCases.cancelReviewsForDelete.execute).toHaveBeenCalledTimes(1);
|
|
93
|
+
expect(useCases.cancelReviewsForDelete.execute).toHaveBeenCalledWith({
|
|
94
|
+
namespace: "cms.article",
|
|
95
|
+
targetId: "entry-1",
|
|
96
|
+
targetRevisionId: "entry-1#0002",
|
|
97
|
+
action: "delete"
|
|
98
|
+
});
|
|
99
|
+
expect(decoratee.execute).toHaveBeenCalledTimes(2);
|
|
100
|
+
});
|
|
101
|
+
it("resolves false when the warning is dismissed", async ()=>{
|
|
102
|
+
const { decoratee, useCases, useCase } = setup("dismiss");
|
|
103
|
+
decoratee.execute.mockRejectedValue(createRefusal());
|
|
104
|
+
const result = await useCase.execute({
|
|
105
|
+
model: MODEL,
|
|
106
|
+
revisionId: "entry-1#0002"
|
|
107
|
+
});
|
|
108
|
+
expect(result).toBe(false);
|
|
109
|
+
expect(useCases.cancelReviewsForDelete.execute).not.toHaveBeenCalled();
|
|
110
|
+
});
|
|
111
|
+
it("rethrows any other error unchanged", async ()=>{
|
|
112
|
+
const { decoratee, useCase } = setup();
|
|
113
|
+
const failure = new Error("Network down");
|
|
114
|
+
decoratee.execute.mockRejectedValue(failure);
|
|
115
|
+
const error = await useCase.execute({
|
|
116
|
+
model: MODEL,
|
|
117
|
+
revisionId: "entry-1#0002"
|
|
118
|
+
}).catch((e)=>e);
|
|
119
|
+
expect(error).toBe(failure);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
//# sourceMappingURL=DeleteEntryRevisionUseCaseReviewDecorator.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/trash/DeleteEntryRevisionUseCaseReviewDecorator.test.js","sources":["../../../src/features/trash/DeleteEntryRevisionUseCaseReviewDecorator.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 { DeleteEntryRevisionUseCase } from \"@webiny/app-headless-cms/features/contentEntry/deleteEntryRevision/abstractions.js\";\nimport type { CmsModel } from \"@webiny/app-headless-cms/types.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 { DeleteEntryRevisionUseCaseReviewDecorator } from \"./DeleteEntryRevisionUseCaseReviewDecorator.js\";\n\nconst MODEL = { modelId: \"article\", singularApiName: \"Article\" } as CmsModel;\n\nfunction createRefusal() {\n return new GraphQLOperationError({\n message: \"This content has a review in progress.\",\n code: ReviewErrorCode.ActiveReviewOnTrash,\n data: {\n model: \"cms.article\",\n action: \"delete\",\n reviews: [\n {\n reviewId: \"review-2\",\n model: \"cms.article\",\n targetId: \"entry-1\",\n targetRevisionId: \"entry-1#0002\",\n title: \"Launch article\",\n stepPosition: 1,\n stepCount: 2,\n stepName: \"Editor\"\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(DeleteEntryRevisionUseCase, decoratee);\n container.registerDecorator(DeleteEntryRevisionUseCaseReviewDecorator);\n\n return {\n confirm,\n decoratee,\n useCases,\n useCase: container.resolve(DeleteEntryRevisionUseCase)\n };\n}\n\ndescribe(\"DeleteEntryRevisionUseCaseReviewDecorator\", () => {\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({ model: MODEL, revisionId: \"entry-1#0002\" });\n\n expect(result).toBe(true);\n expect(decoratee.execute).toHaveBeenCalledWith({\n model: MODEL,\n revisionId: \"entry-1#0002\"\n });\n expect(confirm).not.toHaveBeenCalled();\n });\n\n it(\"on the server refusal cancels only that revision's reviews, then repeats the delete\", async () => {\n const { decoratee, useCases, useCase } = setup();\n decoratee.execute.mockRejectedValueOnce(createRefusal()).mockResolvedValueOnce(true);\n\n const result = await useCase.execute({ model: MODEL, revisionId: \"entry-1#0002\" });\n\n expect(result).toBe(true);\n expect(useCases.cancelReviewsForDelete.execute).toHaveBeenCalledTimes(1);\n expect(useCases.cancelReviewsForDelete.execute).toHaveBeenCalledWith({\n namespace: \"cms.article\",\n targetId: \"entry-1\",\n targetRevisionId: \"entry-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({ model: MODEL, revisionId: \"entry-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\n .execute({ model: MODEL, revisionId: \"entry-1#0002\" })\n .catch(e => e);\n\n expect(error).toBe(failure);\n });\n});\n"],"names":["MODEL","createRefusal","GraphQLOperationError","ReviewErrorCode","setup","decision","confirm","vi","_name","_params","execute","undefined","decoratee","useCases","createTrashUseCaseFakes","container","Container","Confirmation","Notifications","ActiveReviewBlockCollector","ActiveReviewGuard","registerTrashUseCaseFakes","DeleteEntryRevisionUseCase","DeleteEntryRevisionUseCaseReviewDecorator","describe","it","useCase","result","expect","failure","Error","error","e"],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { DeleteEntryUseCase } from "@webiny/app-headless-cms/features/contentEntry/deleteEntry/abstractions.js";
|
|
2
|
+
import type { IDeleteEntryParams } from "@webiny/app-headless-cms/features/contentEntry/deleteEntry/abstractions.js";
|
|
3
|
+
import { ActiveReviewGuard } from "@webiny/app-workflows/review/trash/ActiveReviewGuard/abstractions.js";
|
|
4
|
+
declare class DeleteEntryUseCaseReviewDecoratorImpl implements DeleteEntryUseCase.Interface {
|
|
5
|
+
private guard;
|
|
6
|
+
private decoratee;
|
|
7
|
+
constructor(guard: ActiveReviewGuard.Interface, decoratee: DeleteEntryUseCase.Interface);
|
|
8
|
+
execute(params: IDeleteEntryParams): Promise<boolean>;
|
|
9
|
+
}
|
|
10
|
+
export declare const DeleteEntryUseCaseReviewDecorator: typeof DeleteEntryUseCaseReviewDecoratorImpl & {
|
|
11
|
+
__abstraction: import("@webiny/di").Abstraction<import("@webiny/app-headless-cms/features/contentEntry/deleteEntry/abstractions.js").IDeleteEntryUseCase>;
|
|
12
|
+
};
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { DeleteEntryUseCase } from "@webiny/app-headless-cms/features/contentEntry/deleteEntry/abstractions.js";
|
|
2
|
+
import { ActiveReviewGuard } from "@webiny/app-workflows/review/trash/ActiveReviewGuard/abstractions.js";
|
|
3
|
+
class DeleteEntryUseCaseReviewDecoratorImpl {
|
|
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 DeleteEntryUseCaseReviewDecorator = DeleteEntryUseCase.createDecorator({
|
|
16
|
+
decorator: DeleteEntryUseCaseReviewDecoratorImpl,
|
|
17
|
+
dependencies: [
|
|
18
|
+
ActiveReviewGuard
|
|
19
|
+
]
|
|
20
|
+
});
|
|
21
|
+
export { DeleteEntryUseCaseReviewDecorator };
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=DeleteEntryUseCaseReviewDecorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/trash/DeleteEntryUseCaseReviewDecorator.js","sources":["../../../src/features/trash/DeleteEntryUseCaseReviewDecorator.ts"],"sourcesContent":["import { DeleteEntryUseCase } from \"@webiny/app-headless-cms/features/contentEntry/deleteEntry/abstractions.js\";\nimport type { IDeleteEntryParams } from \"@webiny/app-headless-cms/features/contentEntry/deleteEntry/abstractions.js\";\nimport { ActiveReviewGuard } from \"@webiny/app-workflows/review/trash/ActiveReviewGuard/abstractions.js\";\n\nclass DeleteEntryUseCaseReviewDecoratorImpl implements DeleteEntryUseCase.Interface {\n constructor(\n private guard: ActiveReviewGuard.Interface,\n private decoratee: DeleteEntryUseCase.Interface\n ) {}\n\n async execute(params: IDeleteEntryParams): Promise<boolean> {\n return this.guard.run({\n action: () => this.decoratee.execute(params),\n revisionId: null\n });\n }\n}\n\nexport const DeleteEntryUseCaseReviewDecorator = DeleteEntryUseCase.createDecorator({\n decorator: DeleteEntryUseCaseReviewDecoratorImpl,\n dependencies: [ActiveReviewGuard]\n});\n"],"names":["DeleteEntryUseCaseReviewDecoratorImpl","guard","decoratee","params","DeleteEntryUseCaseReviewDecorator","DeleteEntryUseCase","ActiveReviewGuard"],"mappings":";;AAIA,MAAMA;IACF,YACYC,KAAkC,EAClCC,SAAuC,CACjD;aAFUD,KAAK,GAALA;aACAC,SAAS,GAATA;IACT;IAEH,MAAM,QAAQC,MAA0B,EAAoB;QACxD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;YAClB,QAAQ,IAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAACA;YACrC,YAAY;QAChB;IACJ;AACJ;AAEO,MAAMC,oCAAoCC,mBAAmB,eAAe,CAAC;IAChF,WAAWL;IACX,cAAc;QAACM;KAAkB;AACrC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,139 @@
|
|
|
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 { DeleteEntryUseCase } from "@webiny/app-headless-cms/features/contentEntry/deleteEntry/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 { DeleteEntryUseCaseReviewDecorator } from "./DeleteEntryUseCaseReviewDecorator.js";
|
|
13
|
+
const MODEL = {
|
|
14
|
+
modelId: "article",
|
|
15
|
+
singularApiName: "Article"
|
|
16
|
+
};
|
|
17
|
+
function createRefusal(action = "trash") {
|
|
18
|
+
return new GraphQLOperationError({
|
|
19
|
+
message: "This content has a review in progress.",
|
|
20
|
+
code: ReviewErrorCode.ActiveReviewOnTrash,
|
|
21
|
+
data: {
|
|
22
|
+
model: "cms.article",
|
|
23
|
+
action,
|
|
24
|
+
reviews: [
|
|
25
|
+
{
|
|
26
|
+
reviewId: "review-1",
|
|
27
|
+
model: "cms.article",
|
|
28
|
+
targetId: "entry-1",
|
|
29
|
+
targetRevisionId: "entry-1#0001",
|
|
30
|
+
title: "Launch article",
|
|
31
|
+
stepPosition: 2,
|
|
32
|
+
stepCount: 3,
|
|
33
|
+
stepName: "Legal"
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function setup(decision = "confirm") {
|
|
40
|
+
const confirm = vi.fn(async (_name, _params, execute)=>{
|
|
41
|
+
if ("dismiss" === decision) return false;
|
|
42
|
+
return execute ? execute(void 0) : void 0;
|
|
43
|
+
});
|
|
44
|
+
const decoratee = {
|
|
45
|
+
execute: vi.fn()
|
|
46
|
+
};
|
|
47
|
+
const useCases = createTrashUseCaseFakes();
|
|
48
|
+
const container = new Container();
|
|
49
|
+
container.registerInstance(Confirmation, {
|
|
50
|
+
confirm
|
|
51
|
+
});
|
|
52
|
+
container.registerInstance(Notifications, {
|
|
53
|
+
notify: vi.fn(),
|
|
54
|
+
success: vi.fn(),
|
|
55
|
+
warning: vi.fn()
|
|
56
|
+
});
|
|
57
|
+
container.register(ActiveReviewBlockCollector).inSingletonScope();
|
|
58
|
+
container.register(ActiveReviewGuard).inSingletonScope();
|
|
59
|
+
registerTrashUseCaseFakes(container, useCases);
|
|
60
|
+
container.registerInstance(DeleteEntryUseCase, decoratee);
|
|
61
|
+
container.registerDecorator(DeleteEntryUseCaseReviewDecorator);
|
|
62
|
+
return {
|
|
63
|
+
confirm,
|
|
64
|
+
decoratee,
|
|
65
|
+
useCases,
|
|
66
|
+
useCase: container.resolve(DeleteEntryUseCase)
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
describe("DeleteEntryUseCaseReviewDecorator", ()=>{
|
|
70
|
+
it("passes through to the decoratee when the trash succeeds", async ()=>{
|
|
71
|
+
const { confirm, decoratee, useCases, useCase } = setup();
|
|
72
|
+
decoratee.execute.mockResolvedValue(true);
|
|
73
|
+
const result = await useCase.execute({
|
|
74
|
+
model: MODEL,
|
|
75
|
+
id: "entry-1"
|
|
76
|
+
});
|
|
77
|
+
expect(result).toBe(true);
|
|
78
|
+
expect(decoratee.execute).toHaveBeenCalledTimes(1);
|
|
79
|
+
expect(decoratee.execute).toHaveBeenCalledWith({
|
|
80
|
+
model: MODEL,
|
|
81
|
+
id: "entry-1"
|
|
82
|
+
});
|
|
83
|
+
expect(confirm).not.toHaveBeenCalled();
|
|
84
|
+
expect(useCases.cancelReviewsForDelete.execute).not.toHaveBeenCalled();
|
|
85
|
+
});
|
|
86
|
+
it("on the server refusal warns, cancels the whole entry once and repeats the trash", async ()=>{
|
|
87
|
+
const { confirm, decoratee, useCases, useCase } = setup();
|
|
88
|
+
decoratee.execute.mockRejectedValueOnce(createRefusal("trash")).mockResolvedValueOnce(true);
|
|
89
|
+
const result = await useCase.execute({
|
|
90
|
+
model: MODEL,
|
|
91
|
+
id: "entry-1"
|
|
92
|
+
});
|
|
93
|
+
expect(result).toBe(true);
|
|
94
|
+
expect(confirm).toHaveBeenCalledTimes(1);
|
|
95
|
+
expect(useCases.cancelReviewsForDelete.execute).toHaveBeenCalledTimes(1);
|
|
96
|
+
expect(useCases.cancelReviewsForDelete.execute).toHaveBeenCalledWith({
|
|
97
|
+
namespace: "cms.article",
|
|
98
|
+
targetId: "entry-1",
|
|
99
|
+
targetRevisionId: null,
|
|
100
|
+
action: "trash"
|
|
101
|
+
});
|
|
102
|
+
expect(decoratee.execute).toHaveBeenCalledTimes(2);
|
|
103
|
+
});
|
|
104
|
+
it("resolves false when the warning is dismissed, with nothing cancelled or repeated", async ()=>{
|
|
105
|
+
const { decoratee, useCases, useCase } = setup("dismiss");
|
|
106
|
+
decoratee.execute.mockRejectedValue(createRefusal());
|
|
107
|
+
const result = await useCase.execute({
|
|
108
|
+
model: MODEL,
|
|
109
|
+
id: "entry-1"
|
|
110
|
+
});
|
|
111
|
+
expect(result).toBe(false);
|
|
112
|
+
expect(useCases.cancelReviewsForDelete.execute).not.toHaveBeenCalled();
|
|
113
|
+
expect(decoratee.execute).toHaveBeenCalledTimes(1);
|
|
114
|
+
});
|
|
115
|
+
it("rethrows any other error unchanged", async ()=>{
|
|
116
|
+
const { confirm, decoratee, useCase } = setup();
|
|
117
|
+
const failure = new Error("Network down");
|
|
118
|
+
decoratee.execute.mockRejectedValue(failure);
|
|
119
|
+
const error = await useCase.execute({
|
|
120
|
+
model: MODEL,
|
|
121
|
+
id: "entry-1"
|
|
122
|
+
}).catch((e)=>e);
|
|
123
|
+
expect(error).toBe(failure);
|
|
124
|
+
expect(confirm).not.toHaveBeenCalled();
|
|
125
|
+
});
|
|
126
|
+
it("propagates a second refusal after the repeat", async ()=>{
|
|
127
|
+
const { confirm, decoratee, useCase } = setup();
|
|
128
|
+
const second = createRefusal();
|
|
129
|
+
decoratee.execute.mockRejectedValueOnce(createRefusal()).mockRejectedValueOnce(second);
|
|
130
|
+
const error = await useCase.execute({
|
|
131
|
+
model: MODEL,
|
|
132
|
+
id: "entry-1"
|
|
133
|
+
}).catch((e)=>e);
|
|
134
|
+
expect(error).toBe(second);
|
|
135
|
+
expect(confirm).toHaveBeenCalledTimes(1);
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
//# sourceMappingURL=DeleteEntryUseCaseReviewDecorator.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/trash/DeleteEntryUseCaseReviewDecorator.test.js","sources":["../../../src/features/trash/DeleteEntryUseCaseReviewDecorator.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 { DeleteEntryUseCase } from \"@webiny/app-headless-cms/features/contentEntry/deleteEntry/abstractions.js\";\nimport type { CmsModel } from \"@webiny/app-headless-cms/types.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 { DeleteEntryUseCaseReviewDecorator } from \"./DeleteEntryUseCaseReviewDecorator.js\";\n\nconst MODEL = { modelId: \"article\", singularApiName: \"Article\" } as CmsModel;\n\nfunction createRefusal(action: \"trash\" | \"delete\" = \"trash\") {\n return new GraphQLOperationError({\n message: \"This content has a review in progress.\",\n code: ReviewErrorCode.ActiveReviewOnTrash,\n data: {\n model: \"cms.article\",\n action,\n reviews: [\n {\n reviewId: \"review-1\",\n model: \"cms.article\",\n targetId: \"entry-1\",\n targetRevisionId: \"entry-1#0001\",\n title: \"Launch article\",\n stepPosition: 2,\n stepCount: 3,\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(DeleteEntryUseCase, decoratee);\n container.registerDecorator(DeleteEntryUseCaseReviewDecorator);\n\n return { confirm, decoratee, useCases, useCase: container.resolve(DeleteEntryUseCase) };\n}\n\ndescribe(\"DeleteEntryUseCaseReviewDecorator\", () => {\n it(\"passes through to the decoratee when the trash succeeds\", async () => {\n const { confirm, decoratee, useCases, useCase } = setup();\n decoratee.execute.mockResolvedValue(true);\n\n const result = await useCase.execute({ model: MODEL, id: \"entry-1\" });\n\n expect(result).toBe(true);\n expect(decoratee.execute).toHaveBeenCalledTimes(1);\n expect(decoratee.execute).toHaveBeenCalledWith({ model: MODEL, id: \"entry-1\" });\n expect(confirm).not.toHaveBeenCalled();\n expect(useCases.cancelReviewsForDelete.execute).not.toHaveBeenCalled();\n });\n\n it(\"on the server refusal warns, cancels the whole entry once and repeats the trash\", async () => {\n const { confirm, decoratee, useCases, useCase } = setup();\n decoratee.execute.mockRejectedValueOnce(createRefusal(\"trash\")).mockResolvedValueOnce(true);\n\n const result = await useCase.execute({ model: MODEL, id: \"entry-1\" });\n\n expect(result).toBe(true);\n expect(confirm).toHaveBeenCalledTimes(1);\n expect(useCases.cancelReviewsForDelete.execute).toHaveBeenCalledTimes(1);\n expect(useCases.cancelReviewsForDelete.execute).toHaveBeenCalledWith({\n namespace: \"cms.article\",\n targetId: \"entry-1\",\n targetRevisionId: null,\n action: \"trash\"\n });\n expect(decoratee.execute).toHaveBeenCalledTimes(2);\n });\n\n it(\"resolves false when the warning is dismissed, with nothing cancelled or repeated\", async () => {\n const { decoratee, useCases, useCase } = setup(\"dismiss\");\n decoratee.execute.mockRejectedValue(createRefusal());\n\n const result = await useCase.execute({ model: MODEL, id: \"entry-1\" });\n\n expect(result).toBe(false);\n expect(useCases.cancelReviewsForDelete.execute).not.toHaveBeenCalled();\n expect(decoratee.execute).toHaveBeenCalledTimes(1);\n });\n\n it(\"rethrows any other error unchanged\", async () => {\n const { confirm, decoratee, useCase } = setup();\n const failure = new Error(\"Network down\");\n decoratee.execute.mockRejectedValue(failure);\n\n const error = await useCase.execute({ model: MODEL, id: \"entry-1\" }).catch(e => e);\n\n expect(error).toBe(failure);\n expect(confirm).not.toHaveBeenCalled();\n });\n\n it(\"propagates a second refusal after the repeat\", async () => {\n const { confirm, decoratee, useCase } = setup();\n const second = createRefusal();\n decoratee.execute.mockRejectedValueOnce(createRefusal()).mockRejectedValueOnce(second);\n\n const error = await useCase.execute({ model: MODEL, id: \"entry-1\" }).catch(e => e);\n\n expect(error).toBe(second);\n expect(confirm).toHaveBeenCalledTimes(1);\n });\n});\n"],"names":["MODEL","createRefusal","action","GraphQLOperationError","ReviewErrorCode","setup","decision","confirm","vi","_name","_params","execute","undefined","decoratee","useCases","createTrashUseCaseFakes","container","Container","Confirmation","Notifications","ActiveReviewBlockCollector","ActiveReviewGuard","registerTrashUseCaseFakes","DeleteEntryUseCase","DeleteEntryUseCaseReviewDecorator","describe","it","useCase","result","expect","failure","Error","error","e","second"],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { PermanentlyDeleteEntryUseCase } from "@webiny/app-headless-cms/features/contentEntry/permanentlyDeleteEntry/abstractions.js";
|
|
2
|
+
import type { IPermanentlyDeleteEntryParams } from "@webiny/app-headless-cms/features/contentEntry/permanentlyDeleteEntry/abstractions.js";
|
|
3
|
+
import { ActiveReviewGuard } from "@webiny/app-workflows/review/trash/ActiveReviewGuard/abstractions.js";
|
|
4
|
+
declare class PermanentlyDeleteEntryUseCaseReviewDecoratorImpl implements PermanentlyDeleteEntryUseCase.Interface {
|
|
5
|
+
private guard;
|
|
6
|
+
private decoratee;
|
|
7
|
+
constructor(guard: ActiveReviewGuard.Interface, decoratee: PermanentlyDeleteEntryUseCase.Interface);
|
|
8
|
+
execute(params: IPermanentlyDeleteEntryParams): Promise<boolean>;
|
|
9
|
+
}
|
|
10
|
+
export declare const PermanentlyDeleteEntryUseCaseReviewDecorator: typeof PermanentlyDeleteEntryUseCaseReviewDecoratorImpl & {
|
|
11
|
+
__abstraction: import("@webiny/di").Abstraction<import("@webiny/app-headless-cms/features/contentEntry/permanentlyDeleteEntry/abstractions.js").IPermanentlyDeleteEntryUseCase>;
|
|
12
|
+
};
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { PermanentlyDeleteEntryUseCase } from "@webiny/app-headless-cms/features/contentEntry/permanentlyDeleteEntry/abstractions.js";
|
|
2
|
+
import { ActiveReviewGuard } from "@webiny/app-workflows/review/trash/ActiveReviewGuard/abstractions.js";
|
|
3
|
+
class PermanentlyDeleteEntryUseCaseReviewDecoratorImpl {
|
|
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 PermanentlyDeleteEntryUseCaseReviewDecorator = PermanentlyDeleteEntryUseCase.createDecorator({
|
|
16
|
+
decorator: PermanentlyDeleteEntryUseCaseReviewDecoratorImpl,
|
|
17
|
+
dependencies: [
|
|
18
|
+
ActiveReviewGuard
|
|
19
|
+
]
|
|
20
|
+
});
|
|
21
|
+
export { PermanentlyDeleteEntryUseCaseReviewDecorator };
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=PermanentlyDeleteEntryUseCaseReviewDecorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/trash/PermanentlyDeleteEntryUseCaseReviewDecorator.js","sources":["../../../src/features/trash/PermanentlyDeleteEntryUseCaseReviewDecorator.ts"],"sourcesContent":["import { PermanentlyDeleteEntryUseCase } from \"@webiny/app-headless-cms/features/contentEntry/permanentlyDeleteEntry/abstractions.js\";\nimport type { IPermanentlyDeleteEntryParams } from \"@webiny/app-headless-cms/features/contentEntry/permanentlyDeleteEntry/abstractions.js\";\nimport { ActiveReviewGuard } from \"@webiny/app-workflows/review/trash/ActiveReviewGuard/abstractions.js\";\n\nclass PermanentlyDeleteEntryUseCaseReviewDecoratorImpl\n implements PermanentlyDeleteEntryUseCase.Interface\n{\n constructor(\n private guard: ActiveReviewGuard.Interface,\n private decoratee: PermanentlyDeleteEntryUseCase.Interface\n ) {}\n\n async execute(params: IPermanentlyDeleteEntryParams): Promise<boolean> {\n return this.guard.run({\n action: () => this.decoratee.execute(params),\n revisionId: null\n });\n }\n}\n\nexport const PermanentlyDeleteEntryUseCaseReviewDecorator =\n PermanentlyDeleteEntryUseCase.createDecorator({\n decorator: PermanentlyDeleteEntryUseCaseReviewDecoratorImpl,\n dependencies: [ActiveReviewGuard]\n });\n"],"names":["PermanentlyDeleteEntryUseCaseReviewDecoratorImpl","guard","decoratee","params","PermanentlyDeleteEntryUseCaseReviewDecorator","PermanentlyDeleteEntryUseCase","ActiveReviewGuard"],"mappings":";;AAIA,MAAMA;IAGF,YACYC,KAAkC,EAClCC,SAAkD,CAC5D;aAFUD,KAAK,GAALA;aACAC,SAAS,GAATA;IACT;IAEH,MAAM,QAAQC,MAAqC,EAAoB;QACnE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;YAClB,QAAQ,IAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAACA;YACrC,YAAY;QAChB;IACJ;AACJ;AAEO,MAAMC,+CACTC,8BAA8B,eAAe,CAAC;IAC1C,WAAWL;IACX,cAAc;QAACM;KAAkB;AACrC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|