diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.spec.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.spec.ts index d5a12ee2370..db778fe3dc7 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.spec.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.spec.ts @@ -94,8 +94,7 @@ const baseUVEState = { { id: 1, translated: true }, { id: 2, translated: false }, { id: 3, translated: true } - ]), - workflowActions: signal([]) + ]) }; describe('DotUveToolbarComponent', () => { diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.ts index 5b9205aede4..0f649288747 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.ts @@ -58,7 +58,6 @@ import { EditEmaPersonaSelectorComponent } from '../edit-ema-persona-selector/ed changeDetection: ChangeDetectionStrategy.OnPush }) export class DotUveToolbarComponent { - // `viewChild` signal is not supported by ng-mocks. Ticket: https://github.com/help-me-mom/ng-mocks/issues/8634 $personaSelector = viewChild('personaSelector'); $languageSelector = viewChild('languageSelector'); diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-workflow-actions/dot-uve-workflow-actions.component.spec.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-workflow-actions/dot-uve-workflow-actions.component.spec.ts index 1ebc6128042..76718953ae3 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-workflow-actions/dot-uve-workflow-actions.component.spec.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-workflow-actions/dot-uve-workflow-actions.component.spec.ts @@ -3,6 +3,7 @@ import { Spectator, createComponentFactory, mockProvider } from '@ngneat/spectat import { Subject, of } from 'rxjs'; import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { signal } from '@angular/core'; import { MessageService } from 'primeng/api'; @@ -19,7 +20,6 @@ import { DotWizardService, DotWorkflowActionsFireService, DotWorkflowEventHandlerService, - DotWorkflowsActionsService, PushPublishService } from '@dotcms/data-access'; import { CoreWebService, LoginService } from '@dotcms/dotcms-js'; @@ -34,6 +34,9 @@ import { import { DotUveWorkflowActionsComponent } from './dot-uve-workflow-actions.component'; +import { MOCK_RESPONSE_VTL } from '../../../shared/mocks'; +import { UVEStore } from '../../../store/dot-uve.store'; + const DOT_WORKFLOW_PAYLOAD_MOCK: DotWorkflowPayload = { assign: '654b0931-1027-41f7-ad4d-173115ed8ec1', comments: 'ds', @@ -68,6 +71,8 @@ const workflowActionMock = { ] }; +const expectedInode = MOCK_RESPONSE_VTL.page.inode; + const messageServiceMock = new MockDotMessageService({ 'Workflow-Action': 'Workflow Action', 'edit.content.fire.action.success': 'Success', @@ -76,23 +81,49 @@ const messageServiceMock = new MockDotMessageService({ Loading: 'loading' }); +// const baseUVEState = { +// $uveToolbar: signal(baseUVEToolbarState), +// setDevice: jest.fn(), +// setSocialMedia: jest.fn(), +// pageParams: signal(params), +// pageAPIResponse: signal(MOCK_RESPONSE_VTL), +// workflowActions: signal([]) +// }; + +const pageParams = { + url: 'test-url', + language_id: '1' +}; + +const uveStoreMock = { + pageAPIResponse: signal(MOCK_RESPONSE_VTL), + workflowActions: signal([]), + workflowLoading: signal(false), + canEditPage: signal(true), + pageParams: signal(pageParams), + loadPageAsset: jest.fn(), + reloadCurrentPage: jest.fn(), + setWorkflowActionLoading: jest.fn() +}; + describe('DotUveWorkflowActionsComponent', () => { let spectator: Spectator; let dotWizardService: DotWizardService; - let dotWorkflowsActionsService: DotWorkflowsActionsService; let dotWorkflowEventHandlerService: DotWorkflowEventHandlerService; let dotWorkflowActionsFireService: DotWorkflowActionsFireService; let messageService: MessageService; + let store: InstanceType; + const createComponent = createComponentFactory({ component: DotUveWorkflowActionsComponent, imports: [HttpClientTestingModule], componentProviders: [ DotWizardService, - DotWorkflowsActionsService, DotWorkflowEventHandlerService, DotWorkflowActionsFireService, MessageService, + mockProvider(UVEStore, uveStoreMock), mockProvider(DotAlertConfirmService), mockProvider(DotMessageDisplayService), mockProvider(DotHttpErrorManagerService), @@ -116,53 +147,56 @@ describe('DotUveWorkflowActionsComponent', () => { detectChanges: false }); + store = spectator.inject(UVEStore, true); dotWizardService = spectator.inject(DotWizardService, true); - dotWorkflowsActionsService = spectator.inject(DotWorkflowsActionsService, true); dotWorkflowEventHandlerService = spectator.inject(DotWorkflowEventHandlerService, true); dotWorkflowActionsFireService = spectator.inject(DotWorkflowActionsFireService, true); messageService = spectator.inject(MessageService, true); }); describe('Without Workflow Actions', () => { - beforeEach(() => { - spectator.setInput('inode', '123'); + it('should set action as an empty array and loading to true', () => { + uveStoreMock.workflowLoading.set(true); spectator.detectChanges(); - }); - it('should set action as an empty array and loading to true', () => { const dotWorkflowActionsComponent = spectator.query(DotWorkflowActionsComponent); expect(dotWorkflowActionsComponent.actions()).toEqual([]); expect(dotWorkflowActionsComponent.loading()).toBeTruthy(); expect(dotWorkflowActionsComponent.size()).toBe('small'); }); + + it("should be disabled if user can't edit", () => { + uveStoreMock.canEditPage.set(false); + spectator.detectChanges(); + + const dotWorkflowActionsComponent = spectator.query(DotWorkflowActionsComponent); + expect(dotWorkflowActionsComponent.disabled()).toBeTruthy(); + }); }); describe('With Workflow Actions', () => { beforeEach(() => { - jest.spyOn(dotWorkflowsActionsService, 'getByInode').mockReturnValue( - of(mockWorkflowsActions) - ); - - spectator.setInput('inode', '123'); + uveStoreMock.workflowLoading.set(false); + uveStoreMock.canEditPage.set(true); + uveStoreMock.workflowActions.set(mockWorkflowsActions); spectator.detectChanges(); }); it('should load workflow actions', () => { const dotWorkflowActionsComponent = spectator.query(DotWorkflowActionsComponent); - expect(dotWorkflowsActionsService.getByInode).toHaveBeenCalledWith('123'); expect(dotWorkflowActionsComponent.actions()).toEqual(mockWorkflowsActions); + expect(dotWorkflowActionsComponent.loading()).toBeFalsy(); + expect(dotWorkflowActionsComponent.disabled()).toBeFalsy(); }); - it('should fire workflow actions when it does not have inputs', () => { - jest.spyOn(dotWorkflowEventHandlerService, 'containsPushPublish').mockReturnValue( - false - ); + it('should fire workflow actions and loadPageAssets', () => { + const spySetWorkflowActionLoading = jest.spyOn(store, 'setWorkflowActionLoading'); + const spyLoadPageAsset = jest.spyOn(store, 'loadPageAsset'); const dotWorkflowActionsComponent = spectator.query(DotWorkflowActionsComponent); const spy = jest .spyOn(dotWorkflowActionsFireService, 'fireTo') .mockReturnValue(of(dotcmsContentletMock)); - // const spyNewPage = jest.spyOn(spectator.component.newPage, 'emit'); const spyMessage = jest.spyOn(messageService, 'add'); dotWorkflowActionsComponent.actionFired.emit({ @@ -171,16 +205,16 @@ describe('DotUveWorkflowActionsComponent', () => { }); expect(spy).toHaveBeenCalledWith({ - inode: '123', + inode: expectedInode, actionId: mockWorkflowsActions[0].id, data: undefined }); - // expect(spyNewPage).toHaveBeenCalledWith(dotcmsContentletMock); - expect(dotWorkflowsActionsService.getByInode).toHaveBeenCalledWith( - dotcmsContentletMock.inode - ); - + expect(spySetWorkflowActionLoading).toHaveBeenCalledWith(true); + expect(spyLoadPageAsset).toHaveBeenCalledWith({ + language_id: dotcmsContentletMock.languageId.toString(), + url: dotcmsContentletMock.url + }); expect(spyMessage).toHaveBeenCalledTimes(2); // Check the first message @@ -199,6 +233,29 @@ describe('DotUveWorkflowActionsComponent', () => { }); }); + it('should fire workflow actions and reloadPage', () => { + const spySetWorkflowActionLoading = jest.spyOn(store, 'setWorkflowActionLoading'); + const spyReloadCurrentPage = jest.spyOn(store, 'reloadCurrentPage'); + const dotWorkflowActionsComponent = spectator.query(DotWorkflowActionsComponent); + const spy = jest + .spyOn(dotWorkflowActionsFireService, 'fireTo') + .mockReturnValue(of({ ...dotcmsContentletMock, ...pageParams })); + + dotWorkflowActionsComponent.actionFired.emit({ + ...mockWorkflowsActions[0], + actionInputs: [] + }); + + expect(spy).toHaveBeenCalledWith({ + inode: expectedInode, + actionId: mockWorkflowsActions[0].id, + data: undefined + }); + + expect(spySetWorkflowActionLoading).toHaveBeenCalledWith(true); + expect(spyReloadCurrentPage).toHaveBeenCalledWith(); + }); + it('should open Wizard if it has inputs ', () => { const output$ = new Subject(); @@ -207,9 +264,6 @@ describe('DotUveWorkflowActionsComponent', () => { title: 'title' }; - jest.spyOn(dotWorkflowEventHandlerService, 'containsPushPublish').mockReturnValue( - false - ); jest.spyOn(dotWorkflowEventHandlerService, 'setWizardInput').mockReturnValue( wizardInputMock ); @@ -236,7 +290,7 @@ describe('DotUveWorkflowActionsComponent', () => { workflowActionMock.actionInputs ); expect(spyFireTo).toHaveBeenCalledWith({ - inode: '123', + inode: expectedInode, actionId: workflowActionMock.id, data: DOT_PROCESSED_WORKFLOW_PAYLOAD_MOCK }); @@ -272,44 +326,4 @@ describe('DotUveWorkflowActionsComponent', () => { expect(spyWizard).not.toHaveBeenCalled(); }); }); - - // describe('dot-uve-workflow-actions', () => { - // it('should have attr', () => { - // const workflowActions = spectator.query(DotUveWorkflowActionsComponent); - - // expect(workflowActions.inode).toBe('123-i'); - // }); - - // it('should update page', () => { - // const spyloadPageAsset = jest.spyOn(store, 'loadPageAsset'); - // spectator.triggerEventHandler(DotUveWorkflowActionsComponent, 'newPage', { - // pageURI: '/path-and-stuff', - // url: 'path', - // languageId: 1 - // // eslint-disable-next-line @typescript-eslint/no-explicit-any - // } as any); - - // spectator.detectChanges(); - - // expect(spyloadPageAsset).toHaveBeenCalledWith({ - // url: '/path-and-stuff', - // language_id: '1' - // }); - // }); - - // // it('should trigger a store reload if the URL from urlContentMap is the same as the current URL', () => { - // // jest.spyOn(store, 'pageAPIResponse').mockReturnValue(PAGE_RESPONSE_URL_CONTENT_MAP); - - // // spectator.triggerEventHandler(DotUveWorkflowActionsComponent, 'newPage', { - // // pageURI: '/test-url', - // // url: '/test-url', - // // languageId: 1 - // // // eslint-disable-next-line @typescript-eslint/no-explicit-any - // // } as any); - - // // spectator.detectChanges(); - // // expect(store.reloadCurrentPage).toHaveBeenCalled(); - // // expect(router.navigate).not.toHaveBeenCalled(); - // // }); - // }); }); diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-workflow-actions/dot-uve-workflow-actions.component.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-workflow-actions/dot-uve-workflow-actions.component.ts index 73a0ddb52ed..2a23808dc50 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-workflow-actions/dot-uve-workflow-actions.component.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-workflow-actions/dot-uve-workflow-actions.component.ts @@ -108,7 +108,7 @@ export class DotUveWorkflowActionsComponent { workflow: DotCMSWorkflowAction, data?: T ): void { - this.#uveStore.setWorflowActionLoading(true); + this.#uveStore.setWorkflowActionLoading(true); this.messageService.add({ ...this.successMessage, detail: this.dotMessageService.get('edit.ema.page.executing.workflow.action'), diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/edit-ema-toolbar/edit-ema-toolbar.component.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/edit-ema-toolbar/edit-ema-toolbar.component.ts index 84b2b0bc2f9..6f059eb73aa 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/edit-ema-toolbar/edit-ema-toolbar.component.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/edit-ema-toolbar/edit-ema-toolbar.component.ts @@ -77,8 +77,6 @@ export class EditEmaToolbarComponent { readonly uveStore = inject(UVEStore); protected readonly $toolbarProps = this.uveStore.$toolbarProps; - protected readonly $actions = this.uveStore.workflowActions; - protected readonly $workflowLoding = this.uveStore.workflowLoading; /** * Update the current device diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/workflow/withWorkflow.spec.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/workflow/withWorkflow.spec.ts index c20c578754f..f1bafa1e07a 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/workflow/withWorkflow.spec.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/workflow/withWorkflow.spec.ts @@ -84,7 +84,7 @@ describe('withLoad', () => { }); it('should set workflowLoading to true', () => { - store.setWorflowActionLoading(true); + store.setWorkflowActionLoading(true); expect(store.workflowLoading()).toBe(true); }); }); diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/workflow/withWorkflow.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/workflow/withWorkflow.ts index 78f813eacd0..1827f86a042 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/workflow/withWorkflow.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/workflow/withWorkflow.ts @@ -70,7 +70,7 @@ export function withWorkflow() { }) ) ), - setWorflowActionLoading: (loading: boolean) => { + setWorkflowActionLoading: (loading: boolean) => { patchState(store, { workflowLoading: loading }); diff --git a/dotCMS/src/main/webapp/html/portlet/ext/contentlet/edit_contentlet_js_inc.jsp b/dotCMS/src/main/webapp/html/portlet/ext/contentlet/edit_contentlet_js_inc.jsp index 54c9b0bd033..26ba7e0d63a 100644 --- a/dotCMS/src/main/webapp/html/portlet/ext/contentlet/edit_contentlet_js_inc.jsp +++ b/dotCMS/src/main/webapp/html/portlet/ext/contentlet/edit_contentlet_js_inc.jsp @@ -943,7 +943,7 @@ } - function stealLock(contentletInode){ + function stealLock(contentletInode){ ContentletAjax.unlockContent(contentletInode, stealLockContentCallback); }