Complete test coverage for ActivitiProcessService

Refs #849
This commit is contained in:
Will Abson
2016-11-15 17:41:09 +00:00
committed by Mario Romano
parent 335deed54a
commit 8f97c76668
17 changed files with 825 additions and 107 deletions

View File

@@ -34,6 +34,9 @@ import { ActivitiProcessService } from './src/services/activiti-process.service'
export * from './src/components/activiti-processlist.component';
export * from './src/components/activiti-process-instance-details.component';
// models
export * from './src/models/index';
// services
export * from './src/services/activiti-process.service';

View File

@@ -48,6 +48,9 @@ module.exports = function (config) {
{ pattern: 'node_modules/ng2-activiti-tasklist/dist/**/*.*', included: false, served: true, watched: false },
{ pattern: 'node_modules/ng2-activiti-form/dist/**/*.*', included: false, served: true, watched: false },
// library dependencies
{ pattern: 'node_modules/moment/moment.js', included: true, watched: false },
// paths to support debugging with source maps in dev tools
{pattern: 'src/**/*.ts', included: false, watched: false},
{pattern: 'dist/**/*.js.map', included: false, watched: false}

View File

@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { ProcessInstance } from '../models/process-instance';
import { ProcessInstance } from '../models/process-instance.model';
export class ProcessList {

View File

@@ -15,10 +15,17 @@
* limitations under the License.
*/
import { FilterRepresentationModel } from 'ng2-activiti-tasklist';
import {
AppDefinitionRepresentationModel,
Comment,
FilterRepresentationModel,
TaskDetailsModel,
User
} from 'ng2-activiti-tasklist';
import { ProcessDefinitionRepresentation } from '../models/index';
export var fakeFilters = {
size: 0, total: 0, start: 0,
size: 1, total: 1, start: 0,
data: [new FilterRepresentationModel({
'name': 'Running',
'appId': '22',
@@ -33,16 +40,54 @@ export var fakeEmptyFilters = {
data: []
};
export var fakeApi = {
activiti: {
userFiltersApi: {
getUserProcessInstanceFilters: (filterOpts) => Promise.resolve({}),
createUserProcessInstanceFilter: (filter: FilterRepresentationModel) => Promise.resolve(filter)
}
}
};
export var fakeError = {
message: null,
messageKey: 'GENERAL.ERROR.FORBIDDEN'
};
export var fakeApp1 = new AppDefinitionRepresentationModel({
deploymentId: 26,
name: 'HR processes',
icon: 'glyphicon-cloud',
description: null,
theme: 'theme-6',
modelId: 4,
id: 1
});
export var fakeApp2 = new AppDefinitionRepresentationModel({
deploymentId: 2501,
name: 'Sales onboarding',
icon: 'glyphicon-asterisk',
description: null,
theme: 'theme-1',
modelId: 1002,
id: 1000
});
export var fakeTaskList = {
data: [ new TaskDetailsModel({
id: 1,
name: 'Task 1',
processInstanceId: 1000,
created: '2016-11-10T03:37:30.010+0000'
}), new TaskDetailsModel({
id: 2,
name: 'Task 2',
processInstanceId: 1000,
created: '2016-11-10T03:37:30.010+0000'
})]
};
export var fakeComment = new Comment(1, 'Test', '2016-11-10T03:37:30.010+0000', new User({
id: 13,
firstName: 'Wilbur',
lastName: 'Adams',
email: 'wilbur@app.com'
}));
export var fakeProcessDef = new ProcessDefinitionRepresentation({
id: '32323',
key: 'blah',
name: 'Process 1'
});

View File

@@ -84,7 +84,7 @@ describe('ActivitiFilters', () => {
});
it('should emit an error with a bad response', (done) => {
filterList.appId = '1';
filterList.appId = 1;
spyOn(activitiService, 'getProcessFilters').and.returnValue(Observable.fromPromise(fakeErrorFilterPromise));
filterList.onError.subscribe((err) => {

View File

@@ -41,7 +41,7 @@ export class ActivitiProcessFilters implements OnInit, OnChanges {
onError: EventEmitter<any> = new EventEmitter<any>();
@Input()
appId: string;
appId: number;
@Input()
appName: string;
@@ -88,7 +88,7 @@ export class ActivitiProcessFilters implements OnInit, OnChanges {
* @param appId
* @param appName
*/
getFilters(appId?: string, appName?: string) {
getFilters(appId?: number, appName?: string) {
if (appName) {
this.getFiltersByAppName(appName);
} else {
@@ -100,7 +100,7 @@ export class ActivitiProcessFilters implements OnInit, OnChanges {
* Return the filter list filtered by appId
* @param appId - optional
*/
getFiltersByAppId(appId?: string) {
getFiltersByAppId(appId?: number) {
this.activiti.getProcessFilters(appId).subscribe(
(res: FilterRepresentationModel[]) => {
this.resetFilter();

View File

@@ -21,7 +21,7 @@ import { ActivitiProcessService } from './../services/activiti-process.service';
import { ActivitiProcessInstanceHeader } from './activiti-process-instance-header.component';
import { ActivitiProcessInstanceTasks } from './activiti-process-instance-tasks.component';
import { ActivitiComments } from './activiti-comments.component';
import { ProcessInstance } from '../models/process-instance';
import { ProcessInstance } from '../models/process-instance.model';
declare let componentHandler: any;

View File

@@ -23,7 +23,7 @@ import { AlfrescoTranslationService, CoreModule } from 'ng2-alfresco-core';
import { ActivitiProcessInstanceHeader } from './activiti-process-instance-header.component';
import { TranslationMock } from './../assets/translation.service.mock';
import { exampleProcess } from './../assets/activiti-process.model.mock';
import { ProcessInstance } from './../models/process-instance';
import { ProcessInstance } from './../models/process-instance.model';
import { ActivitiProcessService } from './../services/activiti-process.service';
describe('ActivitiProcessInstanceHeader', () => {

View File

@@ -17,7 +17,7 @@
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { AlfrescoTranslationService } from 'ng2-alfresco-core';
import { ProcessInstance } from '../models/process-instance';
import { ProcessInstance } from '../models/process-instance.model';
import { ActivitiProcessService } from './../services/activiti-process.service';
import { DatePipe } from '@angular/common';

View File

@@ -26,7 +26,7 @@ import { TaskDetailsModel } from 'ng2-activiti-tasklist';
import { ActivitiProcessInstanceTasks } from './activiti-process-instance-tasks.component';
import { TranslationMock } from './../assets/translation.service.mock';
import { taskDetailsMock } from './../assets/task-details.mock';
import { ProcessInstance } from './../models/process-instance';
import { ProcessInstance } from './../models/process-instance.model';
import { ActivitiProcessService } from './../services/activiti-process.service';
describe('ActivitiProcessInstanceTasks', () => {

View File

@@ -21,7 +21,7 @@ import { ActivitiProcessService } from './../services/activiti-process.service';
import { TaskDetailsModel } from 'ng2-activiti-tasklist';
import { Observable, Observer } from 'rxjs/Rx';
import { DatePipe } from '@angular/common';
import { ProcessInstance } from '../models/process-instance';
import { ProcessInstance } from '../models/process-instance.model';
declare let componentHandler: any;
declare let dialogPolyfill: any;

View File

@@ -0,0 +1,20 @@
/*!
* @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.
*/
export * from './process-definition.model';
export * from './process-instance.model';
export * from './process-instance-filter.model';

View File

@@ -0,0 +1,42 @@
/*!
* @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.
*/
export class ProcessDefinitionRepresentation {
id: string;
name: string;
description: string;
key: string;
category: string;
version: number;
deploymentId: string;
tenantId: string;
metaDataValues: any[];
hasStartForm: boolean;
constructor(obj?: any) {
this.id = obj && obj.id || null;
this.name = obj && obj.name || null;
this.description = obj && obj.description || null;
this.key = obj && obj.key || null;
this.category = obj && obj.category || null;
this.version = obj && obj.version || 0;
this.deploymentId = obj && obj.deploymentId || null;
this.tenantId = obj && obj.tenantId || null;
this.metaDataValues = obj && obj.metaDataValues || [];
this.hasStartForm = obj && obj.hasStartForm === true ? true : false;
}
}

View File

@@ -0,0 +1,34 @@
/*!
* @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.
*/
export class ProcessFilterRequestRepresentation {
processDefinitionId: string;
appDefinitionId: string;
state: string;
sort: string;
page: number;
size: number;
constructor(obj?: any) {
this.processDefinitionId = obj && obj.processDefinitionId || null;
this.appDefinitionId = obj && obj.appDefinitionId || null;
this.state = obj && obj.state || null;
this.sort = obj && obj.sort || null;
this.page = obj && obj.page || 0;
this.size = obj && obj.size || 25;
}
}

View File

@@ -16,18 +16,34 @@
*/
import { ReflectiveInjector } from '@angular/core';
import { async } from '@angular/core/testing';
import {
AlfrescoAuthenticationService,
AlfrescoSettingsService,
AlfrescoApiService
} from 'ng2-alfresco-core';
import { fakeApi, fakeEmptyFilters, fakeFilters, fakeError } from '../assets/activiti-process.service.mock';
import { FilterRepresentationModel } from 'ng2-activiti-tasklist';
import { AlfrescoApi } from 'alfresco-js-api';
import {
fakeEmptyFilters,
fakeFilters,
fakeError,
fakeApp1,
fakeApp2,
fakeTaskList,
fakeComment,
fakeProcessDef
} from '../assets/activiti-process.service.mock';
import { exampleProcess } from '../assets/activiti-process.model.mock';
import { ProcessFilterRequestRepresentation } from '../models/process-instance-filter.model';
import { ActivitiProcessService } from './activiti-process.service';
describe('ActivitiProcessService', () => {
let service: ActivitiProcessService;
let authenticationService: AlfrescoAuthenticationService;
let injector: ReflectiveInjector;
let alfrescoApi: AlfrescoApi;
beforeEach(() => {
injector = ReflectiveInjector.resolveAndCreate([
@@ -37,81 +53,636 @@ describe('ActivitiProcessService', () => {
AlfrescoSettingsService
]);
service = injector.get(ActivitiProcessService);
let authenticationService: AlfrescoAuthenticationService = injector.get(AlfrescoAuthenticationService);
spyOn(authenticationService, 'getAlfrescoApi').and.returnValue(fakeApi);
authenticationService = injector.get(AlfrescoAuthenticationService);
alfrescoApi = authenticationService.getAlfrescoApi();
});
xit('should get process instances', (done) => {
describe('process instances', () => {
let getProcessInstances: jasmine.Spy;
beforeEach(() => {
getProcessInstances = spyOn(alfrescoApi.activiti.processApi, 'getProcessInstances')
.and
.returnValue(Promise.resolve({ data: [ exampleProcess ] }));
});
it('should return the correct number of instances', async(() => {
service.getProcessInstances(null).subscribe((instances) => {
expect(instances.length).toBe(1);
});
}));
it('should return the correct instance data', async(() => {
service.getProcessInstances(null).subscribe((instances) => {
let instance = instances[0];
expect(instance.id).toBe(exampleProcess.id);
expect(instance.name).toBe(exampleProcess.name);
expect(instance.started).toBe(exampleProcess.started);
});
}));
it('should call service to fetch process instances', () => {
service.getProcessInstances(null);
expect(getProcessInstances).toHaveBeenCalled();
});
it('should call service with default parameters if no filter specified', () => {
service.getProcessInstances(null);
expect(getProcessInstances).toHaveBeenCalledWith(new ProcessFilterRequestRepresentation({
page: 0,
sort: 'created-desc',
state: 'all'
}));
});
it('should call service with supplied parameters', () => {
let filter: ProcessFilterRequestRepresentation = new ProcessFilterRequestRepresentation({
processDefinitionId: '1',
appDefinitionId: '1',
page: 1,
sort: 'created-asc',
state: 'completed'
});
service.getProcessInstances(filter);
expect(getProcessInstances).toHaveBeenCalledWith(filter);
});
it('should pass on any error that is returned by the API', async(() => {
getProcessInstances = getProcessInstances.and.returnValue(Promise.reject(fakeError));
service.getProcessInstances(null).subscribe(
() => {},
(res) => {
expect(res).toBe(fakeError);
}
);
}));
it('should return a default error if no data is returned by the API', async(() => {
getProcessInstances = getProcessInstances.and.returnValue(Promise.reject(null));
service.getProcessInstances(null).subscribe(
() => {},
(res) => {
expect(res).toBe('Server error');
}
);
}));
});
describe('process instance', () => {
const processId = 'test';
let getProcessInstance: jasmine.Spy;
beforeEach(() => {
getProcessInstance = spyOn(alfrescoApi.activiti.processApi, 'getProcessInstance')
.and
.returnValue(Promise.resolve(exampleProcess));
});
it('should return the correct instance data', async(() => {
service.getProcess(processId).subscribe((instance) => {
expect(instance.id).toBe(exampleProcess.id);
expect(instance.name).toBe(exampleProcess.name);
expect(instance.started).toBe(exampleProcess.started);
});
}));
it('should call service to fetch process instances', () => {
service.getProcess(processId);
expect(getProcessInstance).toHaveBeenCalled();
});
it('should call service with supplied process ID', () => {
service.getProcess(processId);
expect(getProcessInstance).toHaveBeenCalledWith(processId);
});
it('should pass on any error that is returned by the API', async(() => {
getProcessInstance = getProcessInstance.and.returnValue(Promise.reject(fakeError));
service.getProcess(null).subscribe(
() => {},
(res) => {
expect(res).toBe(fakeError);
}
);
}));
it('should return a default error if no data is returned by the API', async(() => {
getProcessInstance = getProcessInstance.and.returnValue(Promise.reject(null));
service.getProcess(null).subscribe(
() => {},
(res) => {
expect(res).toBe('Server error');
}
);
}));
});
describe('start process instance', () => {
const processDefId = '1234', processName = 'My process instance';
let startNewProcessInstance: jasmine.Spy;
beforeEach(() => {
startNewProcessInstance = spyOn(alfrescoApi.activiti.processApi, 'startNewProcessInstance')
.and
.returnValue(Promise.resolve(exampleProcess));
});
it('should call the API to create the process instance', () => {
service.startProcess(processDefId, processName);
expect(startNewProcessInstance).toHaveBeenCalledWith({
name: processName,
processDefinitionId: processDefId
});
});
it('should call the API to create the process instance with form parameters', () => {
let formParams = {
type: 'ford',
color: 'red'
};
service.startProcess(processDefId, processName, formParams);
expect(startNewProcessInstance).toHaveBeenCalledWith({
name: processName,
processDefinitionId: processDefId,
values: formParams
});
});
it('should return the created process instance', async(() => {
service.startProcess(processDefId, processName).subscribe((createdProcess) => {
expect(createdProcess.id).toBe(exampleProcess.id);
expect(createdProcess.name).toBe(exampleProcess.name);
expect(createdProcess.started).toBe(exampleProcess.started);
expect(createdProcess.startedBy.id).toBe(exampleProcess.startedBy.id);
});
}));
it('should pass on any error that is returned by the API', async(() => {
startNewProcessInstance = startNewProcessInstance.and.returnValue(Promise.reject(fakeError));
service.startProcess(processDefId, processName).subscribe(
() => {},
(res) => {
expect(res).toBe(fakeError);
}
);
}));
it('should return a default error if no data is returned by the API', async(() => {
startNewProcessInstance = startNewProcessInstance.and.returnValue(Promise.reject(null));
service.startProcess(processDefId, processName).subscribe(
() => {},
(res) => {
expect(res).toBe('Server error');
}
);
}));
});
describe('cancel process instance', () => {
const processInstanceId = '1234';
let deleteProcessInstance: jasmine.Spy;
beforeEach(() => {
deleteProcessInstance = spyOn(alfrescoApi.activiti.processApi, 'deleteProcessInstance')
.and
.returnValue(Promise.resolve());
});
it('should call service to delete process instances', () => {
service.cancelProcess(processInstanceId);
expect(deleteProcessInstance).toHaveBeenCalled();
});
it('should call service with supplied process ID', () => {
service.cancelProcess(processInstanceId);
expect(deleteProcessInstance).toHaveBeenCalledWith(processInstanceId);
});
it('should run the success callback', (done) => {
service.cancelProcess(processInstanceId).subscribe(() => {
done();
});
});
it('should pass on any error that is returned by the API', async(() => {
deleteProcessInstance = deleteProcessInstance.and.returnValue(Promise.reject(fakeError));
service.cancelProcess(null).subscribe(
() => {},
(res) => {
expect(res).toBe(fakeError);
}
);
}));
it('should return a default error if no data is returned by the API', async(() => {
deleteProcessInstance = deleteProcessInstance.and.returnValue(Promise.reject(null));
service.cancelProcess(null).subscribe(
() => {},
(res) => {
expect(res).toBe('Server error');
}
);
}));
});
describe('process definitions', () => {
let getProcessDefinitions: jasmine.Spy;
beforeEach(() => {
getProcessDefinitions = spyOn(alfrescoApi.activiti.processApi, 'getProcessDefinitions')
.and
.returnValue(Promise.resolve({ data: [ fakeProcessDef, fakeProcessDef ] }));
});
it('should return the correct number of process defs', async(() => {
service.getProcessDefinitions().subscribe((defs) => {
expect(defs.length).toBe(2);
});
}));
it('should return the correct process def data', async(() => {
service.getProcessDefinitions().subscribe((defs) => {
expect(defs[0].id).toBe(fakeProcessDef.id);
expect(defs[0].key).toBe(fakeProcessDef.key);
expect(defs[0].name).toBe(fakeProcessDef.name);
});
}));
it('should call API with correct parameters when no appId provided', () => {
service.getProcessDefinitions();
expect(getProcessDefinitions).toHaveBeenCalledWith({
latest: true
});
});
it('should call API with correct parameters when appId provided', () => {
const appId = '1';
service.getProcessDefinitions(appId);
expect(getProcessDefinitions).toHaveBeenCalledWith({
latest: true,
appDefinitionId: appId
});
});
it('should pass on any error that is returned by the API', async(() => {
getProcessDefinitions = getProcessDefinitions.and.returnValue(Promise.reject(fakeError));
service.getProcessDefinitions().subscribe(
() => {},
(res) => {
expect(res).toBe(fakeError);
}
);
}));
it('should return a default error if no data is returned by the API', async(() => {
getProcessDefinitions = getProcessDefinitions.and.returnValue(Promise.reject(null));
service.getProcessDefinitions().subscribe(
() => {},
(res) => {
expect(res).toBe('Server error');
}
);
}));
});
describe('process instance tasks', () => {
const processId = '1001';
let listTasks: jasmine.Spy;
beforeEach(() => {
listTasks = spyOn(alfrescoApi.activiti.taskApi, 'listTasks')
.and
.returnValue(Promise.resolve(fakeTaskList));
});
it('should return the correct number of tasks', async(() => {
service.getProcessTasks(processId).subscribe((tasks) => {
expect(tasks.length).toBe(2);
});
}));
it('should return the correct task data', async(() => {
let fakeTasks = fakeTaskList.data;
service.getProcessTasks(processId).subscribe((tasks) => {
let task = tasks[0];
expect(task.id).toBe(fakeTasks[0].id);
expect(task.name).toBe(fakeTasks[0].name);
expect(task.created).toBe('2016-11-10T00:00:00+00:00');
});
}));
it('should call service to fetch process instance tasks', () => {
service.getProcessTasks(processId);
expect(listTasks).toHaveBeenCalled();
});
it('should call service with processInstanceId parameter', () => {
service.getProcessTasks(processId);
expect(listTasks).toHaveBeenCalledWith({
processInstanceId: processId
});
});
it('should call service with processInstanceId and state parameters', () => {
service.getProcessTasks(processId, 'completed');
expect(listTasks).toHaveBeenCalledWith({
processInstanceId: processId,
state: 'completed'
});
});
it('should pass on any error that is returned by the API', async(() => {
listTasks = listTasks.and.returnValue(Promise.reject(fakeError));
service.getProcessTasks(processId).subscribe(
() => {},
(res) => {
expect(res).toBe(fakeError);
}
);
}));
it('should return a default error if no data is returned by the API', async(() => {
listTasks = listTasks.and.returnValue(Promise.reject(null));
service.getProcessTasks(processId).subscribe(
() => {},
(res) => {
expect(res).toBe('Server error');
}
);
}));
});
describe('comments', () => {
const processId = '1001';
describe('get comments', () => {
let getProcessInstanceComments: jasmine.Spy;
beforeEach(() => {
getProcessInstanceComments = spyOn(alfrescoApi.activiti.commentsApi, 'getProcessInstanceComments')
.and
.returnValue(Promise.resolve({ data: [ fakeComment, fakeComment ] }));
});
it('should return the correct number of comments', async(() => {
service.getProcessInstanceComments(processId).subscribe((tasks) => {
expect(tasks.length).toBe(2);
});
}));
it('should return the correct comment data', async(() => {
service.getProcessInstanceComments(processId).subscribe((comments) => {
let comment = comments[0];
expect(comment.id).toBe(fakeComment.id);
expect(comment.created).toBe(fakeComment.created);
expect(comment.message).toBe(fakeComment.message);
expect(comment.createdBy.id).toBe(fakeComment.createdBy.id);
});
}));
it('should call service to fetch process instance comments', () => {
service.getProcessInstanceComments(processId);
expect(getProcessInstanceComments).toHaveBeenCalledWith(processId);
});
it('should pass on any error that is returned by the API', async(() => {
getProcessInstanceComments = getProcessInstanceComments.and.returnValue(Promise.reject(fakeError));
service.getProcessInstanceComments(processId).subscribe(
() => {},
(res) => {
expect(res).toBe(fakeError);
}
);
}));
it('should return a default error if no data is returned by the API', async(() => {
getProcessInstanceComments = getProcessInstanceComments.and.returnValue(Promise.reject(null));
service.getProcessInstanceComments(processId).subscribe(
() => {},
(res) => {
expect(res).toBe('Server error');
}
);
}));
});
describe('add comment', () => {
const message = 'Test message';
let addProcessInstanceComment: jasmine.Spy;
beforeEach(() => {
addProcessInstanceComment = spyOn(alfrescoApi.activiti.commentsApi, 'addProcessInstanceComment')
.and
.returnValue(Promise.resolve(fakeComment));
});
it('should call service to add comment', () => {
service.addProcessInstanceComment(processId, message);
expect(addProcessInstanceComment).toHaveBeenCalledWith({
message: message
}, processId);
});
it('should return the created comment', async(() => {
service.addProcessInstanceComment(processId, message).subscribe((comment) => {
expect(comment.id).toBe(fakeComment.id);
expect(comment.created).toBe(fakeComment.created);
expect(comment.message).toBe(fakeComment.message);
expect(comment.createdBy).toBe(fakeComment.createdBy);
});
}));
it('should pass on any error that is returned by the API', async(() => {
addProcessInstanceComment = addProcessInstanceComment.and.returnValue(Promise.reject(fakeError));
service.addProcessInstanceComment(processId, message).subscribe(
() => {},
(res) => {
expect(res).toBe(fakeError);
}
);
}));
it('should return a default error if no data is returned by the API', async(() => {
addProcessInstanceComment = addProcessInstanceComment.and.returnValue(Promise.reject(null));
service.addProcessInstanceComment(processId, message).subscribe(
() => {},
(res) => {
expect(res).toBe('Server error');
}
);
}));
});
});
describe('deployed apps', () => {
let getAppDefinitions: jasmine.Spy;
beforeEach(() => {
getAppDefinitions = spyOn(alfrescoApi.activiti.appsApi, 'getAppDefinitions')
.and
.returnValue(Promise.resolve({ data: [ fakeApp1, fakeApp2 ] }));
});
it('should return the correct app', async(() => {
service.getDeployedApplications(fakeApp1.name).subscribe((app) => {
expect(app.id).toBe(fakeApp1.id);
expect(app.name).toBe(fakeApp1.name);
expect(app.deploymentId).toBe(fakeApp1.deploymentId);
});
}));
it('should call service to fetch apps', () => {
service.getDeployedApplications(null);
expect(getAppDefinitions).toHaveBeenCalled();
});
it('should pass on any error that is returned by the API', async(() => {
getAppDefinitions = getAppDefinitions.and.returnValue(Promise.reject(fakeError));
service.getDeployedApplications(null).subscribe(
() => {},
(res) => {
expect(res).toBe(fakeError);
}
);
}));
it('should return a default error if no data is returned by the API', async(() => {
getAppDefinitions = getAppDefinitions.and.returnValue(Promise.reject(null));
service.getDeployedApplications(null).subscribe(
() => {},
(res) => {
expect(res).toBe('Server error');
}
);
}));
expect(true).toBe(true);
done();
});
describe('filters', () => {
let userFiltersApi = fakeApi.activiti.userFiltersApi;
let getFilters: any, createFilter: any;
let getFilters: jasmine.Spy;
let createFilter: jasmine.Spy;
beforeEach(() => {
getFilters = spyOn(userFiltersApi, 'getUserProcessInstanceFilters');
createFilter = spyOn(userFiltersApi, 'createUserProcessInstanceFilter');
getFilters = spyOn(alfrescoApi.activiti.userFiltersApi, 'getUserProcessInstanceFilters')
.and
.returnValue(Promise.resolve(fakeFilters));
createFilter = spyOn(alfrescoApi.activiti.userFiltersApi, 'createUserProcessInstanceFilter')
.and
.callFake((filter: FilterRepresentationModel) => Promise.resolve(filter));
});
it('should call the API without an appId defined by default', () => {
getFilters = getFilters.and.returnValue(Promise.resolve(fakeFilters));
service.getProcessFilters(null);
expect(getFilters).toHaveBeenCalledWith({});
describe('get filters', () => {
it('should call the API without an appId defined by default', () => {
service.getProcessFilters(null);
expect(getFilters).toHaveBeenCalledWith({});
});
it('should call the API with the correct appId when specified', () => {
service.getProcessFilters(226);
expect(getFilters).toHaveBeenCalledWith({appId: 226});
});
it('should return the non-empty filter list that is returned by the API', async(() => {
service.getProcessFilters(null).subscribe(
(res) => {
expect(res.length).toBe(1);
}
);
}));
it('should return the default filters when none are returned by the API', async(() => {
getFilters = getFilters.and.returnValue(Promise.resolve(fakeEmptyFilters));
service.getProcessFilters(null).subscribe(
(res) => {
expect(res.length).toBe(3);
}
);
}));
it('should create the default filters when none are returned by the API', async(() => {
getFilters = getFilters.and.returnValue(Promise.resolve(fakeEmptyFilters));
createFilter = createFilter.and.returnValue(Promise.resolve({}));
service.getProcessFilters(null).subscribe(
() => {
expect(createFilter).toHaveBeenCalledTimes(3);
}
);
}));
it('should pass on any error that is returned by the API', async(() => {
getFilters = getFilters.and.returnValue(Promise.reject(fakeError));
service.getProcessFilters(null).subscribe(
() => {},
(res) => {
expect(res).toBe(fakeError);
}
);
}));
});
it('should call the API with the correct appId when specified', () => {
getFilters = getFilters.and.returnValue(Promise.resolve(fakeFilters));
service.getProcessFilters('226');
expect(getFilters).toHaveBeenCalledWith({appId: '226'});
});
describe('add filter', () => {
it('should return the non-empty filter list that is returned by the API', (done) => {
getFilters = getFilters.and.returnValue(Promise.resolve(fakeFilters));
service.getProcessFilters(null).subscribe(
(res) => {
expect(res.length).toBe(1);
done();
}
);
});
let filter = fakeFilters.data[0];
it('should return the default filters when none are returned by the API', (done) => {
getFilters = getFilters.and.returnValue(Promise.resolve(fakeEmptyFilters));
it('should call the API to create the filter', () => {
service.addFilter(filter);
expect(createFilter).toHaveBeenCalledWith(filter);
});
service.getProcessFilters(null).subscribe(
(res) => {
expect(res.length).toBe(3);
done();
}
);
});
it('should return the created filter', async(() => {
service.addFilter(filter).subscribe((createdFilter: FilterRepresentationModel) => {
expect(createdFilter).toBe(filter);
});
}));
it('should create the default filters when none are returned by the API', (done) => {
getFilters = getFilters.and.returnValue(Promise.resolve(fakeEmptyFilters));
createFilter = createFilter.and.returnValue(Promise.resolve({}));
it('should pass on any error that is returned by the API', async(() => {
createFilter = createFilter.and.returnValue(Promise.reject(fakeError));
service.getProcessFilters(null).subscribe(
(res) => {
expect(createFilter).toHaveBeenCalledTimes(3);
done();
}
);
});
service.addFilter(filter).subscribe(
() => {},
(res) => {
expect(res).toBe(fakeError);
}
);
}));
it('should pass on any error that is returned by the API', (done) => {
getFilters = getFilters.and.returnValue(Promise.reject(fakeError));
it('should return a default error if no data is returned by the API', async(() => {
createFilter = createFilter.and.returnValue(Promise.reject(null));
service.addFilter(filter).subscribe(
() => {},
(res) => {
expect(res).toBe('Server error');
}
);
}));
service.getProcessFilters(null).subscribe(
() => {},
(res) => {
expect(res).toBe(fakeError);
done();
}
);
});
});
});

View File

@@ -16,12 +16,17 @@
*/
import { AlfrescoAuthenticationService } from 'ng2-alfresco-core';
import { ProcessInstance } from '../models/process-instance';
import { User, Comment, FilterRepresentationModel, TaskQueryRequestRepresentationModel } from 'ng2-activiti-tasklist';
import { ProcessInstance, ProcessDefinitionRepresentation } from '../models/index';
import { ProcessFilterRequestRepresentation } from '../models/process-instance-filter.model';
import {
AppDefinitionRepresentationModel,
Comment,
FilterRepresentationModel,
TaskDetailsModel,
User
} from 'ng2-activiti-tasklist';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
declare var moment: any;
@@ -32,30 +37,27 @@ export class ActivitiProcessService {
}
/**
* Retrive all the Deployed app
* Retrieve all deployed apps
* @returns {Observable<any>}
*/
getDeployedApplications(name: string): Observable<any> {
getDeployedApplications(name: string): Observable<AppDefinitionRepresentationModel> {
return Observable.fromPromise(this.authService.getAlfrescoApi().activiti.appsApi.getAppDefinitions())
.map((response: any) => response.data.find(p => p.name === name))
.do(data => console.log('Application: ' + JSON.stringify(data)));
}
getProcesses(): Observable<ProcessInstance[]> {
let request = {'page': 0, 'sort': 'created-desc', 'state': 'all'};
return Observable.fromPromise(this.authService.getAlfrescoApi().activiti.processApi.getProcessInstances(request))
.map(this.extractData)
.map((response: any) => response.data.find((p: AppDefinitionRepresentationModel) => p.name === name))
.catch(this.handleError);
}
getProcessInstances(requestNode: TaskQueryRequestRepresentationModel): Observable<ProcessInstance[]> {
getProcessInstances(requestNode?: ProcessFilterRequestRepresentation): Observable<ProcessInstance[]> {
requestNode = requestNode || new ProcessFilterRequestRepresentation({
page: 0,
sort: 'created-desc',
state: 'all'
});
return Observable.fromPromise(this.authService.getAlfrescoApi().activiti.processApi.getProcessInstances(requestNode))
.map(this.extractData)
.catch(this.handleError);
}
getProcessFilters(appId: string): Observable<any[]> {
getProcessFilters(appId: number): Observable<FilterRepresentationModel[]> {
let filterOpts = appId ? {
appId: appId
} : {};
@@ -79,7 +81,7 @@ export class ActivitiProcessService {
* @param appId
* @returns {FilterRepresentationModel[]}
*/
private createDefaultFilters(appId: string): FilterRepresentationModel[] {
private createDefaultFilters(appId: number): FilterRepresentationModel[] {
let filters: FilterRepresentationModel[] = [];
let involvedTasksFilter = this.getRunningFilterInstance(appId);
@@ -102,7 +104,7 @@ export class ActivitiProcessService {
* @param appId
* @returns {FilterRepresentationModel}
*/
private getRunningFilterInstance(appId: string): FilterRepresentationModel {
private getRunningFilterInstance(appId: number): FilterRepresentationModel {
return new FilterRepresentationModel({
'name': 'Running',
'appId': appId,
@@ -117,7 +119,7 @@ export class ActivitiProcessService {
* @param appId
* @returns {FilterRepresentationModel}
*/
private getCompletedFilterInstance(appId: string): FilterRepresentationModel {
private getCompletedFilterInstance(appId: number): FilterRepresentationModel {
return new FilterRepresentationModel({
'name': 'Completed',
'appId': appId,
@@ -132,7 +134,7 @@ export class ActivitiProcessService {
* @param appId
* @returns {FilterRepresentationModel}
*/
private getAllFilterInstance(appId: string): FilterRepresentationModel {
private getAllFilterInstance(appId: number): FilterRepresentationModel {
return new FilterRepresentationModel({
'name': 'All',
'appId': appId,
@@ -149,10 +151,7 @@ export class ActivitiProcessService {
*/
addFilter(filter: FilterRepresentationModel): Observable<FilterRepresentationModel> {
return Observable.fromPromise(this.callApiAddFilter(filter))
.map(res => res)
.map((response: FilterRepresentationModel) => {
return response;
}).catch(this.handleError);
.catch(this.handleError);
}
getProcess(id: string): Observable<ProcessInstance> {
@@ -160,7 +159,7 @@ export class ActivitiProcessService {
.catch(this.handleError);
}
getProcessTasks(id: string, state: string): Observable<any[]> {
getProcessTasks(id: string, state?: string): Observable<TaskDetailsModel[]> {
let taskOpts = state ? {
processInstanceId: id,
state: state
@@ -209,14 +208,13 @@ export class ActivitiProcessService {
return Observable.fromPromise(
this.authService.getAlfrescoApi().activiti.commentsApi.addProcessInstanceComment({message: message}, id)
)
.map(res => res)
.map((response: Comment) => {
return new Comment(response.id, response.message, response.created, response.createdBy);
}).catch(this.handleError);
}
getProcessDefinitions(appId: string) {
getProcessDefinitions(appId?: string): Observable<ProcessDefinitionRepresentation[]> {
let opts = appId ? {
latest: true,
appDefinitionId: appId
@@ -227,10 +225,11 @@ export class ActivitiProcessService {
this.authService.getAlfrescoApi().activiti.processApi.getProcessDefinitions(opts)
)
.map(this.extractData)
.map(processDefs => processDefs.map((pd) => new ProcessDefinitionRepresentation(pd)))
.catch(this.handleError);
}
startProcess(processDefinitionId: string, name: string, startFormValues?: any) {
startProcess(processDefinitionId: string, name: string, startFormValues?: any): Observable<ProcessInstance> {
let startRequest: any = {
name: name,
processDefinitionId: processDefinitionId
@@ -241,10 +240,11 @@ export class ActivitiProcessService {
return Observable.fromPromise(
this.authService.getAlfrescoApi().activiti.processApi.startNewProcessInstance(startRequest)
)
.map((pd) => new ProcessInstance(pd))
.catch(this.handleError);
}
cancelProcess(processInstanceId: string) {
cancelProcess(processInstanceId: string): Observable<void> {
return Observable.fromPromise(
this.authService.getAlfrescoApi().activiti.processApi.deleteProcessInstance(processInstanceId)
)