From 152e7805bc42f59bb44d2c60a5246e67e8cc0ce8 Mon Sep 17 00:00:00 2001 From: Deepak Paul Date: Wed, 2 Aug 2017 22:02:47 +0530 Subject: [PATCH] [ADF-1143] [TaskList] - Not able to start a task when changing the assignee from the 'Start Task' form (#2164) * [ADF-1143] [TaskList] - Not able to start a task when changing the assignee from the 'Start Task' form * Create task has been split into three diffrent service calls to replicate the ecxact behaviour of APS * Current API call sequence is create-task -> attach-form -> assign-user * Added a new service assign task * Modified tests according to the API calls * [ADF-1143] [TaskList] - Not able to start a task when changing the assignee from the 'Start Task' form * Added responsive behaviour for APIs * [ADF-1143] [TaskList] - Not able to start a task when changing the assignee from the 'Start Task' form *Code refactoring --- .../src/assets/start-task.mock.ts | 4 +- .../src/assets/tasklist-service.mock.ts | 22 +-- .../src/components/start-task.component.html | 4 +- .../components/start-task.component.spec.ts | 166 ++++++++++++------ .../src/components/start-task.component.ts | 65 ++++--- .../src/services/tasklist.service.spec.ts | 45 ++++- .../src/services/tasklist.service.ts | 18 ++ 7 files changed, 224 insertions(+), 100 deletions(-) diff --git a/ng2-components/ng2-activiti-tasklist/src/assets/start-task.mock.ts b/ng2-components/ng2-activiti-tasklist/src/assets/start-task.mock.ts index eb1f153c13..01d36610e0 100644 --- a/ng2-components/ng2-activiti-tasklist/src/assets/start-task.mock.ts +++ b/ng2-components/ng2-activiti-tasklist/src/assets/start-task.mock.ts @@ -18,9 +18,9 @@ export let startTaskMock = { 'name': 'fakeName', 'description': 'fakeDescription', - 'assignee': {'id': 2001, 'firstName': 'Jhon', 'lastName': 'Adams', 'email': 'jhon@app.activiti.com'}, + 'assignee': null, 'dueDate': '2017-11-03T15:25:42.749+0000', - 'formKey': '11201', + 'formKey': null, 'category': 'fakeAppId' }; diff --git a/ng2-components/ng2-activiti-tasklist/src/assets/tasklist-service.mock.ts b/ng2-components/ng2-activiti-tasklist/src/assets/tasklist-service.mock.ts index ce831dd17b..b903d79207 100644 --- a/ng2-components/ng2-activiti-tasklist/src/assets/tasklist-service.mock.ts +++ b/ng2-components/ng2-activiti-tasklist/src/assets/tasklist-service.mock.ts @@ -68,14 +68,16 @@ export let fakeFilterWithProcessDefinitionKey = { sort: 'created-desc', text: '', state: 'open', assignment: 'fake-assignee', processDefinitionKey: '1' }; -export let fakeUser = { id: 1, email: 'fake-email@dom.com', firstName: 'firstName', lastName: 'lastName' }; +export let fakeUser1 = { id: 1, email: 'fake-email@dom.com', firstName: 'firstName', lastName: 'lastName' }; + +export let fakeUser2 = { id: 1001, email: 'some-one@somegroup.com', firstName: 'some', lastName: 'one' }; export let fakeTaskList = { size: 1, total: 1, start: 0, data: [ { id: '1', name: 'FakeNameTask', description: null, category: null, - assignee: fakeUser, + assignee: fakeUser1, created: '2016-07-15T11:19:17.440+0000' } ] @@ -86,13 +88,13 @@ export let fakeTaskListDifferentProcessDefinitionKey = { data: [ { id: '1', name: 'FakeNameTask', description: null, category: null, - assignee: fakeUser, + assignee: fakeUser1, processDefinitionKey: '1', created: '2016-07-15T11:19:17.440+0000' }, { id: '2', name: 'FakeNameTask2', description: null, category: null, - assignee: fakeUser, + assignee: fakeUser1, processDefinitionKey: '2', created: '2016-07-15T11:19:17.440+0000' } @@ -104,7 +106,7 @@ export let secondFakeTaskList = { data: [ { id: '200', name: 'FakeNameTask', description: null, category: null, - assignee: fakeUser, + assignee: fakeUser1, created: '2016-07-15T11:19:17.440+0000' } ] @@ -114,16 +116,16 @@ export let fakeErrorTaskList = { error: 'wrong request' }; -export let fakeTaskDetails = { id: '999', name: 'fake-task-name', formKey: '99', assignee: fakeUser }; +export let fakeTaskDetails = { id: '999', name: 'fake-task-name', formKey: '99', assignee: fakeUser1 }; export let fakeTasksComment = { size: 2, total: 2, start: 0, data: [ { - id: 1, message: 'fake-message-1', created: '', createdBy: fakeUser + id: 1, message: 'fake-message-1', created: '', createdBy: fakeUser1 }, { - id: 2, message: 'fake-message-2', created: '', createdBy: fakeUser + id: 2, message: 'fake-message-2', created: '', createdBy: fakeUser1 } ] }; @@ -133,12 +135,12 @@ export let fakeTasksChecklist = { data: [ { id: 1, name: 'FakeCheckTask1', description: null, category: null, - assignee: fakeUser, + assignee: fakeUser1, created: '2016-07-15T11:19:17.440+0000' }, { id: 2, name: 'FakeCheckTask2', description: null, category: null, - assignee: fakeUser, + assignee: fakeUser1, created: '2016-07-15T11:19:17.440+0000' } ] diff --git a/ng2-components/ng2-activiti-tasklist/src/components/start-task.component.html b/ng2-components/ng2-activiti-tasklist/src/components/start-task.component.html index 600b613484..a717e038c6 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/start-task.component.html +++ b/ng2-components/ng2-activiti-tasklist/src/components/start-task.component.html @@ -34,7 +34,7 @@ - + {{'START_TASK.FORM.LABEL.NONE'|translate}} {{ getDisplayUser(user.firstName, user.lastName, ' ')}} @@ -44,7 +44,7 @@ - + {{'START_TASK.FORM.LABEL.NONE'|translate}} {{ form.name }} diff --git a/ng2-components/ng2-activiti-tasklist/src/components/start-task.component.spec.ts b/ng2-components/ng2-activiti-tasklist/src/components/start-task.component.spec.ts index 58b23835ad..a5ac2b6d2c 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/start-task.component.spec.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/start-task.component.spec.ts @@ -20,6 +20,7 @@ import { MdButtonModule, MdDatepickerModule, MdGridListModule, MdIconModule, MdI import { AlfrescoTranslationService, CoreModule } from 'ng2-alfresco-core'; import { Observable } from 'rxjs/Rx'; import { StartTaskModel } from '../models/start-task.model'; +import { User } from '../models/user.model'; import { PeopleService } from '../services/people.service'; import { TaskListService } from '../services/tasklist.service'; import { startTaskMock } from './../assets/start-task.mock'; @@ -34,9 +35,11 @@ describe('StartTaskComponent', () => { let service: TaskListService; let peopleService: PeopleService; let element: HTMLElement; - let getformlistSpy: jasmine.Spy; + let getFormlistSpy: jasmine.Spy; let getWorkflowUsersSpy: jasmine.Spy; - let getcreateNewTaskSpy: jasmine.Spy; + let createNewTaskSpy: jasmine.Spy; + let attachFormSpy: jasmine.Spy; + let assignUserSpy: jasmine.Spy; let fakeForms = [ { id: 123, @@ -47,6 +50,7 @@ describe('StartTaskComponent', () => { name: 'Employee Info' } ]; + let testUser = {id: 1001, firstName: 'fakeName', email: 'fake@app.activiti.com'}; beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ @@ -81,7 +85,7 @@ describe('StartTaskComponent', () => { beforeEach(() => { service = fixture.debugElement.injector.get(TaskListService); peopleService = fixture.debugElement.injector.get(PeopleService); - getformlistSpy = spyOn(service, 'getFormList').and.returnValue(Observable.of(fakeForms)); + getFormlistSpy = spyOn(service, 'getFormList').and.returnValue(Observable.of(fakeForms)); getWorkflowUsersSpy = spyOn(peopleService, 'getWorkflowUsers').and.returnValue(Observable.of([ { id: 1, @@ -111,37 +115,30 @@ describe('StartTaskComponent', () => { expect(activitiStartTaskComponent.forms[0].name).toEqual('Display Data'); expect(activitiStartTaskComponent.forms[1].name).toEqual('Employee Info'); expect(activitiStartTaskComponent.forms[1].id).toEqual(1111); - expect(getformlistSpy).toHaveBeenCalled(); + expect(getFormlistSpy).toHaveBeenCalled(); }); describe('create task', () => { beforeEach(() => { - jasmine.Ajax.install(); - getcreateNewTaskSpy = spyOn(service, 'createNewTask').and.returnValue(Observable.of( + createNewTaskSpy = spyOn(service, 'createNewTask').and.returnValue(Observable.of( { id: 91, name: 'fakeName', - formKey: '4', - assignee: {id: 1001, firstName: 'fakeName', email: 'fake@app.activiti.com'} + formKey: null, + assignee: null } )); }); - afterEach(() => { - jasmine.Ajax.uninstall(); - }); - it('should create new task when start is clicked', async(() => { activitiStartTaskComponent.success.subscribe((res) => { expect(res).toBeDefined(); }); activitiStartTaskComponent.appId = 'fakeAppId'; activitiStartTaskComponent.startTaskmodel = new StartTaskModel(startTaskMock); - activitiStartTaskComponent.start(); - jasmine.Ajax.requests.mostRecent().respondWith({ - 'status': 200 - }); + let createTaskButton = element.querySelector('#button-start'); + createTaskButton.click(); })); it('should send on success event when the task is started', async(() => { @@ -149,30 +146,13 @@ describe('StartTaskComponent', () => { expect(res).toBeDefined(); expect(res.id).toBe(91); expect(res.name).toBe('fakeName'); - expect(res.formKey).toBe('4'); - expect(res.assignee.id).toBe(1001); + expect(res.formKey).toBe(null); + expect(res.assignee).toBe(null); }); activitiStartTaskComponent.appId = 'fakeAppId'; activitiStartTaskComponent.startTaskmodel = new StartTaskModel(startTaskMock); - activitiStartTaskComponent.start(); - jasmine.Ajax.requests.mostRecent().respondWith({ - 'status': 200, - contentType: 'json', - responseText: - { - id: '91', - name: 'fakeName', - description: 'fakeDescription', - formKey: '4', - assignee: {id: 1001, firstName: 'fakeName', email: 'fake@app.activiti.com'}, - dueDate: null, - endDate: null, - duration: null, - priority: 50, - parentTaskId: null, - parentTaskName: null - } - }); + let createTaskButton = element.querySelector('#button-start'); + createTaskButton.click(); })); it('should send on success event when only name is given', async(() => { @@ -181,36 +161,108 @@ describe('StartTaskComponent', () => { }); activitiStartTaskComponent.appId = 'fakeAppId'; activitiStartTaskComponent.startTaskmodel.name = 'fakeName'; - activitiStartTaskComponent.startTaskmodel = new StartTaskModel(startTaskMock); - activitiStartTaskComponent.start(); - jasmine.Ajax.requests.mostRecent().respondWith({ - 'status': 200, - contentType: 'json', - responseText: {} - }); + let createTaskButton = element.querySelector('#button-start'); + createTaskButton.click(); })); - it('should attach a task when a form id selected', () => { - activitiStartTaskComponent.success.subscribe((res) => { - expect(res).toBeDefined(); - expect(res.formKey).toBe('4'); - }); - activitiStartTaskComponent.appId = 'fakeAppId'; - activitiStartTaskComponent.startTaskmodel = new StartTaskModel(startTaskMock); - activitiStartTaskComponent.start(); - expect(getcreateNewTaskSpy).toHaveBeenCalled(); - }); - it('should not emit success event when data not present', async(() => { let successSpy: jasmine.Spy = spyOn(activitiStartTaskComponent.success, 'emit'); activitiStartTaskComponent.startTaskmodel = new StartTaskModel(null); - activitiStartTaskComponent.start(); + let createTaskButton = element.querySelector('#button-start'); + createTaskButton.click(); fixture.detectChanges(); - expect(getcreateNewTaskSpy).not.toHaveBeenCalled(); + expect(createNewTaskSpy).not.toHaveBeenCalled(); expect(successSpy).not.toHaveBeenCalled(); })); }); + describe('assign form', () => { + beforeEach(() => { + attachFormSpy = spyOn(service, 'attachFormToATask').and.returnValue(Observable.of( + { + id: 91, + name: 'fakeName', + formKey: 1204, + assignee: null + } + )); + }); + + it('should attach form to the task when a form is selected', () => { + activitiStartTaskComponent.success.subscribe((res) => { + expect(res).toBeDefined(); + expect(res.id).toBe(91); + expect(res.name).toBe('fakeName'); + expect(res.formKey).toBe(1204); + expect(res.assignee).toBe(null); + }); + activitiStartTaskComponent.appId = 'fakeAppId'; + activitiStartTaskComponent.formKey = 1204; + activitiStartTaskComponent.startTaskmodel = new StartTaskModel(startTaskMock); + let createTaskButton = element.querySelector('#button-start'); + createTaskButton.click(); + }); + + it('should not attach form to the task when a no form is selected', () => { + activitiStartTaskComponent.success.subscribe((res) => { + expect(res).toBeDefined(); + expect(res.id).toBe(91); + expect(res.name).toBe('fakeName'); + expect(res.formKey).toBe(null); + }); + activitiStartTaskComponent.appId = 'fakeAppId'; + activitiStartTaskComponent.formKey = null; + activitiStartTaskComponent.startTaskmodel = new StartTaskModel(startTaskMock); + let createTaskButton = element.querySelector('#button-start'); + createTaskButton.click(); + }); + }); + + describe('assign task', () => { + beforeEach(() => { + assignUserSpy = spyOn(service, 'assignTask').and.returnValue(Observable.of( + { + id: 91, + name: 'fakeName', + formKey: 1204, + assignee: testUser + } + )); + }); + + it('should assign task when an assignee is selected', () => { + activitiStartTaskComponent.success.subscribe((res) => { + expect(res).toBeDefined(); + expect(res.id).toBe(91); + expect(res.name).toBe('fakeName'); + expect(res.formKey).toBe(1204); + expect(res.assignee).toBe(testUser); + }); + activitiStartTaskComponent.appId = 'fakeAppId'; + activitiStartTaskComponent.formKey = 1204; + activitiStartTaskComponent.assignee = new User(testUser); + activitiStartTaskComponent.startTaskmodel = new StartTaskModel(startTaskMock); + let createTaskButton = element.querySelector('#button-start'); + createTaskButton.click(); + }); + + it('should not assign task when no assignee is selected', () => { + activitiStartTaskComponent.success.subscribe((res) => { + expect(res).toBeDefined(); + expect(res.id).toBe(91); + expect(res.name).toBe('fakeName'); + expect(res.formKey).toBe(1204); + expect(res.assignee).toBe(null); + }); + activitiStartTaskComponent.appId = 'fakeAppId'; + activitiStartTaskComponent.formKey = 1204; + activitiStartTaskComponent.assignee = null; + activitiStartTaskComponent.startTaskmodel = new StartTaskModel(startTaskMock); + let createTaskButton = element.querySelector('#button-start'); + createTaskButton.click(); + }); + }); + it('should not attach a task when a form id is not slected', () => { let attachFormToATask = spyOn(service, 'attachFormToATask').and.returnValue(Observable.of()); spyOn(service, 'createNewTask').and.callFake( diff --git a/ng2-components/ng2-activiti-tasklist/src/components/start-task.component.ts b/ng2-components/ng2-activiti-tasklist/src/components/start-task.component.ts index 3f7c41d93e..3c2677856d 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/start-task.component.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/start-task.component.ts @@ -17,6 +17,7 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { AlfrescoTranslationService, LogService } from 'ng2-alfresco-core'; +import { Observable } from 'rxjs/Rx'; import { Form } from '../models/form.model'; import { StartTaskModel } from '../models/start-task.model'; import { TaskDetailsModel } from '../models/task-details.model'; @@ -43,11 +44,17 @@ export class StartTaskComponent implements OnInit { @Output() error: EventEmitter = new EventEmitter(); - people: User [] = []; + people: User[] = []; startTaskmodel: StartTaskModel = new StartTaskModel(); - forms: Form []; + forms: Form[]; + + assignee: any; + + formKey: number; + + taskId: string; /** * Constructor @@ -70,48 +77,58 @@ export class StartTaskComponent implements OnInit { this.getUsers(); } - public start() { + public start(): void { if (this.startTaskmodel.name) { this.startTaskmodel.category = this.appId; - this.taskService.createNewTask(new TaskDetailsModel(this.startTaskmodel)).subscribe( + this.taskService.createNewTask(new TaskDetailsModel(this.startTaskmodel)) + .switchMap((createRes: any) => + this.attachForm(createRes.id, this.formKey).defaultIfEmpty(createRes) + .switchMap((attachRes: any) => + this.assignTask(createRes.id, this.assignee).defaultIfEmpty(attachRes ? attachRes : createRes) + ) + ) + .subscribe( (res: any) => { this.success.emit(res); - this.attachForm(res.id); - this.resetForm(); }, (err) => { this.error.emit(err); - this.logService.error('An error occurred while trying to add the task'); - } - ); + this.logService.error('An error occurred while creating new task'); + }); } } - private attachForm(taskId: string) { - if (this.startTaskmodel.formKey && taskId) { - this.taskService.attachFormToATask(taskId, Number(this.startTaskmodel.formKey)); + private attachForm(taskId: string, formKey: number): Observable { + let response = Observable.of(); + if (taskId && formKey) { + response = this.taskService.attachFormToATask(taskId, formKey); } + return response; } - public onCancel() { + private assignTask(taskId: string, assignee: any): Observable { + let response = Observable.of(); + if (taskId && assignee) { + response = this.taskService.assignTask(taskId, assignee); + } + return response; + } + + public onCancel(): void { this.cancel.emit(); } - private loadFormsTask() { + private loadFormsTask(): void { this.taskService.getFormList().subscribe((res: Form[]) => { - this.forms = res; - }, + this.forms = res; + }, (err) => { this.error.emit(err); this.logService.error('An error occurred while trying to get the forms'); }); } - private resetForm() { - this.startTaskmodel = null; - } - - private getUsers() { + private getUsers(): void { this.peopleService.getWorkflowUsers().subscribe((users) => { this.people = users; }, (err) => { @@ -120,15 +137,15 @@ export class StartTaskComponent implements OnInit { }); } - isUserNameEmpty(user: any) { + public isUserNameEmpty(user: any): boolean { return !user || (this.isEmpty(user.firstName) && this.isEmpty(user.lastName)); } - private isEmpty(data: string) { + private isEmpty(data: string): boolean { return data === undefined || data === null || data.trim().length === 0; } - getDisplayUser(firstName: string, lastName: string, delimiter: string = '-'): string { + public getDisplayUser(firstName: string, lastName: string, delimiter: string = '-'): string { firstName = (firstName !== null ? firstName : ''); lastName = (lastName !== null ? lastName : ''); return firstName + delimiter + lastName; diff --git a/ng2-components/ng2-activiti-tasklist/src/services/tasklist.service.spec.ts b/ng2-components/ng2-activiti-tasklist/src/services/tasklist.service.spec.ts index 515ea2441b..646b1feef8 100644 --- a/ng2-components/ng2-activiti-tasklist/src/services/tasklist.service.spec.ts +++ b/ng2-components/ng2-activiti-tasklist/src/services/tasklist.service.spec.ts @@ -33,12 +33,14 @@ import { fakeTaskListDifferentProcessDefinitionKey, fakeTasksChecklist, fakeTasksComment, - fakeUser, + fakeUser1, + fakeUser2, secondFakeTaskList } from '../assets/tasklist-service.mock'; import { Comment } from '../models/comment.model'; import { FilterRepresentationModel, TaskQueryRequestRepresentationModel } from '../models/filter.model'; import { TaskDetailsModel } from '../models/task-details.model'; +import { User } from '../models/user.model'; import { TaskListService } from './tasklist.service'; declare let jasmine: any; @@ -288,7 +290,7 @@ describe('Activiti TaskList Service', () => { name: 'FakeNameTask', description: null, category: null, - assignee: fakeUser, + assignee: fakeUser1, created: '' }); @@ -307,7 +309,7 @@ describe('Activiti TaskList Service', () => { contentType: 'application/json', responseText: JSON.stringify({ id: '777', name: 'FakeNameTask', description: null, category: null, - assignee: fakeUser, + assignee: fakeUser1, created: '2016-07-15T11:19:17.440+0000' }) }); @@ -345,7 +347,7 @@ describe('Activiti TaskList Service', () => { contentType: 'application/json', responseText: JSON.stringify({ id: '111', message: 'fake-comment-message', - createdBy: fakeUser, + createdBy: fakeUser1, created: '2016-07-15T11:19:17.440+0000' }) }); @@ -540,7 +542,40 @@ describe('Activiti TaskList Service', () => { name: 'FakeNameTask', description: 'FakeDescription', category: '3', - assignee: fakeUser, + assignee: fakeUser1, + created: '2016-07-15T11:19:17.440+0000' + }) + }); + }); + + it('should assign task to a user', (done) => { + let testTaskId = '8888'; + service.assignTask(testTaskId, fakeUser2).subscribe( + (res: TaskDetailsModel) => { + expect(res).toBeDefined(); + expect(res.id).toEqual(testTaskId); + expect(res.name).toEqual('FakeNameTask'); + expect(res.description).toEqual('FakeDescription'); + expect(res.category).toEqual('3'); + expect(res.created).not.toEqual(''); + expect(res.adhocTaskCanBeReassigned).toBe(true); + expect(res.assignee).toEqual(new User(fakeUser2)); + expect(res.involvedPeople).toEqual([fakeUser1]); + done(); + } + ); + + jasmine.Ajax.requests.mostRecent().respondWith({ + 'status': 200, + contentType: 'application/json', + responseText: JSON.stringify({ + id: testTaskId, + name: 'FakeNameTask', + description: 'FakeDescription', + adhocTaskCanBeReassigned: true, + category: '3', + assignee: fakeUser2, + involvedPeople: [fakeUser1], created: '2016-07-15T11:19:17.440+0000' }) }); diff --git a/ng2-components/ng2-activiti-tasklist/src/services/tasklist.service.ts b/ng2-components/ng2-activiti-tasklist/src/services/tasklist.service.ts index 5a9cf3a1d9..d2c110d80f 100644 --- a/ng2-components/ng2-activiti-tasklist/src/services/tasklist.service.ts +++ b/ng2-components/ng2-activiti-tasklist/src/services/tasklist.service.ts @@ -366,6 +366,20 @@ export class TaskListService { }).catch(err => this.handleError(err)); } + /** + * Assign task to user/group + * @param taskId - string + * @param requestNode - any + * @returns {TaskDetailsModel} + */ + assignTask(taskId: string, requestNode: any): Observable { + return Observable.fromPromise(this.callApiAssignTask(taskId, requestNode)) + .map(res => res) + .map((response: TaskDetailsModel) => { + return new TaskDetailsModel(response); + }).catch(err => this.handleError(err)); + } + /** * Claim a task * @param id - taskId @@ -496,4 +510,8 @@ export class TaskListService { 'filter': { 'sort': 'created-desc', 'name': '', 'state': 'completed', 'assignment': 'involved' } }); } + + private callApiAssignTask(taskId: string, requestNode: any) { + return this.apiService.getInstance().activiti.taskApi.assignTask(taskId, requestNode); + } }