From 29b4190888014ea54290ec57527979cdfb9cba4d Mon Sep 17 00:00:00 2001 From: Dharan <14145706+dhrn@users.noreply.github.com> Date: Wed, 28 Jul 2021 16:06:07 +0530 Subject: [PATCH] [ACS-1767] [ADF] - Convert C329803 and C329800 cases (#7170) --- .../form/attach-form-component.e2e.ts | 39 +++++++ .../pages/attach-form.page.ts | 4 + .../tasks/standalone-task.e2e.ts | 61 ++++++++-- .../src/lib/mock/task/task-details.mock.ts | 40 +++++++ .../task-form/task-form.component.spec.ts | 107 ++++++++++++++---- .../protractor/core/pages/form/form-fields.ts | 4 + 6 files changed, 229 insertions(+), 26 deletions(-) diff --git a/e2e/process-services/form/attach-form-component.e2e.ts b/e2e/process-services/form/attach-form-component.e2e.ts index b2537a1eba..9027718bf2 100644 --- a/e2e/process-services/form/attach-form-component.e2e.ts +++ b/e2e/process-services/form/attach-form-component.e2e.ts @@ -57,6 +57,13 @@ describe('Attach Form Component', () => { formFieldValue: 'Test value' }; + const standaloneTask = { + taskName: 'Standalone Task', + formTitle: 'Select Form To Attach', + formName: 'Simple form', + widgetTitle: 'textfield' + }; + beforeAll(async () => { await apiService.loginWithProfile('admin'); @@ -69,6 +76,7 @@ describe('Attach Form Component', () => { appModel = await applicationService.importPublishDeployApp(app.file_path); await taskUtil.createStandaloneTask(testNames.taskName); + await taskUtil.createStandaloneTask(standaloneTask.taskName); await loginPage.login(user.username, user.password); }); @@ -126,4 +134,35 @@ describe('Attach Form Component', () => { await expect(await formFields.getFieldValue(formTextField)).toEqual(testNames.formFieldValue); }); + + it('[C329804] Attach form from standalone task with no form template', async () => { + await (await (await navigationBarPage.navigateToProcessServicesPage()).goToTaskApp()).clickTasksButton(); + + await taskPage.filtersPage().goToFilter(CONSTANTS.TASK_FILTERS.MY_TASKS); + await taskPage.tasksListPage().selectRow(standaloneTask.taskName); + + await taskPage.taskDetails().clickAttachFormButton(); + await attachFormPage.checkDefaultFormTitleIsDisplayed(standaloneTask.formTitle); + await attachFormPage.checkCancelButtonIsDisplayed(); + await attachFormPage.checkAttachFormButtonIsDisabled(); + await attachFormPage.openDropDownForms(); + await attachFormPage.checkFormDropdownIsDisplayed(); + await attachFormPage.selectAttachFormOption(standaloneTask.formName); + await formFields.checkWidgetIsReadOnlyMode(standaloneTask.widgetTitle); + await attachFormPage.clickCancelButton(); + + await taskPage.taskDetails().checkAttachFormButtonIsDisplayed(); + + await taskDetailsPage.clickAttachFormButton(); + await attachFormPage.checkDefaultFormTitleIsDisplayed(standaloneTask.formTitle); + await attachFormPage.checkCancelButtonIsDisplayed(); + await attachFormPage.checkAttachFormButtonIsDisabled(); + await attachFormPage.openDropDownForms(); + await attachFormPage.checkFormDropdownIsDisplayed(); + await attachFormPage.selectAttachFormOption(standaloneTask.formName); + await formFields.checkWidgetIsReadOnlyMode(standaloneTask.widgetTitle); + await attachFormPage.clickAttachFormButton(); + + await taskPage.taskDetails().checkAttachFormButtonIsNotDisplayed(); + }); }); diff --git a/e2e/process-services/pages/attach-form.page.ts b/e2e/process-services/pages/attach-form.page.ts index dc16bb989b..03917ec103 100644 --- a/e2e/process-services/pages/attach-form.page.ts +++ b/e2e/process-services/pages/attach-form.page.ts @@ -49,6 +49,10 @@ export class AttachFormPage { await expect(result).toEqual(formTitle); } + async openDropDownForms(): Promise { + await BrowserActions.click(this.formDropdown); + } + async checkFormDropdownIsDisplayed(): Promise { await BrowserVisibility.waitUntilElementIsVisible(this.formDropdown); } diff --git a/e2e/process-services/tasks/standalone-task.e2e.ts b/e2e/process-services/tasks/standalone-task.e2e.ts index 146ef28ce8..de3ceeec39 100644 --- a/e2e/process-services/tasks/standalone-task.e2e.ts +++ b/e2e/process-services/tasks/standalone-task.e2e.ts @@ -17,12 +17,19 @@ import { browser } from 'protractor'; -import { createApiService, ApplicationsUtil, LoginPage, UsersActions } from '@alfresco/adf-testing'; +import { + ApplicationsUtil, + BrowserVisibility, + createApiService, + LoginPage, UserModel, + UsersActions, + Widget +} from '@alfresco/adf-testing'; import { TasksPage } from './../pages/tasks.page'; import { NavigationBarPage } from '../../core/pages/navigation-bar.page'; +import { TaskActionsApi, TasksApi } from '@alfresco/js-api'; import CONSTANTS = require('../../util/constants'); import Task = require('../../models/APS/Task'); -import { TaskActionsApi, TasksApi } from '@alfresco/js-api'; describe('Start Task - Task App', () => { @@ -31,8 +38,9 @@ describe('Start Task - Task App', () => { const loginPage = new LoginPage(); const navigationBarPage = new NavigationBarPage(); const taskPage = new TasksPage(); + const widget = new Widget(); - let processUserModel; + let processUserModel, anotherUser; const noFormMessage = 'No forms attached'; const apiService = createApiService(); @@ -44,20 +52,22 @@ describe('Start Task - Task App', () => { beforeAll(async () => { await apiService.loginWithProfile('admin'); processUserModel = await usersActions.createUser(); - + anotherUser = await usersActions.createUser(new UserModel({ tenantId: processUserModel.tenantId })); await apiService.login(processUserModel.username, processUserModel.password); await applicationUtil.importApplication(app.file_path); - - await loginPage.login(processUserModel.username, processUserModel.password); }); beforeEach(async () => { - await browser.refresh(); + await loginPage.login(processUserModel.username, processUserModel.password); await (await (await navigationBarPage.navigateToProcessServicesPage()).goToTaskApp()).clickTasksButton(); await taskPage.filtersPage().goToFilter(CONSTANTS.TASK_FILTERS.MY_TASKS); }); + afterEach( async () => { + await navigationBarPage.clickLogoutButton(); + }); + it('[C260421] Should a standalone task be displayed when creating a new task without form', async () => { const task = await taskPage.createNewTask(); await task.addName('Standalone task'); @@ -131,4 +141,41 @@ describe('Start Task - Task App', () => { await taskPage.taskDetails().waitFormNameEqual(CONSTANTS.TASK_DETAILS.NO_FORM); await expect(await taskDetails.getNoFormMessage()).toEqual(noFormMessage); }); + + it('[C329799] Form actions are enabled in assigned task', async () => { + const taskName = 'Task on behalf of'; + const task = await taskPage.createNewTask(); + await task.addName(taskName); + await task.selectForm(app.formName); + await task.clickStartButton(); + await taskPage.tasksListPage().checkContentIsDisplayed(taskName); + await taskPage.tasksListPage().selectRow(taskName); + await taskPage.taskDetails().updateAssignee(`${anotherUser.firstName} ${anotherUser.lastName}`); + await taskPage.tasksListPage().getDataTable().waitTillContentLoaded(); + await navigationBarPage.clickLogoutButton(); + await loginPage.login(anotherUser.username, anotherUser.password); + await (await (await navigationBarPage.navigateToProcessServicesPage()).goToTaskApp()).clickTasksButton(); + + await taskPage.filtersPage().goToFilter(CONSTANTS.TASK_FILTERS.MY_TASKS); + await taskPage.tasksListPage().checkContentIsDisplayed(taskName); + await taskPage.tasksListPage().selectRow(taskName); + await taskPage.formFields().checkFormIsDisplayed(); + + await widget.textWidget().isWidgetVisible(app.form_fields.form_fieldId); + await widget.textWidget().setValue(app.form_fields.form_fieldId, 'value'); + + await expect(await taskPage.formFields().isSaveFormButtonEnabled()).toEqual(true); + await expect(await taskPage.formFields().isCompleteFormButtonEnabled()).toEqual(true); + await taskPage.formFields().completeForm(); + + await taskPage.filtersPage().goToFilter(CONSTANTS.TASK_FILTERS.COMPLETED_TASKS); + await taskPage.tasksListPage().checkContentIsDisplayed(taskName); + await taskPage.tasksListPage().selectRow(taskName); + await taskPage.formFields().checkFormIsDisplayed(); + + await expect(await widget.textWidget().getFieldValue(app.form_fields.form_fieldId)).toEqual('value'); + + await BrowserVisibility.waitUntilElementIsNotVisible(await taskPage.formFields().saveButton); + await expect(await taskPage.formFields().isCompleteFormButtonEnabled()).toEqual(false); + }); }); diff --git a/lib/process-services/src/lib/mock/task/task-details.mock.ts b/lib/process-services/src/lib/mock/task/task-details.mock.ts index 57557ee11b..6d1fa10b34 100644 --- a/lib/process-services/src/lib/mock/task/task-details.mock.ts +++ b/lib/process-services/src/lib/mock/task/task-details.mock.ts @@ -974,3 +974,43 @@ export const fakeUser = new UserRepresentation({ tenantPictureId: null, tenantName: 'abc' }); + +export const completedProcessTaskWithoutForm = new TaskDetailsModel({ + id: '49', + name: 'process task without form', + description: null, + category: null, + assignee: { + id: 3, + firstName: 'HR', + lastName: 'User', + email: 'hruser@example.com' + }, + created: '2021-07-08T07:39:27.046+0000', + dueDate: null, + endDate: '2021-07-08T07:39:35.817+0000', + duration: 8771, + priority: 0, + parentTaskId: null, + parentTaskName: null, + processInstanceId: '37', + processInstanceName: null, + processDefinitionId: 'process:1:36', + processDefinitionName: 'process', + processDefinitionDescription: null, + processDefinitionKey: 'process', + processDefinitionCategory: 'http://www.activiti.org/processdef', + processDefinitionVersion: 1, + processDefinitionDeploymentId: '34', + formKey: null, + processInstanceStartUserId: '3', + initiatorCanCompleteTask: false, + adhocTaskCanBeReassigned: false, + taskDefinitionKey: 'sid-1E90524A-8270-4031-89B6-5D18F414BFB8', + executionId: '41', + involvedPeople: [], + involvedGroups: [], + memberOfCandidateGroup: false, + memberOfCandidateUsers: false, + managerOfCandidateGroup: false +}); diff --git a/lib/process-services/src/lib/task-list/components/task-form/task-form.component.spec.ts b/lib/process-services/src/lib/task-list/components/task-form/task-form.component.spec.ts index 61667e3fa8..4d395395f4 100644 --- a/lib/process-services/src/lib/task-list/components/task-form/task-form.component.spec.ts +++ b/lib/process-services/src/lib/task-list/components/task-form/task-form.component.spec.ts @@ -19,33 +19,34 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { TaskFormComponent } from './task-form.component'; import { - setupTestBed, - FormService, AuthenticationService, FormModel, FormOutcomeEvent, - FormOutcomeModel + FormOutcomeModel, + FormService, + setupTestBed } from '@alfresco/adf-core'; import { TaskListService } from '../../services/tasklist.service'; import { NO_ERRORS_SCHEMA, SimpleChange } from '@angular/core'; import { of, throwError } from 'rxjs'; import { - taskFormMock, - taskDetailsMock, - completedTaskDetailsMock, - taskDetailsWithOutFormMock, - standaloneTaskWithoutForm, - completedStandaloneTaskWithoutForm, claimableTaskDetailsMock, - initiatorCanCompleteTaskDetailsMock, - taskDetailsWithOutCandidateGroup, - claimedTaskDetailsMock, claimedByGroupMemberMock, - initiatorWithCandidatesTaskDetailsMock, - involvedUserTaskForm, + claimedTaskDetailsMock, + completedProcessTaskWithoutForm, + completedStandaloneTaskWithoutForm, + completedTaskDetailsMock, + completedTaskWithFormMock, fakeUser, + initiatorCanCompleteTaskDetailsMock, + initiatorWithCandidatesTaskDetailsMock, involvedGroupTaskForm, - completedTaskWithFormMock + involvedUserTaskForm, + standaloneTaskWithoutForm, + taskDetailsMock, + taskDetailsWithOutCandidateGroup, + taskDetailsWithOutFormMock, + taskFormMock } from '../../../mock/task/task-details.mock'; import { TaskDetailsModel } from '../../models/task-details.model'; import { ProcessTestingModule } from '../../../testing/process.testing.module'; @@ -367,6 +368,36 @@ describe('TaskFormComponent', () => { cancelButtonElement.click(); expect(cancelSpy).toHaveBeenCalled(); }); + + it('Should display the template in a process task with no Form', async () => { + component.taskDetails = new TaskDetailsModel(taskDetailsWithOutFormMock); + fixture.detectChanges(); + await fixture.whenStable(); + let formMessage = fixture.debugElement.nativeElement.querySelector('.adf-empty-content__title'); + let subMessage = fixture.debugElement.nativeElement.querySelector('.adf-empty-content__subtitle'); + let completeButtonElement = fixture.debugElement.nativeElement.querySelector('#adf-no-form-complete-button'); + let cancelButton = fixture.debugElement.nativeElement.querySelector('#adf-no-form-cancel-button'); + expect(completeButtonElement['disabled']).toEqual(false); + expect(cancelButton['disabled']).toEqual(false); + expect(formMessage.innerText).toContain('ADF_TASK_LIST.STANDALONE_TASK.NO_FORM_MESSAGE'); + expect(subMessage.innerText).toContain('ADF_TASK_FORM.EMPTY_FORM.SUBTITLE'); + + completeButtonElement.click(); + component.taskDetails = new TaskDetailsModel(completedProcessTaskWithoutForm); + fixture.detectChanges(); + await fixture.whenStable(); + + formMessage = fixture.debugElement.nativeElement.querySelector('.adf-empty-content__title'); + subMessage = fixture.debugElement.nativeElement.querySelector('.adf-empty-content__subtitle'); + completeButtonElement = fixture.debugElement.nativeElement.querySelector('#adf-no-form-complete-button'); + cancelButton = fixture.debugElement.nativeElement.querySelector('#adf-no-form-cancel-button'); + expect(formMessage.innerText).toContain('ADF_TASK_FORM.COMPLETED_TASK.TITLE'); + expect(subMessage.innerText).toContain('ADF_TASK_FORM.COMPLETED_TASK.SUBTITLE'); + expect(cancelButton).not.toBeNull(); + expect(cancelButton['disabled']).toEqual(false, 'cancel button not visible for completed task'); + expect(completeButtonElement).toBeNull('complete button shown for completed task'); + expect(taskListService.completeTask).toHaveBeenCalled(); + }); }); describe('Standalone Task with no form', () => { @@ -376,7 +407,7 @@ describe('TaskFormComponent', () => { fixture.detectChanges(); }); - it('Should be able to display empty template in case standalone task does not attached a form', async () => { + it('Should display empty template in case standalone task does not attached a form', async () => { component.taskDetails = new TaskDetailsModel(standaloneTaskWithoutForm); fixture.detectChanges(); await fixture.whenStable(); @@ -397,7 +428,7 @@ describe('TaskFormComponent', () => { expect(showAttachFormSpy).toHaveBeenCalled(); }); - it('Should be able to display completed template if standalone task completed', async() => { + it('Should display completed template if standalone task completed', async() => { component.taskDetails = completedStandaloneTaskWithoutForm; fixture.detectChanges(); await fixture.whenStable(); @@ -408,9 +439,35 @@ describe('TaskFormComponent', () => { expect(completedFormMessage.innerText).toContain('ADF_TASK_LIST.STANDALONE_TASK.COMPLETE_TASK_MESSAGE'); expect(subMessage.innerText).toContain('ADF_TASK_LIST.STANDALONE_TASK.COMPLETE_TASK_SUB_MESSAGE'); }); + + it('Should display the template in a standalone task with no Form', async () => { + component.taskDetails = standaloneTaskWithoutForm; + component.currentLoggedUser = standaloneTaskWithoutForm.assignee; + fixture.detectChanges(); + await fixture.whenStable(); + let formMessage = fixture.debugElement.nativeElement.querySelector('.adf-no-form-message'); + let completeButtonElement = fixture.debugElement.nativeElement.querySelector('#adf-no-form-complete-button'); + let attacheFormButton = fixture.debugElement.nativeElement.querySelector('#adf-no-form-attach-form-button'); + expect(completeButtonElement['disabled']).toEqual(false); + expect(attacheFormButton['disabled']).toEqual(false); + expect(formMessage.innerText).toContain('ADF_TASK_LIST.STANDALONE_TASK.NO_FORM_MESSAGE'); + + completeButtonElement.click(); + component.taskDetails = new TaskDetailsModel(completedStandaloneTaskWithoutForm); + fixture.detectChanges(); + await fixture.whenStable(); + + formMessage = fixture.debugElement.nativeElement.querySelector('.adf-no-form-message'); + completeButtonElement = fixture.debugElement.nativeElement.querySelector('#adf-no-form-complete-button'); + attacheFormButton = fixture.debugElement.nativeElement.querySelector('#adf-no-form-attach-form-button'); + expect(formMessage.innerText).toContain('ADF_TASK_LIST.STANDALONE_TASK.COMPLETE_TASK_MESSAGE'); + expect(attacheFormButton).toBeNull('attach form button shown for completed task'); + expect(completeButtonElement).toBeNull('complete button shown for completed task'); + expect(taskListService.completeTask).toHaveBeenCalled(); + }); }); - describe('Form with visiblity', () => { + describe('Form with visibility', () => { beforeEach(async () => { component.taskId = '123'; @@ -743,9 +800,10 @@ describe('TaskFormComponent', () => { beforeEach(() => { component.taskId = '20259'; + spyOn(formService, 'saveTaskForm').and.returnValue(of({})); }); - it('Should be able to save a form for a involved user', async() => { + it('[T14599423] Form in unassigned task is read-only', async () => { getTaskDetailsSpy.and.returnValue(of(involvedUserTaskForm)); fixture.detectChanges(); await fixture.whenStable(); @@ -757,6 +815,15 @@ describe('TaskFormComponent', () => { expect(completeButton.disabled).toEqual(true); }); + it('Should be able to save a form for a involved user', async() => { + getTaskDetailsSpy.and.returnValue(of(involvedUserTaskForm)); + fixture.detectChanges(); + await fixture.whenStable(); + const saveButton = fixture.debugElement.nativeElement.querySelector('[id="adf-form-save"]'); + saveButton.click(); + expect(formService.saveTaskForm).toHaveBeenCalled(); + }); + it('Should be able to save a form for a involved group user', async() => { getTaskDetailsSpy.and.returnValue(of(involvedGroupTaskForm)); fixture.detectChanges(); @@ -767,6 +834,8 @@ describe('TaskFormComponent', () => { expect(activitFormSelector).toBeDefined(); expect(saveButton.disabled).toEqual(false); expect(completeButton.disabled).toEqual(true); + saveButton.click(); + expect(formService.saveTaskForm).toHaveBeenCalled(); }); }); diff --git a/lib/testing/src/lib/protractor/core/pages/form/form-fields.ts b/lib/testing/src/lib/protractor/core/pages/form/form-fields.ts index 4bdddd0109..98c5ef79c3 100644 --- a/lib/testing/src/lib/protractor/core/pages/form/form-fields.ts +++ b/lib/testing/src/lib/protractor/core/pages/form/form-fields.ts @@ -221,6 +221,10 @@ export class FormFields { } } + async isSaveFormButtonEnabled(): Promise { + return this.saveButton.isEnabled(); + } + async isCompleteFormButtonEnabled(): Promise { return this.completeButton.isEnabled(); }