From a3b0f8c787854a9b2e6b33cb4adee07f10cd5ed4 Mon Sep 17 00:00:00 2001 From: mauriziovitale84 Date: Thu, 3 Nov 2016 14:33:09 +0000 Subject: [PATCH 01/16] Fix process definition api --- .../analyticsParamsReportComponent.mock.ts | 23 ++++++++++++++++ ...lytics-report-parameters.component.spec.ts | 2 +- .../analytics-report-parameters.component.ts | 2 +- .../src/services/analytics.service.ts | 27 +++++++++++++++---- 4 files changed, 47 insertions(+), 7 deletions(-) diff --git a/ng2-components/ng2-activiti-analytics/src/assets/analyticsParamsReportComponent.mock.ts b/ng2-components/ng2-activiti-analytics/src/assets/analyticsParamsReportComponent.mock.ts index 626996af3b..07d44ade6a 100644 --- a/ng2-components/ng2-activiti-analytics/src/assets/analyticsParamsReportComponent.mock.ts +++ b/ng2-components/ng2-activiti-analytics/src/assets/analyticsParamsReportComponent.mock.ts @@ -69,6 +69,29 @@ export var reportDefParamProcessDef = { 'definition': '{ "parameters" :[{"id":"processDefinitionId","name":null,"nameKey":null,"type":"processDefinition","value":null,"dependsOn":null}]}' }; +export var reportDefParamProcessDefOptionsNoApp = [ + { + 'id': 'FakeProcessTest 1:1:1', + 'name': 'Fake Process Test 1 Name ', + 'version': 1 + }, + { + 'id': 'FakeProcessTest 1:2:1', + 'name': 'Fake Process Test 1 Name ', + 'version': 2 + }, + { + 'id': 'FakeProcessTest 2:1:1', + 'name': 'Fake Process Test 2 Name ', + 'version': 1 + }, + { + 'id': 'FakeProcessTest 3:1:1', + 'name': 'Fake Process Test 3 Name ', + 'version': 1 + } +]; + export var reportDefParamProcessDefOptions = { 'size': 4, 'total': 4, 'start': 0, 'data': [ { diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.spec.ts b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.spec.ts index 9302b32f01..bb435e61cc 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.spec.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.spec.ts @@ -293,7 +293,7 @@ describe('Test ng2-analytics-report-parameters Report Parameters ', () => { jasmine.Ajax.requests.mostRecent().respondWith({ status: 200, contentType: 'json', - responseText: analyticParamsMock.reportDefParamProcessDefOptions + responseText: analyticParamsMock.reportDefParamProcessDefOptionsNoApp }); }); diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.ts b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.ts index f31fcb0f18..f1768acc42 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.ts @@ -182,7 +182,7 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges { } public convertNumber(value: string): number { - return parseInt(value, 10); + return value != null ? parseInt(value, 10) : 0; } convertFormValuesToReportParamQuery(values: any): ReportQuery { diff --git a/ng2-components/ng2-activiti-analytics/src/services/analytics.service.ts b/ng2-components/ng2-activiti-analytics/src/services/analytics.service.ts index 867fe2c47d..ea7eb28496 100644 --- a/ng2-components/ng2-activiti-analytics/src/services/analytics.service.ts +++ b/ng2-components/ng2-activiti-analytics/src/services/analytics.service.ts @@ -68,7 +68,11 @@ export class AnalyticsService { if (type === 'status') { return this.getProcessStatusValues(); } else if (type === 'processDefinition') { - return this.getProcessDefinitionsValues(appId); + if (appId === null || appId === undefined) { + return this.getProcessDefinitionsValuesNoApp(); + } else { + return this.getProcessDefinitionsValues(appId); + } } else if (type === 'dateInterval') { return this.getDateIntervalValues(); } else if (type === 'task') { @@ -122,13 +126,26 @@ export class AnalyticsService { }); } + getProcessDefinitionsValuesNoApp(): Observable { + let url = `${this.alfrescoSettingsService.getBPMApiBaseUrl()}/app/rest/reporting/process-definitions`; + let options = this.getRequestOptions(); + return this.http + .get(url, options) + .map((res: any) => { + let paramOptions: ParameterValueModel[] = []; + let body = res.json(); + body.forEach((opt) => { + paramOptions.push(new ParameterValueModel(opt)); + }); + return paramOptions; + }).catch(this.handleError); + } + getProcessDefinitionsValues(appId: string): Observable { let url = `${this.alfrescoSettingsService.getBPMApiBaseUrl()}/app/rest/process-definitions`; let params: URLSearchParams; - if (appId) { - params = new URLSearchParams(); - params.set('appDefinitionId', appId); - } + params = new URLSearchParams(); + params.set('appDefinitionId', appId); let options = this.getRequestOptions(params); return this.http .get(url, options) From a1a95cc96385f6db800e91b6c2db580ab080edf2 Mon Sep 17 00:00:00 2001 From: Vito Albano Date: Wed, 26 Oct 2016 18:15:25 +0100 Subject: [PATCH 02/16] Fix dialog for firefox and safari --- .../src/components/activiti-people.component.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.ts index 7ce00fc1a3..a055de8824 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.ts @@ -58,10 +58,10 @@ export class ActivitiPeople implements OnInit { } public showDialog() { + if (!this.dialog.nativeElement.showModal) { + dialogPolyfill.registerDialog(this.dialog.nativeElement); + } if (this.dialog) { - if (!this.dialog.nativeElement.showModal) { - dialogPolyfill.registerDialog(this.dialog.nativeElement); - } this.dialog.nativeElement.showModal(); } } From 0bd05a2d4caf83c5e5a15901ee5065a7bc4154cd Mon Sep 17 00:00:00 2001 From: Vito Albano Date: Mon, 31 Oct 2016 14:09:43 +0000 Subject: [PATCH 03/16] Added remove involved user to people service --- .../services/activiti-people.service.spec.ts | 169 ++++++++++++++++++ .../src/services/activiti-people.service.ts | 73 ++++++++ 2 files changed, 242 insertions(+) create mode 100644 ng2-components/ng2-activiti-tasklist/src/services/activiti-people.service.spec.ts create mode 100644 ng2-components/ng2-activiti-tasklist/src/services/activiti-people.service.ts diff --git a/ng2-components/ng2-activiti-tasklist/src/services/activiti-people.service.spec.ts b/ng2-components/ng2-activiti-tasklist/src/services/activiti-people.service.spec.ts new file mode 100644 index 0000000000..85fbcf4619 --- /dev/null +++ b/ng2-components/ng2-activiti-tasklist/src/services/activiti-people.service.spec.ts @@ -0,0 +1,169 @@ +/*! + * @license + * Copyright 2016 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 { ReflectiveInjector } from '@angular/core'; +import { + AlfrescoAuthenticationService, + AlfrescoSettingsService, + AlfrescoApiService +} from 'ng2-alfresco-core'; +import { User } from '../models/user.model'; +import { ActivitiPeopleService } from './activiti-people.service'; + +declare let jasmine: any; + +const firstInvolvedUser: User = new User({ + id: '1', + email: 'fake-user1@fake.com', + firstName: 'fakeName1', + lastName: 'fakeLast1' +}); + +const secondInvolvedUser: User = new User({ + id: '2', + email: 'fake-user2@fake.com', + firstName: 'fakeName2', + lastName: 'fakeLast2' +}); + +const fakeInvolveUserList: User[] = [firstInvolvedUser, secondInvolvedUser]; + +describe('Activiti People Search Service', () => { + + let service, injector, apiService; + + beforeEach(() => { + injector = ReflectiveInjector.resolveAndCreate([ + AlfrescoSettingsService, + AlfrescoApiService, + AlfrescoAuthenticationService, + ActivitiPeopleService + ]); + }); + + beforeEach(() => { + service = injector.get(ActivitiPeopleService); + apiService = injector.get(AlfrescoApiService); + }); + + it('can instantiate service with authorization', () => { + expect(apiService).not.toBeNull('authorization should be provided'); + let serviceApi = new ActivitiPeopleService(null, apiService); + + expect(serviceApi instanceof ActivitiPeopleService).toBe(true, 'new service should be ok'); + }); + + describe('when user is logged in', () => { + + beforeEach(() => { + jasmine.Ajax.install(); + }); + + afterEach(() => { + jasmine.Ajax.uninstall(); + }); + + it('should be able to retrieve people to involve in the task', (done) => { + service.getWorkflowUsers('fake-task-id', 'fake-filter').subscribe( + (users: User[]) => { + expect(users).toBeDefined(); + expect(users.length).toBe(2); + expect(users[0].id).toEqual('1'); + expect(users[0].email).toEqual('fake-user1@fake.com'); + expect(users[0].firstName).toEqual('fakeName1'); + expect(users[0].lastName).toEqual('fakeLast1'); + done(); + }); + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'json', + responseText: {data: fakeInvolveUserList} + }); + }); + + it('should return empty list when there are no users to involve', (done) => { + service.getWorkflowUsers('fake-task-id', 'fake-filter').subscribe( + (users: User[]) => { + expect(users).toBeDefined(); + expect(users.length).toBe(0); + done(); + }); + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'json', + responseText: {} + }); + }); + + it('getWorkflowUsers catch errors call', (done) => { + service.getWorkflowUsers('fake-task-id', 'fake-filter').subscribe(() => { + }, () => { + done(); + }); + + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 403 + }); + }); + + it('should be able to involve people in the task', (done) => { + service.involveUserWithTask('fake-task-id', 'fake-user-id').subscribe( + () => { + expect(jasmine.Ajax.requests.mostRecent().method).toBe('PUT'); + expect(jasmine.Ajax.requests.mostRecent().url).toContain('tasks/fake-task-id/action/involve'); + done(); + }); + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200 + }); + }); + + it('involveUserWithTask catch errors call', (done) => { + service.involveUserWithTask('fake-task-id', 'fake-user-id').subscribe(() => { + }, () => { + done(); + }); + + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 403 + }); + }); + + it('should be able to remove involved people from task', (done) => { + service.removeInvolvedUser('fake-task-id', 'fake-user-id').subscribe( + () => { + expect(jasmine.Ajax.requests.mostRecent().method).toBe('PUT'); + expect(jasmine.Ajax.requests.mostRecent().url).toContain('tasks/fake-task-id/action/remove-involved'); + done(); + }); + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200 + }); + }); + + it('removeInvolvedUser catch errors call', (done) => { + service.removeInvolvedUser('fake-task-id', 'fake-user-id').subscribe(() => { + }, () => { + done(); + }); + + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 403 + }); + }); + }); +}); diff --git a/ng2-components/ng2-activiti-tasklist/src/services/activiti-people.service.ts b/ng2-components/ng2-activiti-tasklist/src/services/activiti-people.service.ts new file mode 100644 index 0000000000..1e5e99433d --- /dev/null +++ b/ng2-components/ng2-activiti-tasklist/src/services/activiti-people.service.ts @@ -0,0 +1,73 @@ +/*! + * @license + * Copyright 2016 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, AlfrescoAuthenticationService } from 'ng2-alfresco-core'; +import { Observable } from 'rxjs/Rx'; +import { Response } from '@angular/http'; +import { User } from '../models/user.model'; + +@Injectable() +export class ActivitiPeopleService { + + constructor(private authService: AlfrescoAuthenticationService, + private alfrescoJsApi: AlfrescoApiService) { + } + + getWorkflowUsers(taskId: string, searchWord: string): Observable { + let option = {excludeTaskId: taskId, filter: searchWord}; + return Observable.fromPromise(this.getWorkflowUserApi(option)) + .map((response: any) => response.data || []) + .catch(this.handleError); + } + + involveUserWithTask(taskId: string, idToInvolve: string): Observable { + let node = {userId: idToInvolve}; + return Observable.fromPromise(this.involveUserToTaskApi(taskId, node)) + .catch(this.handleError); + } + + removeInvolvedUser(taskId: string, idToRemove: string): Observable { + let node = {userId: idToRemove}; + return Observable.fromPromise(this.removeInvolvedUserFromTaskApi(taskId, node)) + .catch(this.handleError); + } + + private getWorkflowUserApi(options: any) { + return this.alfrescoJsApi.getInstance().activiti.usersWorkflowApi.getUsers(options); + } + + private involveUserToTaskApi(taskId: string, node: any) { + return this.alfrescoJsApi.getInstance().activiti.taskActionsApi.involveUser(taskId, node); + } + + private removeInvolvedUserFromTaskApi(taskId: string, node: any) { + return this.alfrescoJsApi.getInstance().activiti.taskActionsApi.removeInvolvedUser(taskId, node); + } + + /** + * Throw the error + * @param error + * @returns {ErrorObservable} + */ + private handleError(error: Response) { + // in a real world app, we may send the error to some remote logging infrastructure + // instead of just logging it to the console + console.error(error); + return Observable.throw(error || 'Server error'); + } +} From 7b0e8e10167b58fe250113a6e693eb36e7e58a88 Mon Sep 17 00:00:00 2001 From: Vito Albano Date: Mon, 31 Oct 2016 17:11:09 +0000 Subject: [PATCH 04/16] Added component search for users --- .../activiti-people-search.component.css | 18 +++++ .../activiti-people-search.component.html | 17 ++++ .../activiti-people-search.component.ts | 81 +++++++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.css create mode 100644 ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.html create mode 100644 ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.ts diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.css b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.css new file mode 100644 index 0000000000..cd41a4d0df --- /dev/null +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.css @@ -0,0 +1,18 @@ +:host { + width: 100%; +} + +.activiti-label { + font-weight: bolder; +} + +.material-icons:hover { + color: rgb(255, 152, 0); +} + +.fix-element-user-list{ + padding-top: 0px; + padding-right: 0px; + padding-bottom: 0px; + padding-left: 0px; +} diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.html b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.html new file mode 100644 index 0000000000..6cba3d51e5 --- /dev/null +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.html @@ -0,0 +1,17 @@ +
+ + +
+
    +
  • + + face + {{ user.firstName }} - {{ user.lastName }} + +
  • +
    + No user found to involve +
    +
diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.ts new file mode 100644 index 0000000000..d77de3ac88 --- /dev/null +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.ts @@ -0,0 +1,81 @@ +/*! + * @license + * Copyright 2016 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 { Component, Input, Output, EventEmitter, OnInit, AfterViewInit } from '@angular/core'; +import { FormControl } from '@angular/forms'; +import { User } from '../models/user.model'; +import { Observable } from 'rxjs/Observable'; + +declare let componentHandler: any; + +@Component({ + selector: 'activiti-people-search', + moduleId: module.id, + templateUrl: './activiti-people-search.component.html', + styleUrls: ['./activiti-people-search.component.css'] +}) + +export class ActivitiPeopleSearch implements OnInit, AfterViewInit { + + @Input() + results: Observable; + + @Output() + onSearch: EventEmitter = new EventEmitter(); + + @Output() + onModalRowClicked: EventEmitter = new EventEmitter(); + + private searchUser: FormControl = new FormControl(); + + userList: User[] = []; + + constructor() { + this.searchUser + .valueChanges + .debounceTime(200) + .subscribe((event) => { + this.onSearch.emit(event); + }); + } + + ngOnInit() { + this.results.subscribe((list) => { + this.userList = list; + }); + } + + ngAfterViewInit() { + this.setupMaterialComponents(componentHandler); + } + + setupMaterialComponents(handler?: any): boolean { + // workaround for MDL issues with dynamic components + if (handler) { + handler.upgradeAllRegistered(); + return true; + } + return false; + } + + onRowClick(userClicked: User) { + this.onModalRowClicked.emit(userClicked); + this.userList = this.userList.filter((user) => { + return user.id !== userClicked.id; + }); + } +} From e33c5d9859493d4478ae5008968aa39b7ff45113 Mon Sep 17 00:00:00 2001 From: Vito Albano Date: Mon, 31 Oct 2016 17:11:57 +0000 Subject: [PATCH 05/16] Added new people search to the index.ts --- ng2-components/ng2-activiti-tasklist/index.ts | 13 ++++++++----- .../ng2-activiti-tasklist/src/components/index.ts | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ng2-components/ng2-activiti-tasklist/index.ts b/ng2-components/ng2-activiti-tasklist/index.ts index b6c3b1cf53..e2494041dc 100644 --- a/ng2-components/ng2-activiti-tasklist/index.ts +++ b/ng2-components/ng2-activiti-tasklist/index.ts @@ -19,6 +19,8 @@ import { NgModule, ModuleWithProviders } from '@angular/core'; import { CoreModule } from 'ng2-alfresco-core'; import { DataTableModule } from 'ng2-alfresco-datatable'; import { ActivitiFormModule } from 'ng2-activiti-form'; +import { ActivitiPeopleService } from './src/services/activiti-people.service'; +import { ActivitiTaskListService } from './src/services/activiti-tasklist.service'; import { ActivitiApps, @@ -30,11 +32,10 @@ import { ActivitiComments, ActivitiPeople, ActivitiTaskHeader, - ActivitiStartProcessButton + ActivitiStartProcessButton, + ActivitiPeopleSearch } from './src/components/index'; -import { ActivitiTaskListService } from './src/services/activiti-tasklist.service'; - export * from './src/components/index'; export * from './src/services/activiti-tasklist.service'; export * from './src/models/filter.model'; @@ -49,11 +50,13 @@ export const ACTIVITI_TASKLIST_DIRECTIVES: any[] = [ ActivitiComments, ActivitiPeople, ActivitiTaskHeader, - ActivitiStartProcessButton + ActivitiStartProcessButton, + ActivitiPeopleSearch ]; export const ACTIVITI_TASKLIST_PROVIDERS: any[] = [ - ActivitiTaskListService + ActivitiTaskListService, + ActivitiPeopleService ]; @NgModule({ diff --git a/ng2-components/ng2-activiti-tasklist/src/components/index.ts b/ng2-components/ng2-activiti-tasklist/src/components/index.ts index 9847cd7f7f..cef995cbf1 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/index.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/index.ts @@ -25,3 +25,4 @@ export * from './no-task-detail-template.component'; export * from './activiti-filters.component'; export * from './activiti-task-details.component'; export * from './activiti-start-task.component'; +export * from './activiti-people-search.component'; From 018cd8fa734f62098c139ea2488abfa36bb1914c Mon Sep 17 00:00:00 2001 From: Vito Albano Date: Mon, 31 Oct 2016 17:12:48 +0000 Subject: [PATCH 06/16] Changed activiti people to manage the new search user window --- .../components/activiti-people.component.css | 4 ++ .../components/activiti-people.component.html | 22 ++++---- .../activiti-people.component.spec.ts | 50 +++++++++++++++++ .../components/activiti-people.component.ts | 55 ++++++++++++------- 4 files changed, 101 insertions(+), 30 deletions(-) create mode 100644 ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.spec.ts diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.css b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.css index 7e9e64291f..0578c7e3c3 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.css +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.css @@ -9,3 +9,7 @@ .material-icons:hover { color: rgb(255, 152, 0); } + +.involve-user-padding { + padding: 20px 24px 2px; +} diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.html b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.html index 5430f9b172..c2c359dec4 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.html +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.html @@ -1,16 +1,19 @@ {{ 'TASK_DETAILS.LABELS.PEOPLE' | translate }}
add
-
+
Add a person
@@ -19,15 +22,14 @@
-

New User

-
-
- - -
+

Involve User

+
+ +
-
diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.spec.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.spec.ts new file mode 100644 index 0000000000..f8047fbef2 --- /dev/null +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.spec.ts @@ -0,0 +1,50 @@ +/*! + * @license + * Copyright 2016 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 { + AlfrescoAuthenticationService, + AlfrescoSettingsService, + AlfrescoApiService + } from 'ng2-alfresco-core';*/ +import { AlfrescoTranslationService } from 'ng2-alfresco-core'; +import { ActivitiPeopleService } from '../services/activiti-people.service'; +import { ActivitiPeople } from './activiti-people.component'; +import { ComponentFixture, TestBed, async } from '@angular/core/testing'; + +describe('Activiti People Component', () => { + + let activitiPeopleComponent: ActivitiPeople; + let fixture: ComponentFixture; + let element: HTMLElement; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ActivitiPeople], + providers: [AlfrescoTranslationService, ActivitiPeopleService] + }).compileComponents().then(() => { + fixture = TestBed.createComponent(ActivitiPeople); + activitiPeopleComponent = fixture.componentInstance; + element = fixture.nativeElement; + }); + })); + + it('should not show any image if the user is not logged in', () => { + expect(element.querySelector('#userinfo_container')).toBeDefined(); + expect(element.querySelector('#logged-user-img')).toBeNull(); + }); +}); diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.ts index a055de8824..5795275b45 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.ts @@ -15,10 +15,11 @@ * limitations under the License. */ -import { Component, Input, OnInit, ViewChild } from '@angular/core'; -import { AlfrescoTranslationService, AlfrescoAuthenticationService } from 'ng2-alfresco-core'; +import { Component, Input, ViewChild } from '@angular/core'; +import { AlfrescoTranslationService } from 'ng2-alfresco-core'; import { User } from '../models/user.model'; import { Observer, Observable } from 'rxjs/Rx'; +import { ActivitiPeopleService } from '../services/activiti-people.service'; @Component({ selector: 'activiti-people', @@ -26,35 +27,32 @@ import { Observer, Observable } from 'rxjs/Rx'; templateUrl: './activiti-people.component.html', styleUrls: ['./activiti-people.component.css'] }) -export class ActivitiPeople implements OnInit { +export class ActivitiPeople { @Input() people: User [] = []; + @Input() + taskId: string = ''; + @ViewChild('dialog') dialog: any; - private peopleObserver: Observer; + private peopleObserver: Observer; people$: Observable; /** * Constructor - * @param auth * @param translate + * @param people service */ - constructor(private auth: AlfrescoAuthenticationService, - private translate: AlfrescoTranslationService) { + constructor(private translate: AlfrescoTranslationService, + private peopleService: ActivitiPeopleService) { if (translate) { translate.addTranslationFolder('node_modules/ng2-activiti-tasklist/src'); } - this.people$ = new Observable(observer => this.peopleObserver = observer).share(); - } - - ngOnInit() { - this.people$.subscribe((user: User) => { - this.people.push(user); - }); + this.people$ = new Observable(observer => this.peopleObserver = observer).share(); } public showDialog() { @@ -66,16 +64,33 @@ export class ActivitiPeople implements OnInit { } } - public add() { - alert('add people'); - - this.cancel(); - } - public cancel() { if (this.dialog) { this.dialog.nativeElement.close(); } } + searchUser(searchedWord: string) { + this.peopleService.getWorkflowUsers(this.taskId, searchedWord) + .subscribe((users) => { + this.peopleObserver.next(users); + }, error => console.log('Could not load users')); + } + + involveUser(user: User) { + this.peopleService.involveUserWithTask(this.taskId, user.id.toString()) + .subscribe(() => { + this.people.push(user); + }, error => console.error('Impossible to involve user with task')); + } + + removeInvolvedUser(user: User) { + this.peopleService.removeInvolvedUser(this.taskId, user.id.toString()) + .subscribe(() => { + this.people = this.people.filter((involvedUser) => { + return involvedUser.id !== user.id; + }); + }, error => console.error('Impossible to remove involved user from task')); + } + } From 71dfc2a6b08a69ac65af48d1a6d3efdc740b2024 Mon Sep 17 00:00:00 2001 From: Vito Albano Date: Mon, 31 Oct 2016 17:13:10 +0000 Subject: [PATCH 07/16] Added task id as input --- .../src/components/activiti-task-details.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.html b/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.html index 6658cf65c5..1b1566b74f 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.html +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.html @@ -12,7 +12,7 @@
- +
From 859c491a34949590964c871f414adfc042587f8c Mon Sep 17 00:00:00 2001 From: Vito Albano Date: Tue, 1 Nov 2016 15:40:36 +0000 Subject: [PATCH 08/16] Added test for people component --- .../components/activiti-people.component.html | 12 +- .../activiti-people.component.spec.ts | 237 +++++++++++++++++- .../components/activiti-people.component.ts | 4 +- .../ng2-activiti-tasklist/src/i18n/it.json | 7 +- 4 files changed, 237 insertions(+), 23 deletions(-) diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.html b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.html index c2c359dec4..4104152578 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.html +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.html @@ -1,4 +1,4 @@ -{{ 'TASK_DETAILS.LABELS.PEOPLE' | translate }}
add
@@ -9,7 +9,7 @@
  • face - {{user.firstName}} {{user.lastName}} + {{user.firstName}} {{user.lastName}} delete @@ -17,12 +17,12 @@
  • -
    +
    {{ 'TASK_DETAILS.PEOPLE.NONE' | translate }}
    - -

    Involve User

    + +

    Involve User

    - +
    diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.spec.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.spec.ts index f8047fbef2..1c5737713f 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.spec.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.spec.ts @@ -15,36 +15,247 @@ * limitations under the License. */ -/* - import { - AlfrescoAuthenticationService, - AlfrescoSettingsService, - AlfrescoApiService - } from 'ng2-alfresco-core';*/ -import { AlfrescoTranslationService } from 'ng2-alfresco-core'; +import { + CoreModule, + AlfrescoTranslationService +} from 'ng2-alfresco-core'; import { ActivitiPeopleService } from '../services/activiti-people.service'; import { ActivitiPeople } from './activiti-people.component'; -import { ComponentFixture, TestBed, async } from '@angular/core/testing'; +import { ActivitiPeopleSearch } from './activiti-people-search.component'; +import { TranslationMock } from '../assets/translation.service.mock'; +import { ComponentFixture, TestBed, async, fakeAsync, tick } from '@angular/core/testing'; +import { User } from '../models/user.model'; + +declare let jasmine: any; + +const fakeUser: User = new User({ + id: 'fake-id', + firstName: 'fake-name', + lastName: 'fake-last', + email: 'fake@mail.com' +}); + +const fakeUserToInvolve: User = new User({ + id: 'fake-involve-id', + firstName: 'fake-involve-name', + lastName: 'fake-involve-last', + email: 'fake-involve@mail.com' +}); describe('Activiti People Component', () => { let activitiPeopleComponent: ActivitiPeople; let fixture: ComponentFixture; let element: HTMLElement; + let componentHandler; beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ActivitiPeople], - providers: [AlfrescoTranslationService, ActivitiPeopleService] + imports: [CoreModule], + declarations: [ActivitiPeople, ActivitiPeopleSearch], + providers: [ + {provide: AlfrescoTranslationService, useClass: TranslationMock}, + ActivitiPeopleService] }).compileComponents().then(() => { fixture = TestBed.createComponent(ActivitiPeople); activitiPeopleComponent = fixture.componentInstance; element = fixture.nativeElement; + componentHandler = jasmine.createSpyObj('componentHandler', [ + 'upgradeAllRegistered' + ]); + + window['componentHandler'] = componentHandler; }); })); - it('should not show any image if the user is not logged in', () => { - expect(element.querySelector('#userinfo_container')).toBeDefined(); - expect(element.querySelector('#logged-user-img')).toBeNull(); + afterAll(() => { + fixture.destroy(); + TestBed.resetTestingModule(); + }); + + it('should show people component title', () => { + expect(element.querySelector('#people-title')).toBeDefined(); + expect(element.querySelector('#people-title')).not.toBeNull(); + }); + + it('should show no people involved message', () => { + fixture.detectChanges(); + fixture.whenStable() + .then(() => { + expect(element.querySelector('#no-people-label')).not.toBeNull(); + expect(element.querySelector('#no-people-label').textContent).toContain('TASK_DETAILS.PEOPLE.NONE'); + }); + }); + + describe('when interact with people dialog', () => { + + beforeEach(() => { + activitiPeopleComponent.taskId = 'fake-task-id'; + activitiPeopleComponent.people = []; + fixture.detectChanges(); + }); + + it('should show dialog when clicked on add', () => { + expect(element.querySelector('#addPeople')).not.toBeNull(); + activitiPeopleComponent.showDialog(); + + expect(element.querySelector('#add-people-dialog')).not.toBeNull(); + expect(element.querySelector('#add-people-dialog-title')).not.toBeNull(); + expect(element.querySelector('#add-people-dialog-title').textContent).toContain('Involve User'); + }); + + it('should close dialog when clicked on cancel', () => { + activitiPeopleComponent.showDialog(); + expect(element.querySelector('#addPeople')).not.toBeNull(); + activitiPeopleComponent.cancel(); + let dialogWindow = element.querySelector('#add-people-dialog'); + expect(dialogWindow.getAttribute('open')).toBeNull(); + }); + }); + + describe('when there are involved people', () => { + + beforeEach(() => { + activitiPeopleComponent.taskId = 'fake-task-id'; + activitiPeopleComponent.people.push(fakeUser); + fixture.detectChanges(); + }); + + beforeEach(() => { + jasmine.Ajax.install(); + }); + + afterEach(() => { + jasmine.Ajax.uninstall(); + }); + + it('should show people involved', () => { + expect(element.querySelector('#user-fake-id')).not.toBeNull(); + expect(element.querySelector('#user-fake-id').textContent).toContain('fake-name'); + expect(element.querySelector('#user-fake-id').textContent).toContain('fake-last'); + }); + + it('should remove pepole involved', fakeAsync(() => { + activitiPeopleComponent.removeInvolvedUser(fakeUser); + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200 + }); + tick(); + fixture.detectChanges(); + fixture.whenStable() + .then(() => { + expect(element.querySelector('#user-fake-id')).toBeNull(); + }); + })); + + it('should involve pepole', fakeAsync(() => { + activitiPeopleComponent.involveUser(fakeUserToInvolve); + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200 + }); + tick(); + fixture.detectChanges(); + fixture.whenStable() + .then(() => { + expect(element.querySelector('#user-fake-involve-id')).not.toBeNull(); + expect(element.querySelector('#user-fake-involve-id').textContent) + .toBe('fake-involve-name fake-involve-last'); + }); + })); + + it('should return an observable with user search results', (done) => { + activitiPeopleComponent.people$.subscribe((users) => { + expect(users.length).toBe(2); + expect(users[0].firstName).toBe('fake-test-1'); + expect(users[0].lastName).toBe('fake-last-1'); + expect(users[0].email).toBe('fake-test-1@test.com'); + expect(users[0].id).toBe(1); + done(); + }); + activitiPeopleComponent.searchUser('fake-search-word'); + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'json', + responseText: { + data: [{ + id: 1, + firstName: 'fake-test-1', + lastName: 'fake-last-1', + email: 'fake-test-1@test.com' + }, { + id: 2, + firstName: 'fake-test-2', + lastName: 'fake-last-2', + email: 'fake-test-2@test.com' + }] + } + }); + }); + + it('should return an empty list for not valid search', (done) => { + activitiPeopleComponent.people$.subscribe((users) => { + expect(users.length).toBe(0); + done(); + }); + activitiPeopleComponent.searchUser('fake-search-word'); + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'json', + responseText: {} + }); + }); + }); + + describe('when there are errors on service call', () => { + + beforeEach(() => { + jasmine.Ajax.install(); + }); + + afterEach(() => { + jasmine.Ajax.uninstall(); + }); + + it('should log error message when search fails', fakeAsync(() => { + console.log = jasmine.createSpy('log'); + activitiPeopleComponent.searchUser('fake-search'); + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 403 + }); + tick(); + + expect(console.log).toHaveBeenCalledWith('Could not load users'); + })); + + it('should not remove user if remove involved user fail', fakeAsync(() => { + activitiPeopleComponent.people.push(fakeUser); + fixture.detectChanges(); + activitiPeopleComponent.removeInvolvedUser(fakeUser); + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 403 + }); + tick(); + fixture.detectChanges(); + fixture.whenStable() + .then(() => { + expect(element.querySelector('#user-fake-id')).not.toBeNull(); + expect(element.querySelector('#user-fake-id').textContent) + .toBe('fake-name fake-last'); + }); + })); + + it('should not involve user if involve user fail', fakeAsync(() => { + activitiPeopleComponent.involveUser(fakeUserToInvolve); + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 403 + }); + tick(); + fixture.detectChanges(); + fixture.whenStable() + .then(() => { + expect(element.querySelector('#user-fake-id')).toBeNull(); + expect(element.querySelector('#no-people-label').textContent).toContain('TASK_DETAILS.PEOPLE.NONE'); + }); + })); }); }); diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.ts index 5795275b45..f8b57d7762 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.ts @@ -39,7 +39,7 @@ export class ActivitiPeople { dialog: any; private peopleObserver: Observer; - people$: Observable; + people$: Observable; /** * Constructor @@ -52,7 +52,7 @@ export class ActivitiPeople { if (translate) { translate.addTranslationFolder('node_modules/ng2-activiti-tasklist/src'); } - this.people$ = new Observable(observer => this.peopleObserver = observer).share(); + this.people$ = new Observable(observer => this.peopleObserver = observer).share(); } public showDialog() { diff --git a/ng2-components/ng2-activiti-tasklist/src/i18n/it.json b/ng2-components/ng2-activiti-tasklist/src/i18n/it.json index 62021c250d..66528d70dc 100644 --- a/ng2-components/ng2-activiti-tasklist/src/i18n/it.json +++ b/ng2-components/ng2-activiti-tasklist/src/i18n/it.json @@ -8,7 +8,10 @@ "LABELS": { "ASSIGNEE": "Assegnatario", "DUE": "Scadenza", - "FORM": "Form" + "FORM": "Form", + "PEOPLE": "Persone", + "COMMENTS": "Commenti", + "CHECKLIST": "Checklist" }, "MESSAGES": { "NONE": "Nessun dettaglio task trovato." @@ -25,4 +28,4 @@ "NONE": "Nessun filtro task selezionato." } } -} \ No newline at end of file +} From a3b7df14ce17625c22cfc8235fdb11d10bf6eb3e Mon Sep 17 00:00:00 2001 From: Vito Albano Date: Wed, 2 Nov 2016 09:51:18 +0000 Subject: [PATCH 09/16] add test for people search component --- .../activiti-people-search.component.html | 6 +- .../activiti-people-search.component.spec.ts | 137 ++++++++++++++++++ .../activiti-people-search.component.ts | 14 +- .../activiti-people.component.spec.ts | 5 - .../components/activiti-people.component.ts | 1 - 5 files changed, 150 insertions(+), 13 deletions(-) create mode 100644 ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.spec.ts diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.html b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.html index 6cba3d51e5..f23a2d73ff 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.html +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.html @@ -1,17 +1,17 @@
    -
    • + (click)="onRowClick(user)" id="user-{{user.id}}"> face {{ user.firstName }} - {{ user.lastName }}
    • -
      +
      No user found to involve
    diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.spec.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.spec.ts new file mode 100644 index 0000000000..1c039bdbcd --- /dev/null +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.spec.ts @@ -0,0 +1,137 @@ +/*! + * @license + * Copyright 2016 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 { + CoreModule, + AlfrescoTranslationService +} from 'ng2-alfresco-core'; +import { ActivitiPeopleSearch } from './activiti-people-search.component'; +import { TranslationMock } from '../assets/translation.service.mock'; +import { ComponentFixture, TestBed, async } from '@angular/core/testing'; +import { User } from '../models/user.model'; +import { Observable } from 'rxjs/Observable'; + +declare let jasmine: any; + +const fakeUser: User = new User({ + id: '1', + firstName: 'fake-name', + lastName: 'fake-last', + email: 'fake@mail.com' +}); + +const fakeSecondUser: User = new User({ + id: '2', + firstName: 'fake-involve-name', + lastName: 'fake-involve-last', + email: 'fake-involve@mail.com' +}); + +describe('Activiti People Search', () => { + + let activitiPeopleSearchComponent: ActivitiPeopleSearch; + let fixture: ComponentFixture; + let element: HTMLElement; + let componentHandler; + let userArray = [fakeUser, fakeSecondUser]; + let searchInput; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [CoreModule], + declarations: [ActivitiPeopleSearch], + providers: [ + {provide: AlfrescoTranslationService, useClass: TranslationMock}] + }).compileComponents().then(() => { + fixture = TestBed.createComponent(ActivitiPeopleSearch); + activitiPeopleSearchComponent = fixture.componentInstance; + element = fixture.nativeElement; + componentHandler = jasmine.createSpyObj('componentHandler', [ + 'upgradeAllRegistered' + ]); + + window['componentHandler'] = componentHandler; + activitiPeopleSearchComponent.results = Observable.of([]); + fixture.detectChanges(); + }); + })); + + it('should show input search text', () => { + expect(element.querySelector('#userSearchText')).toBeDefined(); + expect(element.querySelector('#userSearchText')).not.toBeNull(); + }); + + it('should show no user found to involve message', () => { + fixture.detectChanges(); + fixture.whenStable() + .then(() => { + expect(element.querySelector('#no-user-found')).not.toBeNull(); + expect(element.querySelector('#no-user-found').textContent).toContain('No user found to involve'); + }); + }); + + it('should show user which can be involved ', (done) => { + activitiPeopleSearchComponent.onSearch.subscribe(() => { + activitiPeopleSearchComponent.results = Observable.of(userArray); + activitiPeopleSearchComponent.ngOnInit(); + fixture.detectChanges(); + fixture.whenStable() + .then(() => { + expect(element.querySelector('#user-1')).not.toBeNull(); + expect(element.querySelector('#user-1').textContent) + .toContain('fake-name - fake-last'); + expect(element.querySelector('#user-2')).not.toBeNull(); + expect(element.querySelector('#user-2').textContent) + .toContain('fake-involve-name - fake-involve-last'); + done(); + }); + }); + searchInput = element.querySelector('#userSearchText'); + searchInput.value = 'fake-search'; + activitiPeopleSearchComponent.searchUser.markAsDirty(); + searchInput.dispatchEvent(new Event('input')); + }); + + it('should send an event when an user is clicked', async(() => { + activitiPeopleSearchComponent.onModalRowClicked.subscribe((user) => { + expect(user).toBeDefined(); + expect(user.firstName).toBe('fake-name'); + }); + activitiPeopleSearchComponent.results = Observable.of(userArray); + activitiPeopleSearchComponent.ngOnInit(); + fixture.detectChanges(); + fixture.whenStable() + .then(() => { + let userToSelect = element.querySelector('#user-1'); + userToSelect.click(); + }); + })); + + it('should remove clicked user', async(() => { + activitiPeopleSearchComponent.results = Observable.of(userArray); + activitiPeopleSearchComponent.ngOnInit(); + fixture.detectChanges(); + let userToSelect = element.querySelector('#user-1'); + userToSelect.click(); + + fixture.detectChanges(); + fixture.whenStable() + .then(() => { + expect(element.querySelector('#user-1')).toBeNull(); + }); + })); +}); diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.ts index d77de3ac88..ca115088ce 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people-search.component.ts @@ -19,6 +19,7 @@ import { Component, Input, Output, EventEmitter, OnInit, AfterViewInit } from '@ import { FormControl } from '@angular/forms'; import { User } from '../models/user.model'; import { Observable } from 'rxjs/Observable'; +import { AlfrescoTranslationService } from 'ng2-alfresco-core'; declare let componentHandler: any; @@ -40,11 +41,15 @@ export class ActivitiPeopleSearch implements OnInit, AfterViewInit { @Output() onModalRowClicked: EventEmitter = new EventEmitter(); - private searchUser: FormControl = new FormControl(); + searchUser: FormControl = new FormControl(); userList: User[] = []; - constructor() { + constructor(private translate: AlfrescoTranslationService) { + if (translate) { + translate.addTranslationFolder('node_modules/ng2-activiti-tasklist/src'); + } + this.searchUser .valueChanges .debounceTime(200) @@ -65,11 +70,12 @@ export class ActivitiPeopleSearch implements OnInit, AfterViewInit { setupMaterialComponents(handler?: any): boolean { // workaround for MDL issues with dynamic components + let isUpgraded: boolean = false; if (handler) { handler.upgradeAllRegistered(); - return true; + isUpgraded = true; } - return false; + return isUpgraded; } onRowClick(userClicked: User) { diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.spec.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.spec.ts index 1c5737713f..cd177df72c 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.spec.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.spec.ts @@ -68,11 +68,6 @@ describe('Activiti People Component', () => { }); })); - afterAll(() => { - fixture.destroy(); - TestBed.resetTestingModule(); - }); - it('should show people component title', () => { expect(element.querySelector('#people-title')).toBeDefined(); expect(element.querySelector('#people-title')).not.toBeNull(); diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.ts index f8b57d7762..8869922778 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.ts @@ -48,7 +48,6 @@ export class ActivitiPeople { */ constructor(private translate: AlfrescoTranslationService, private peopleService: ActivitiPeopleService) { - if (translate) { translate.addTranslationFolder('node_modules/ng2-activiti-tasklist/src'); } From b57a79c0427be870d568f05d392a5a2997727250 Mon Sep 17 00:00:00 2001 From: Vito Albano Date: Wed, 2 Nov 2016 11:31:23 +0000 Subject: [PATCH 10/16] Added some improvements and clear user list --- .../src/components/activiti-people.component.ts | 1 + .../src/components/activiti-start-task.component.ts | 12 ++++-------- .../components/activiti-task-header.component.ts | 13 ++++--------- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.ts index 8869922778..bece74f85b 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.ts @@ -66,6 +66,7 @@ export class ActivitiPeople { public cancel() { if (this.dialog) { this.dialog.nativeElement.close(); + this.peopleObserver.next([]); } } diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.ts index 15da8c356d..2f0a8f7c60 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.ts @@ -15,8 +15,8 @@ * limitations under the License. */ -import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core'; -import { AlfrescoTranslationService, AlfrescoAuthenticationService } from 'ng2-alfresco-core'; +import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core'; +import { AlfrescoTranslationService } from 'ng2-alfresco-core'; import { TaskDetailsModel } from '../models/task-details.model'; import { ActivitiTaskListService } from './../services/activiti-tasklist.service'; @@ -29,7 +29,7 @@ declare let dialogPolyfill: any; templateUrl: './activiti-start-task.component.html', styleUrls: ['./activiti-start-task.component.css'] }) -export class ActivitiStartProcessButton implements OnInit { +export class ActivitiStartProcessButton { @Input() appId: string; @@ -49,8 +49,7 @@ export class ActivitiStartProcessButton implements OnInit { * @param translate * @param taskService */ - constructor(private auth: AlfrescoAuthenticationService, - private translate: AlfrescoTranslationService, + constructor(private translate: AlfrescoTranslationService, private taskService: ActivitiTaskListService) { if (translate) { @@ -58,9 +57,6 @@ export class ActivitiStartProcessButton implements OnInit { } } - ngOnInit() { - } - public start() { if (this.name) { this.taskService.createNewTask(new TaskDetailsModel({ diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-header.component.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-header.component.ts index 19b1dcb95d..2d86438e27 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-header.component.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-header.component.ts @@ -15,8 +15,8 @@ * limitations under the License. */ -import { Component, Input, OnInit } from '@angular/core'; -import { AlfrescoTranslationService, AlfrescoAuthenticationService } from 'ng2-alfresco-core'; +import { Component, Input } from '@angular/core'; +import { AlfrescoTranslationService } from 'ng2-alfresco-core'; import { TaskDetailsModel } from '../models/task-details.model'; declare let componentHandler: any; @@ -27,7 +27,7 @@ declare let componentHandler: any; templateUrl: './activiti-task-header.component.html', styleUrls: ['./activiti-task-header.component.css'] }) -export class ActivitiTaskHeader implements OnInit { +export class ActivitiTaskHeader { @Input() taskDetails: TaskDetailsModel; @@ -37,16 +37,11 @@ export class ActivitiTaskHeader implements OnInit { * @param auth * @param translate */ - constructor(private auth: AlfrescoAuthenticationService, - private translate: AlfrescoTranslationService) { + constructor(private translate: AlfrescoTranslationService) { if (translate) { translate.addTranslationFolder('node_modules/ng2-activiti-tasklist/src'); } } - ngOnInit() { - - } - } From 207d2206eb24c4926d30527c7c36d8675073e003 Mon Sep 17 00:00:00 2001 From: Vito Albano Date: Wed, 2 Nov 2016 17:18:15 +0000 Subject: [PATCH 11/16] Added start task test --- ng2-components/ng2-activiti-tasklist/index.ts | 4 +- .../activiti-start-task.component.html | 24 ++-- .../activiti-start-task.component.spec.ts | 124 ++++++++++++++++++ .../activiti-start-task.component.ts | 2 +- 4 files changed, 143 insertions(+), 11 deletions(-) create mode 100644 ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.spec.ts diff --git a/ng2-components/ng2-activiti-tasklist/index.ts b/ng2-components/ng2-activiti-tasklist/index.ts index e2494041dc..3e4263e937 100644 --- a/ng2-components/ng2-activiti-tasklist/index.ts +++ b/ng2-components/ng2-activiti-tasklist/index.ts @@ -32,7 +32,7 @@ import { ActivitiComments, ActivitiPeople, ActivitiTaskHeader, - ActivitiStartProcessButton, + ActivitiStartTaskButton, ActivitiPeopleSearch } from './src/components/index'; @@ -50,7 +50,7 @@ export const ACTIVITI_TASKLIST_DIRECTIVES: any[] = [ ActivitiComments, ActivitiPeople, ActivitiTaskHeader, - ActivitiStartProcessButton, + ActivitiStartTaskButton, ActivitiPeopleSearch ]; diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.html b/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.html index 837e1730fb..fb369d4477 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.html +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.html @@ -1,19 +1,27 @@ - + - -

    {{'START_TASK.DIALOG.TITLE'|translate}}

    + +

    {{'START_TASK.DIALOG.TITLE'|translate}}

    - +
    - - + +
    - - + +
    diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.spec.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.spec.ts new file mode 100644 index 0000000000..509a898e10 --- /dev/null +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.spec.ts @@ -0,0 +1,124 @@ +/*! + * @license + * Copyright 2016 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 { + CoreModule, + AlfrescoTranslationService +} from 'ng2-alfresco-core'; +import { ActivitiTaskListService } from '../services/activiti-tasklist.service'; +import { ActivitiStartTaskButton } from './activiti-start-task.component'; +import { TranslationMock } from '../assets/translation.service.mock'; +import { ComponentFixture, TestBed, async } from '@angular/core/testing'; + +declare let jasmine: any; + +describe('Activiti Start Task Component', () => { + + let activitiStartTaskButton: ActivitiStartTaskButton; + let fixture: ComponentFixture; + let element: HTMLElement; + let startTaskButton: HTMLElement; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [CoreModule], + declarations: [ActivitiStartTaskButton], + providers: [ + {provide: AlfrescoTranslationService, useClass: TranslationMock}, + ActivitiTaskListService] + }).compileComponents().then(() => { + fixture = TestBed.createComponent(ActivitiStartTaskButton); + activitiStartTaskButton = fixture.componentInstance; + element = fixture.nativeElement; + fixture.detectChanges(); + startTaskButton = element.querySelector('#start-task-button'); + }); + })); + + beforeEach(() => { + jasmine.Ajax.install(); + }); + + afterEach(() => { + jasmine.Ajax.uninstall(); + }); + + it('should show start task button', () => { + expect(element.querySelector('#start-task-button')).toBeDefined(); + expect(element.querySelector('#start-task-button')).not.toBeNull(); + expect(element.querySelector('#start-task-button').textContent).toContain('START_TASK.BUTTON'); + }); + + it('should show start dialog on press button', () => { + startTaskButton.click(); + expect(element.querySelector('#start-task-dialog')).not.toBeNull(); + expect(element.querySelector('#start-task-dialog').getAttribute('open')).not.toBeNull(); + expect(element.querySelector('#start-task-dialog-title')).not.toBeNull(); + expect(element.querySelector('#start-task-dialog-title').textContent).toContain('START_TASK.DIALOG.TITLE'); + }); + + it('should close start dialog on cancel button', () => { + startTaskButton.click(); + expect(element.querySelector('#start-task-dialog')).not.toBeNull(); + expect(element.querySelector('#start-task-dialog').getAttribute('open')).not.toBeNull(); + let cancelButton = element.querySelector('#button-cancel'); + cancelButton.click(); + expect(element.querySelector('#start-task-dialog').getAttribute('open')).toBeNull(); + }); + + it('should create new task when start is clicked', () => { + activitiStartTaskButton.onSuccess.subscribe(() => { + expect(element.querySelector('#start-task-dialog').getAttribute('open')).toBeNull(); + }); + let createTaskButton = element.querySelector('#button-start'); + startTaskButton.click(); + activitiStartTaskButton.name = 'fake-name'; + createTaskButton.click(); + jasmine.Ajax.requests.mostRecent().respondWith({ + 'status': 200 + }); + }); + + it('alert message is showed on start error', () => { + spyOn(window, 'alert'); + activitiStartTaskButton.onSuccess.subscribe(() => { + expect(window.alert).toHaveBeenCalledWith('An error occurred while trying to add the task'); + }); + let createTaskButton = element.querySelector('#button-start'); + startTaskButton.click(); + activitiStartTaskButton.name = 'fake-name'; + createTaskButton.click(); + jasmine.Ajax.requests.mostRecent().respondWith({ + 'status': 403 + }); + }); + + it('should send on success event when the task is started', () => { + activitiStartTaskButton.onSuccess.subscribe((res) => { + expect(res).toBeDefined(); + }); + let createTaskButton = element.querySelector('#button-start'); + startTaskButton.click(); + activitiStartTaskButton.name = 'fake-name'; + createTaskButton.click(); + jasmine.Ajax.requests.mostRecent().respondWith({ + 'status': 200, + contentType: 'json', + responseText: {} + }); + }); +}); diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.ts index 2f0a8f7c60..f31b0e3ede 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.ts @@ -29,7 +29,7 @@ declare let dialogPolyfill: any; templateUrl: './activiti-start-task.component.html', styleUrls: ['./activiti-start-task.component.css'] }) -export class ActivitiStartProcessButton { +export class ActivitiStartTaskButton { @Input() appId: string; From 8ea6df0157fc70370b5c929d3c1c01ed92f230cd Mon Sep 17 00:00:00 2001 From: Vito Albano Date: Thu, 3 Nov 2016 14:36:14 +0000 Subject: [PATCH 12/16] Added test for checklist - fixed test for people --- .../activiti-checklist.component.html | 24 +-- .../activiti-checklist.component.spec.ts | 172 ++++++++++++++++++ .../activiti-checklist.component.ts | 5 +- .../activiti-people.component.spec.ts | 30 ++- 4 files changed, 199 insertions(+), 32 deletions(-) create mode 100644 ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.spec.ts diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.html b/ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.html index 9bfdf6e968..7cc63454db 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.html +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.html @@ -1,33 +1,33 @@ -{{ 'TASK_DETAILS.LABELS.CHECKLIST' | translate }} -
    add
    -
    +
    add
    +
    Add a checklist
    -
    +
    {{ 'TASK_DETAILS.CHECKLIST.NONE' | translate }}
    - -

    New Task

    + +

    New Check

    - - + +
    - - + +
    -
    \ No newline at end of file +
    diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.spec.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.spec.ts new file mode 100644 index 0000000000..35ff285f11 --- /dev/null +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.spec.ts @@ -0,0 +1,172 @@ +/*! + * @license + * Copyright 2016 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 { + CoreModule, + AlfrescoTranslationService +} from 'ng2-alfresco-core'; +import { SimpleChange } from '@angular/core'; +import { ActivitiTaskListService } from '../services/activiti-tasklist.service'; +import { ActivitiChecklist } from './activiti-checklist.component'; +import { TranslationMock } from '../assets/translation.service.mock'; +import { ComponentFixture, TestBed, async } from '@angular/core/testing'; +import { TaskDetailsModel } from '../models/task-details.model'; + +declare let jasmine: any; + +const fakeTaskDetail = new TaskDetailsModel({ + id: 'fake-check-id', + name: 'fake-check-name' +}); + +describe('Activiti Checklist Component', () => { + + let checklistComponent: ActivitiChecklist; + let fixture: ComponentFixture; + let element: HTMLElement; + let showChecklistDialog, closeCheckDialogButton; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [CoreModule], + declarations: [ActivitiChecklist], + providers: [ + {provide: AlfrescoTranslationService, useClass: TranslationMock}, + ActivitiTaskListService] + }).compileComponents().then(() => { + fixture = TestBed.createComponent(ActivitiChecklist); + checklistComponent = fixture.componentInstance; + element = fixture.nativeElement; + fixture.detectChanges(); + }); + })); + + it('should show people component title', () => { + expect(element.querySelector('#checklist-label')).toBeDefined(); + expect(element.querySelector('#checklist-label')).not.toBeNull(); + }); + + it('should show no checklist message', () => { + expect(element.querySelector('#checklist-none-message')).not.toBeNull(); + expect(element.querySelector('#checklist-none-message').textContent).toContain('TASK_DETAILS.CHECKLIST.NONE'); + }); + + describe('when interact with people dialog', () => { + + beforeEach(() => { + checklistComponent.taskId = 'fake-task-id'; + checklistComponent.checklist = []; + fixture.detectChanges(); + showChecklistDialog = element.querySelector('#add-checklist'); + closeCheckDialogButton = element.querySelector('#close-check-dialog'); + }); + + it('should show dialog when clicked on add', () => { + expect(showChecklistDialog).not.toBeNull(); + showChecklistDialog.click(); + + expect(element.querySelector('#checklist-dialog')).not.toBeNull(); + expect(element.querySelector('#add-checklist-title')).not.toBeNull(); + expect(element.querySelector('#add-checklist-title').textContent).toContain('New Check'); + }); + + it('should close dialog when clicked on cancel', () => { + showChecklistDialog.click(); + expect(element.querySelector('#checklist-dialog').getAttribute('open')).not.toBeNull(); + closeCheckDialogButton.click(); + expect(element.querySelector('#checklist-dialog').getAttribute('open')).toBeNull(); + }); + }); + + describe('when there are task checklist', () => { + + beforeEach(() => { + checklistComponent.taskId = 'fake-task-id'; + checklistComponent.checklist = []; + fixture.detectChanges(); + showChecklistDialog = element.querySelector('#add-checklist'); + }); + + beforeEach(() => { + jasmine.Ajax.install(); + }); + + afterEach(() => { + jasmine.Ajax.uninstall(); + }); + + it('should show task checklist', () => { + checklistComponent.checklist.push(fakeTaskDetail); + fixture.detectChanges(); + expect(element.querySelector('#check-fake-check-id')).not.toBeNull(); + expect(element.querySelector('#check-fake-check-id').textContent).toContain('fake-check-name'); + }); + + it('should add checklist', async(() => { + showChecklistDialog.click(); + let addButtonDialog = element.querySelector('#add-check'); + addButtonDialog.click(); + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'json', + responseText: {id: 'fake-check-added-id', name: 'fake-check-added-name'} + }); + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('#check-fake-check-added-id')).not.toBeNull(); + expect(element.querySelector('#check-fake-check-added-id').textContent).toContain('fake-check-added-name'); + }); + })); + + it('should show load task checklist on change', async(() => { + checklistComponent.taskId = 'new-fake-task-id'; + checklistComponent.checklist.push(fakeTaskDetail); + fixture.detectChanges(); + let change = new SimpleChange(null, 'new-fake-task-id'); + checklistComponent.ngOnChanges({ + taskId: change + }); + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'json', + responseText: {data: [{id: 'fake-check-changed-id', name: 'fake-check-changed-name'}]} + }); + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('#check-fake-check-changed-id')).not.toBeNull(); + expect(element.querySelector('#check-fake-check-changed-id').textContent).toContain('fake-check-changed-name'); + }); + })); + + it('should show empty checklist when task id is null', async(() => { + checklistComponent.taskId = 'new-fake-task-id'; + checklistComponent.checklist.push(fakeTaskDetail); + fixture.detectChanges(); + checklistComponent.taskId = null; + let change = new SimpleChange(null, 'new-fake-task-id'); + checklistComponent.ngOnChanges({ + taskId: change + }); + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(element.querySelector('#checklist-none-message')).not.toBeNull(); + expect(element.querySelector('#checklist-none-message').textContent).toContain('TASK_DETAILS.CHECKLIST.NONE'); + }); + })); + }); + +}); diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.ts index dab4a8825b..35894db685 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.ts @@ -16,7 +16,7 @@ */ import { Component, Input, OnInit, ViewChild, OnChanges, SimpleChanges } from '@angular/core'; -import { AlfrescoTranslationService, AlfrescoAuthenticationService } from 'ng2-alfresco-core'; +import { AlfrescoTranslationService } from 'ng2-alfresco-core'; import { ActivitiTaskListService } from './../services/activiti-tasklist.service'; import { TaskDetailsModel } from '../models/task-details.model'; import { Observer, Observable } from 'rxjs/Rx'; @@ -48,8 +48,7 @@ export class ActivitiChecklist implements OnInit, OnChanges { * @param auth * @param translate */ - constructor(private auth: AlfrescoAuthenticationService, - private translate: AlfrescoTranslationService, + constructor(private translate: AlfrescoTranslationService, private activitiTaskList: ActivitiTaskListService) { if (translate) { diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.spec.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.spec.ts index cd177df72c..d462229df4 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.spec.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.spec.ts @@ -23,7 +23,7 @@ import { ActivitiPeopleService } from '../services/activiti-people.service'; import { ActivitiPeople } from './activiti-people.component'; import { ActivitiPeopleSearch } from './activiti-people-search.component'; import { TranslationMock } from '../assets/translation.service.mock'; -import { ComponentFixture, TestBed, async, fakeAsync, tick } from '@angular/core/testing'; +import { ComponentFixture, TestBed, async } from '@angular/core/testing'; import { User } from '../models/user.model'; declare let jasmine: any; @@ -130,28 +130,26 @@ describe('Activiti People Component', () => { expect(element.querySelector('#user-fake-id').textContent).toContain('fake-last'); }); - it('should remove pepole involved', fakeAsync(() => { + it('should remove pepole involved', async(() => { activitiPeopleComponent.removeInvolvedUser(fakeUser); jasmine.Ajax.requests.mostRecent().respondWith({ status: 200 }); - tick(); - fixture.detectChanges(); fixture.whenStable() .then(() => { + fixture.detectChanges(); expect(element.querySelector('#user-fake-id')).toBeNull(); }); })); - it('should involve pepole', fakeAsync(() => { + it('should involve pepole', async(() => { activitiPeopleComponent.involveUser(fakeUserToInvolve); jasmine.Ajax.requests.mostRecent().respondWith({ status: 200 }); - tick(); - fixture.detectChanges(); fixture.whenStable() .then(() => { + fixture.detectChanges(); expect(element.querySelector('#user-fake-involve-id')).not.toBeNull(); expect(element.querySelector('#user-fake-involve-id').textContent) .toBe('fake-involve-name fake-involve-last'); @@ -211,43 +209,41 @@ describe('Activiti People Component', () => { jasmine.Ajax.uninstall(); }); - it('should log error message when search fails', fakeAsync(() => { + it('should log error message when search fails', async(() => { console.log = jasmine.createSpy('log'); + activitiPeopleComponent.people$.subscribe(() => { + expect(console.log).toHaveBeenCalledWith('Could not load users'); + }); activitiPeopleComponent.searchUser('fake-search'); jasmine.Ajax.requests.mostRecent().respondWith({ status: 403 }); - tick(); - - expect(console.log).toHaveBeenCalledWith('Could not load users'); })); - it('should not remove user if remove involved user fail', fakeAsync(() => { + it('should not remove user if remove involved user fail', async(() => { activitiPeopleComponent.people.push(fakeUser); fixture.detectChanges(); activitiPeopleComponent.removeInvolvedUser(fakeUser); jasmine.Ajax.requests.mostRecent().respondWith({ status: 403 }); - tick(); - fixture.detectChanges(); fixture.whenStable() .then(() => { + fixture.detectChanges(); expect(element.querySelector('#user-fake-id')).not.toBeNull(); expect(element.querySelector('#user-fake-id').textContent) .toBe('fake-name fake-last'); }); })); - it('should not involve user if involve user fail', fakeAsync(() => { + it('should not involve user if involve user fail', async(() => { activitiPeopleComponent.involveUser(fakeUserToInvolve); jasmine.Ajax.requests.mostRecent().respondWith({ status: 403 }); - tick(); - fixture.detectChanges(); fixture.whenStable() .then(() => { + fixture.detectChanges(); expect(element.querySelector('#user-fake-id')).toBeNull(); expect(element.querySelector('#no-people-label').textContent).toContain('TASK_DETAILS.PEOPLE.NONE'); }); From a1243747b4a6f326a6cb306ba67c6d6303a598ee Mon Sep 17 00:00:00 2001 From: Vito Albano Date: Thu, 3 Nov 2016 15:05:00 +0000 Subject: [PATCH 13/16] Disabled action on readonly task --- .../src/components/activiti-checklist.component.html | 4 ++-- .../src/components/activiti-checklist.component.ts | 3 +++ .../src/components/activiti-comments.component.html | 6 +++--- .../src/components/activiti-comments.component.ts | 3 +++ .../src/components/activiti-people.component.html | 9 +++++---- .../src/components/activiti-people.component.ts | 3 +++ .../src/components/activiti-task-details.component.html | 9 ++++++--- 7 files changed, 25 insertions(+), 12 deletions(-) diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.html b/ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.html index 7cc63454db..1f74274e2b 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.html +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.html @@ -1,7 +1,7 @@ {{ 'TASK_DETAILS.LABELS.CHECKLIST' | translate }} -
    add
    -
    +
    add
    +
    Add a checklist
    \ No newline at end of file +
    diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-comments.component.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-comments.component.ts index a2be327c5b..10f5a7b1a4 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-comments.component.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-comments.component.ts @@ -33,6 +33,9 @@ export class ActivitiComments implements OnInit, OnChanges { @Input() taskId: string; + @Input() + readOnly: boolean = false; + @ViewChild('dialog') dialog: any; diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.html b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.html index 4104152578..ee8e956297 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.html +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.html @@ -1,7 +1,7 @@ {{ 'TASK_DETAILS.LABELS.PEOPLE' | translate }} -
    add
    -
    +
    add
    +
    Add a person