From 6cedc59fdfe8fc249d97d78392b8cf5d1519ab8c Mon Sep 17 00:00:00 2001 From: Silviu Popa Date: Sat, 13 Jul 2019 18:24:16 +0300 Subject: [PATCH] [ADF-4590] TaskCloud - refractor StartTask (#4761) * [ADF-4590] - refractor task-cloud service * [ADF-4590] - change unit tests * [ADF-4590] - fix unit tests * [ADF-4590] - add return type, remove unnecesary unit test * [ADF-4590] - fix lint * [ADF-4590] - PR changes --- .../lib/task/services/task-cloud.service.ts | 38 ++++++++- .../start-task-cloud.component.spec.ts | 48 ++++++++---- .../components/start-task-cloud.component.ts | 13 ++-- .../task/start-task/mock/task-details.mock.ts | 4 +- .../src/lib/task/start-task/public-api.ts | 1 - .../services/start-task-cloud.service.spec.ts | 13 ++-- .../services/start-task-cloud.service.ts | 78 ------------------- .../start-task/start-task-cloud.module.ts | 2 - 8 files changed, 85 insertions(+), 112 deletions(-) delete mode 100644 lib/process-services-cloud/src/lib/task/start-task/services/start-task-cloud.service.ts diff --git a/lib/process-services-cloud/src/lib/task/services/task-cloud.service.ts b/lib/process-services-cloud/src/lib/task/services/task-cloud.service.ts index 8ca9bbca7d..5f86487874 100644 --- a/lib/process-services-cloud/src/lib/task/services/task-cloud.service.ts +++ b/lib/process-services-cloud/src/lib/task/services/task-cloud.service.ts @@ -19,8 +19,9 @@ import { Injectable } from '@angular/core'; import { AlfrescoApiService, LogService, AppConfigService, IdentityUserService } from '@alfresco/adf-core'; import { from, throwError, Observable } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; -import { TaskDetailsCloudModel } from '../start-task/models/task-details-cloud.model'; +import { TaskDetailsCloudModel, StartTaskCloudResponseModel } from '../start-task/models/task-details-cloud.model'; import { BaseCloudService } from '../../services/base-cloud.service'; +import { StartTaskCloudRequestModel } from '../start-task/models/start-task-cloud-request.model'; @Injectable({ providedIn: 'root' @@ -189,6 +190,32 @@ export class TaskCloudService extends BaseCloudService { } } + /** + * Creates a new standalone task. + * @param taskDetails Details of the task to create + * @returns Details of the newly created task + */ + createNewTask(startTaskRequest: StartTaskCloudRequestModel, appName: string): Observable { + const queryUrl = this.buildCreateTaskUrl(appName); + const bodyParam = JSON.stringify(this.buildRequestBody(startTaskRequest)); + const pathParams = {}, queryParams = {}, headerParams = {}, + formParams = {}, contentTypes = ['application/json'], accepts = ['application/json']; + + return from( + this.apiService + .getInstance() + .oauth2Auth.callCustomApi( + queryUrl, 'POST', pathParams, queryParams, + headerParams, formParams, bodyParam, + contentTypes, accepts, null, null) + ).pipe( + map((response: StartTaskCloudResponseModel) => { + return new TaskDetailsCloudModel(response.entry); + }), + catchError((err) => this.handleError(err)) + ); + } + /** * Updates the details (name, description, due date) for a task. * @param appName Name of the app @@ -228,6 +255,15 @@ export class TaskCloudService extends BaseCloudService { return `${this.getBasePath(appName)}/rb/v1/tasks/${taskId}/complete`; } + private buildCreateTaskUrl(appName: string): string { + this.contextRoot = this.appConfigService.get('bpmHost'); + return `${this.getBasePath(appName)}/rb/v1/tasks`; + } + + private buildRequestBody(startTaskRequest: StartTaskCloudRequestModel) { + return new StartTaskCloudRequestModel(startTaskRequest); + } + private handleError(error: any) { this.logService.error(error); return throwError(error || 'Server error'); diff --git a/lib/process-services-cloud/src/lib/task/start-task/components/start-task-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/task/start-task/components/start-task-cloud.component.spec.ts index 87bffa0cc4..55763ff4a9 100644 --- a/lib/process-services-cloud/src/lib/task/start-task/components/start-task-cloud.component.spec.ts +++ b/lib/process-services-cloud/src/lib/task/start-task/components/start-task-cloud.component.spec.ts @@ -25,32 +25,39 @@ import { UserPreferencesService, IdentityUserModel } from '@alfresco/adf-core'; -import { StartTaskCloudService } from '../services/start-task-cloud.service'; import { StartTaskCloudComponent } from './start-task-cloud.component'; import { of, throwError } from 'rxjs'; import { taskDetailsMock } from '../mock/task-details.mock'; import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { ProcessServiceCloudTestingModule } from './../../../testing/process-service-cloud.testing.module'; import { StartTaskCloudTestingModule } from '../testing/start-task-cloud.testing.module'; -import { TaskDetailsCloudModel } from '../models/task-details-cloud.model'; import { FormDefinitionSelectorCloudService } from '../../../form/services/form-definition-selector-cloud.service'; +import { TaskCloudService } from '../../services/task-cloud.service'; +import { StartTaskCloudRequestModel } from '../models/start-task-cloud-request.model'; describe('StartTaskCloudComponent', () => { let component: StartTaskCloudComponent; let fixture: ComponentFixture; - let service: StartTaskCloudService; + let service: TaskCloudService; let identityService: IdentityUserService; let formDefinitionSelectorCloudService: FormDefinitionSelectorCloudService; let element: HTMLElement; let createNewTaskSpy: jasmine.Spy; + let alfrescoApiService: AlfrescoApiService; + + const mock = { + oauth2Auth: { + callCustomApi: () => Promise.resolve(taskDetailsMock) + } + }; const mockUser = new IdentityUserModel({username: 'currentUser', firstName: 'Test', lastName: 'User', email: 'currentUser@test.com'}); setupTestBed({ imports: [ProcessServiceCloudTestingModule, StartTaskCloudTestingModule], providers: [ - StartTaskCloudService, + TaskCloudService, AlfrescoApiService, AppConfigService, LogService, @@ -61,14 +68,16 @@ describe('StartTaskCloudComponent', () => { schemas: [ CUSTOM_ELEMENTS_SCHEMA ] }); - beforeEach(async(() => { + beforeEach(async (() => { fixture = TestBed.createComponent(StartTaskCloudComponent); component = fixture.componentInstance; element = fixture.nativeElement; - service = TestBed.get(StartTaskCloudService); + service = TestBed.get(TaskCloudService); identityService = TestBed.get(IdentityUserService); + alfrescoApiService = TestBed.get(AlfrescoApiService); formDefinitionSelectorCloudService = TestBed.get(FormDefinitionSelectorCloudService); + spyOn(alfrescoApiService, 'getInstance').and.returnValue(mock); createNewTaskSpy = spyOn(service, 'createNewTask').and.returnValue(of(taskDetailsMock)); spyOn(identityService, 'getCurrentUserInfo').and.returnValue(mockUser); spyOn(formDefinitionSelectorCloudService, 'getForms').and.returnValue(of([])); @@ -129,8 +138,9 @@ describe('StartTaskCloudComponent', () => { expect(successSpy).not.toHaveBeenCalled(); }); - it('should assign task to the logged in user when invalid assignee is selected', async(() => { + it('should not start task to the logged in user when invalid assignee is selected', (done) => { component.taskForm.controls['name'].setValue('fakeName'); + component.appName = 'fakeAppName'; fixture.detectChanges(); const assigneeInput = element.querySelector('input.adf-cloud-input'); assigneeInput.nodeValue = 'a'; @@ -139,22 +149,25 @@ describe('StartTaskCloudComponent', () => { createTaskButton.click(); fixture.detectChanges(); fixture.whenStable().then(() => { - const taskRequest = new TaskDetailsCloudModel({ name: 'fakeName', assignee: 'currentUser', candidateGroups: []}); - expect(createNewTaskSpy).toHaveBeenCalledWith(taskRequest); + const taskRequest = new StartTaskCloudRequestModel({ name: 'fakeName', assignee: 'currentUser', candidateGroups: []}); + expect(createNewTaskSpy).toHaveBeenCalledWith(taskRequest, 'fakeAppName'); + done(); }); - })); + }); - it('should assign task to the logged in user when assignee is not selected', async(() => { + it('should not start task to the logged in user when assignee is not selected', (done) => { component.taskForm.controls['name'].setValue('fakeName'); + component.appName = 'fakeAppName'; fixture.detectChanges(); const createTaskButton = element.querySelector('#button-start'); createTaskButton.click(); fixture.detectChanges(); fixture.whenStable().then(() => { - const taskRequest = new TaskDetailsCloudModel({ name: 'fakeName', assignee: 'currentUser', candidateGroups: []}); - expect(createNewTaskSpy).toHaveBeenCalledWith(taskRequest); + const taskRequest = new StartTaskCloudRequestModel({ name: 'fakeName', assignee: 'currentUser', candidateGroups: []}); + expect(createNewTaskSpy).toHaveBeenCalledWith(taskRequest, 'fakeAppName'); + done(); }); - })); + }); }); it('should select logged in user as assignee by default', () => { @@ -198,9 +211,14 @@ describe('StartTaskCloudComponent', () => { component.taskForm.controls['name'].setValue('fakeName'); const errorSpy = spyOn(component.error, 'emit'); createNewTaskSpy.and.returnValue(throwError({})); - const createTaskButton = element.querySelector('#button-start'); + component.appName = 'fakeAppName'; fixture.detectChanges(); + const assigneeInput = element.querySelector('input.adf-cloud-input'); + assigneeInput.nodeValue = 'a'; + fixture.detectChanges(); + const createTaskButton = element.querySelector('#button-start'); createTaskButton.click(); + fixture.detectChanges(); expect(errorSpy).toHaveBeenCalled(); }); diff --git a/lib/process-services-cloud/src/lib/task/start-task/components/start-task-cloud.component.ts b/lib/process-services-cloud/src/lib/task/start-task/components/start-task-cloud.component.ts index 053e80c6cd..340d698abc 100644 --- a/lib/process-services-cloud/src/lib/task/start-task/components/start-task-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/task/start-task/components/start-task-cloud.component.ts @@ -21,8 +21,6 @@ import moment from 'moment-es6'; import { Moment } from 'moment'; import { Observable, Subscription } from 'rxjs'; import { FormBuilder, AbstractControl, Validators, FormGroup, FormControl } from '@angular/forms'; -import { StartTaskCloudService } from '../services/start-task-cloud.service'; -import { TaskDetailsCloudModel } from '../models/task-details-cloud.model'; import { LogService, UserPreferencesService, @@ -32,6 +30,8 @@ import { } from '@alfresco/adf-core'; import { PeopleCloudComponent } from './people-cloud/people-cloud.component'; import { GroupCloudComponent } from '../../../../lib/group/components/group-cloud.component'; +import { TaskCloudService } from '../../services/task-cloud.service'; +import { StartTaskCloudRequestModel } from '../models/start-task-cloud-request.model'; @Component({ selector: 'adf-cloud-start-task', @@ -105,7 +105,7 @@ export class StartTaskCloudComponent implements OnInit, OnDestroy { private localeSub: Subscription; private createTaskSub: Subscription; - constructor(private taskService: StartTaskCloudService, + constructor(private taskService: TaskCloudService, private dateAdapter: DateAdapter, private userPreferencesService: UserPreferencesService, private formBuilder: FormBuilder, @@ -153,17 +153,16 @@ export class StartTaskCloudComponent implements OnInit, OnDestroy { public saveTask() { this.submitted = true; const newTask = Object.assign(this.taskForm.value); - newTask.appName = this.appName; newTask.dueDate = this.dueDate; newTask.assignee = this.assigneeName; newTask.formKey = this.formKey; newTask.candidateGroups = this.candidateGroupNames; - this.createNewTask(new TaskDetailsCloudModel(newTask)); + this.createNewTask(new StartTaskCloudRequestModel(newTask)); } - private createNewTask(newTask: TaskDetailsCloudModel) { - this.createTaskSub = this.taskService.createNewTask(newTask) + private createNewTask(newTask: StartTaskCloudRequestModel) { + this.createTaskSub = this.taskService.createNewTask(newTask, this.appName) .subscribe( (res: any) => { this.submitted = false; diff --git a/lib/process-services-cloud/src/lib/task/start-task/mock/task-details.mock.ts b/lib/process-services-cloud/src/lib/task/start-task/mock/task-details.mock.ts index 2581a413d6..3efe74af75 100644 --- a/lib/process-services-cloud/src/lib/task/start-task/mock/task-details.mock.ts +++ b/lib/process-services-cloud/src/lib/task/start-task/mock/task-details.mock.ts @@ -15,6 +15,6 @@ * limitations under the License. */ -import { TaskDetailsCloudModel } from '../models/task-details-cloud.model'; +import { StartTaskCloudRequestModel } from '../models/start-task-cloud-request.model'; -export let taskDetailsMock = new TaskDetailsCloudModel({ assignee: 'fake-assigne', name: 'fake-name' }); +export let taskDetailsMock = new StartTaskCloudRequestModel({ assignee: 'fake-assigne', name: 'fake-name' }); diff --git a/lib/process-services-cloud/src/lib/task/start-task/public-api.ts b/lib/process-services-cloud/src/lib/task/start-task/public-api.ts index f60a74e193..c7db846a40 100644 --- a/lib/process-services-cloud/src/lib/task/start-task/public-api.ts +++ b/lib/process-services-cloud/src/lib/task/start-task/public-api.ts @@ -16,7 +16,6 @@ */ export * from './models/task-details-cloud.model'; -export * from './services/start-task-cloud.service'; export * from './components/start-task-cloud.component'; export * from './components/people-cloud/people-cloud.component'; export * from './start-task-cloud.module'; diff --git a/lib/process-services-cloud/src/lib/task/start-task/services/start-task-cloud.service.spec.ts b/lib/process-services-cloud/src/lib/task/start-task/services/start-task-cloud.service.spec.ts index 6205d85f24..03b5d0977c 100644 --- a/lib/process-services-cloud/src/lib/task/start-task/services/start-task-cloud.service.spec.ts +++ b/lib/process-services-cloud/src/lib/task/start-task/services/start-task-cloud.service.spec.ts @@ -18,7 +18,6 @@ import { TestBed } from '@angular/core/testing'; import { setupTestBed } from '@alfresco/adf-core'; -import { StartTaskCloudService } from './start-task-cloud.service'; import { StartTaskCloudTestingModule } from '../testing/start-task-cloud.testing.module'; import { of, throwError } from 'rxjs'; import { taskDetailsMock } from '../mock/task-details.mock'; @@ -30,23 +29,25 @@ import { LogService, StorageService } from '@alfresco/adf-core'; +import { TaskCloudService } from '../../services/task-cloud.service'; describe('StartTaskCloudService', () => { - let service: StartTaskCloudService; + let service: TaskCloudService; + const fakeAppName: string = 'fake-app'; setupTestBed({ imports: [StartTaskCloudTestingModule], - providers: [StartTaskCloudService, AlfrescoApiService, AppConfigService, LogService, StorageService] + providers: [TaskCloudService, AlfrescoApiService, AppConfigService, LogService, StorageService] }); beforeEach(() => { - service = TestBed.get(StartTaskCloudService); + service = TestBed.get(TaskCloudService); }); it('should able to create a new task ', (done) => { spyOn(service, 'createNewTask').and.returnValue(of({id: 'fake-id', name: 'fake-name'})); - service.createNewTask(taskDetailsMock).subscribe( + service.createNewTask(taskDetailsMock, fakeAppName).subscribe( (res: TaskDetailsCloudModel) => { expect(res).toBeDefined(); expect(res.id).toEqual('fake-id'); @@ -63,7 +64,7 @@ describe('StartTaskCloudService', () => { }); spyOn(service, 'createNewTask').and.returnValue(throwError(errorResponse)); - service.createNewTask(taskDetailsMock) + service.createNewTask(taskDetailsMock, fakeAppName) .subscribe( () => { fail('expected an error, not applications'); diff --git a/lib/process-services-cloud/src/lib/task/start-task/services/start-task-cloud.service.ts b/lib/process-services-cloud/src/lib/task/start-task/services/start-task-cloud.service.ts deleted file mode 100644 index 419ccbc529..0000000000 --- a/lib/process-services-cloud/src/lib/task/start-task/services/start-task-cloud.service.ts +++ /dev/null @@ -1,78 +0,0 @@ -/*! - * @license - * Copyright 2019 Alfresco Software, Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Injectable } from '@angular/core'; -import { - AlfrescoApiService, - AppConfigService, - LogService -} from '@alfresco/adf-core'; -import { from, Observable, throwError } from 'rxjs'; -import { StartTaskCloudRequestModel } from '../models/start-task-cloud-request.model'; -import { TaskDetailsCloudModel, StartTaskCloudResponseModel } from '../models/task-details-cloud.model'; -import { map, catchError } from 'rxjs/operators'; -import { BaseCloudService } from '../../../services/base-cloud.service'; - -@Injectable() -export class StartTaskCloudService extends BaseCloudService { - - constructor( - private apiService: AlfrescoApiService, - private appConfigService: AppConfigService, - private logService: LogService - ) { super(); } - - /** - * Creates a new standalone task. - * @param taskDetails Details of the task to create - * @returns Details of the newly created task - */ - createNewTask(taskDetails: TaskDetailsCloudModel): Observable { - const queryUrl = this.buildCreateTaskUrl(taskDetails.appName); - const bodyParam = JSON.stringify(this.buildRequestBody(taskDetails)); - const pathParams = {}, queryParams = {}, headerParams = {}, - formParams = {}, contentTypes = ['application/json'], accepts = ['application/json']; - - return from( - this.apiService - .getInstance() - .oauth2Auth.callCustomApi( - queryUrl, 'POST', pathParams, queryParams, - headerParams, formParams, bodyParam, - contentTypes, accepts, null, null) - ).pipe( - map((response: StartTaskCloudResponseModel) => { - return new TaskDetailsCloudModel(response.entry); - }), - catchError((err) => this.handleError(err)) - ); - } - - private buildCreateTaskUrl(appName: string): any { - this.contextRoot = this.appConfigService.get('bpmHost'); - return `${this.getBasePath(appName)}/rb/v1/tasks`; - } - - private buildRequestBody(taskDetails: any) { - return new StartTaskCloudRequestModel(taskDetails); - } - - private handleError(error: any) { - this.logService.error(error); - return throwError(error || 'Server error'); - } -} diff --git a/lib/process-services-cloud/src/lib/task/start-task/start-task-cloud.module.ts b/lib/process-services-cloud/src/lib/task/start-task/start-task-cloud.module.ts index 153cf55820..040d3cc171 100644 --- a/lib/process-services-cloud/src/lib/task/start-task/start-task-cloud.module.ts +++ b/lib/process-services-cloud/src/lib/task/start-task/start-task-cloud.module.ts @@ -21,7 +21,6 @@ import { FlexLayoutModule } from '@angular/flex-layout'; import { MaterialModule } from '../../material.module'; import { TemplateModule, PipeModule, CoreModule } from '@alfresco/adf-core'; import { StartTaskCloudComponent } from './components/start-task-cloud.component'; -import { StartTaskCloudService } from './services/start-task-cloud.service'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { PeopleCloudComponent } from './components/people-cloud/people-cloud.component'; import { GroupCloudModule } from '../../group/group-cloud.module'; @@ -43,7 +42,6 @@ import { FormCloudModule } from '../../form/form-cloud.module'; ], declarations: [StartTaskCloudComponent, PeopleCloudComponent], providers: [ - StartTaskCloudService, TaskCloudService ], exports: [