-
-
-
-
+
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..7ede77c23e
--- /dev/null
+++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-people.component.spec.ts
@@ -0,0 +1,252 @@
+/*!
+ * @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 { 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 } 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({
+ 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 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', async(() => {
+ activitiPeopleComponent.removeInvolvedUser(fakeUser);
+ jasmine.Ajax.requests.mostRecent().respondWith({
+ status: 200
+ });
+ fixture.whenStable()
+ .then(() => {
+ fixture.detectChanges();
+ expect(element.querySelector('#user-fake-id')).toBeNull();
+ });
+ }));
+
+ it('should involve pepole', async(() => {
+ activitiPeopleComponent.involveUser(fakeUserToInvolve);
+ jasmine.Ajax.requests.mostRecent().respondWith({
+ status: 200
+ });
+ 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');
+ });
+ }));
+
+ it('should return an observable with user search results', (done) => {
+ activitiPeopleComponent.peopleSearch$.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.peopleSearch$.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', async(() => {
+ console.log = jasmine.createSpy('log');
+ activitiPeopleComponent.peopleSearch$.subscribe(() => {
+ expect(console.log).toHaveBeenCalledWith('Could not load users');
+ });
+ activitiPeopleComponent.searchUser('fake-search');
+ jasmine.Ajax.requests.mostRecent().respondWith({
+ status: 403
+ });
+ }));
+
+ 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
+ });
+ 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', async(() => {
+ activitiPeopleComponent.involveUser(fakeUserToInvolve);
+ jasmine.Ajax.requests.mostRecent().respondWith({
+ status: 403
+ });
+ fixture.whenStable()
+ .then(() => {
+ fixture.detectChanges();
+ 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 7ce00fc1a3..e4fa29919e 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,56 +27,79 @@ 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 = '';
+
+ @Input()
+ readOnly: boolean = false;
+
@ViewChild('dialog')
dialog: any;
- private peopleObserver: Observer;
- people$: Observable;
+ private peopleSearchObserver: Observer;
+ peopleSearch$: 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.peopleSearch$ = new Observable(observer => this.peopleSearchObserver = observer).share();
}
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();
}
}
- public add() {
- alert('add people');
-
- this.cancel();
- }
-
public cancel() {
if (this.dialog) {
this.dialog.nativeElement.close();
+ this.peopleSearchObserver.next([]);
}
}
+ searchUser(searchedWord: string) {
+ this.peopleService.getWorkflowUsers(this.taskId, searchedWord)
+ .subscribe((users) => {
+ this.peopleSearchObserver.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'));
+ }
+
+ getDisplayUser(user: User): string {
+ let firstName = user.firstName && user.firstName !== 'null' ? user.firstName : 'N/A';
+ let lastName = user.lastName && user.lastName !== 'null' ? user.lastName : 'N/A';
+ return firstName + ' ' + lastName;
+ }
+
}
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 @@
-
+
-