Merge pull request #855 from Alfresco/dev-valbano-545

Add fix for tests and visibility
This commit is contained in:
Maurizio Vitale 2016-10-06 09:57:23 +01:00 committed by GitHub
commit d20a750816
7 changed files with 501 additions and 453 deletions

View File

@ -10,7 +10,7 @@
</div> </div>
<div class="mdl-card__media"> <div class="mdl-card__media">
<div *ngIf="form.hasTabs()"> <div *ngIf="form.hasTabs()">
<tabs-widget [tabs]="form.tabs"></tabs-widget> <tabs-widget [tabs]="form.tabs" (formTabChanged)="checkVisibility($event);"></tabs-widget>
</div> </div>
<div *ngIf="!form.hasTabs() && form.hasFields()"> <div *ngIf="!form.hasTabs() && form.hasFields()">

View File

@ -31,6 +31,7 @@ describe('TabModel', () => {
let model = new TabModel(null, json); let model = new TabModel(null, json);
expect(model.id).toBe(json.id); expect(model.id).toBe(json.id);
expect(model.title).toBe(json.title); expect(model.title).toBe(json.title);
expect(model.isVisible).toBe(true);
expect(model.visibilityCondition).toBe(json.visibilityCondition); expect(model.visibilityCondition).toBe(json.visibilityCondition);
}); });
@ -38,6 +39,8 @@ describe('TabModel', () => {
let model = new TabModel(null, null); let model = new TabModel(null, null);
expect(model.id).toBeUndefined(); expect(model.id).toBeUndefined();
expect(model.title).toBeUndefined(); expect(model.title).toBeUndefined();
expect(model.isVisible).toBeDefined();
expect(model.isVisible).toBe(true);
expect(model.visibilityCondition).toBeUndefined(); expect(model.visibilityCondition).toBeUndefined();
}); });

View File

@ -23,6 +23,7 @@ export class TabModel extends FormWidgetModel {
id: string; id: string;
title: string; title: string;
isVisible: boolean = true;
visibilityCondition: any; visibilityCondition: any;
fields: ContainerModel[] = []; fields: ContainerModel[] = [];

View File

@ -13,8 +13,9 @@
[attr.id]="tab.id"> [attr.id]="tab.id">
<container-widget <container-widget
*ngFor="let field of tab.fields" *ngFor="let field of tab.fields"
[content]="field"> [content]="field" (formValueChanged)="tabChanged($event);">
</container-widget> </container-widget>
</div> </div>
</div> </div>
</div> </div>
-

View File

@ -15,8 +15,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { Component, Input, AfterViewInit } from '@angular/core'; import { Component, Input, AfterViewInit, EventEmitter, Output } from '@angular/core';
import { TabModel } from './../core/index'; import { TabModel, FormFieldModel } from './../core/index';
declare let __moduleName: string; declare let __moduleName: string;
declare var componentHandler; declare var componentHandler;
@ -31,6 +31,9 @@ export class TabsWidget implements AfterViewInit {
@Input() @Input()
tabs: TabModel[] = []; tabs: TabModel[] = [];
@Output()
formTabChanged: EventEmitter<FormFieldModel> = new EventEmitter<FormFieldModel>();
hasTabs() { hasTabs() {
return this.tabs && this.tabs.length > 0; return this.tabs && this.tabs.length > 0;
} }
@ -47,4 +50,9 @@ export class TabsWidget implements AfterViewInit {
} }
return false; return false;
} }
tabChanged( field: FormFieldModel ) {
this.formTabChanged.emit(field);
}
} }

View File

@ -15,28 +15,39 @@
* limitations under the License. * limitations under the License.
*/ */
/*
import { it, describe, inject, beforeEach, beforeEachProviders } from '@angular/core/testing'; import {
async, inject, TestBed
} from '@angular/core/testing';
import {
MockBackend,
MockConnection
} from '@angular/http/testing';
import {
HttpModule,
Http,
XHRBackend,
Response,
ResponseOptions
} from '@angular/http';
import { WidgetVisibilityService } from './widget-visibility.service'; import { WidgetVisibilityService } from './widget-visibility.service';
import { AlfrescoSettingsService, AlfrescoAuthenticationService } from 'ng2-alfresco-core'; import { AlfrescoSettingsService } from 'ng2-alfresco-core';
import { HTTP_PROVIDERS } from '@angular/http';
import { WidgetVisibilityModel } from '../models/widget-visibility.model';
import { TaskProcessVariableModel } from '../models/task-process-variable.model'; import { TaskProcessVariableModel } from '../models/task-process-variable.model';
import { WidgetVisibilityModel } from '../models/widget-visibility.model';
import { FormModel, FormValues, FormFieldModel } from '../components/widgets/core/index'; import { FormModel, FormValues, FormFieldModel } from '../components/widgets/core/index';
declare let AlfrescoApi: any;
declare let jasmine: any;
describe('WidgetVisibilityService', () => { //////// Tests /////////////
let service; describe('WidgetVisibilityService (mockBackend)', () => {
let formTest = new FormModel({}); let formTest = new FormModel({});
let formValues: FormValues = { 'test_1': 'value_1', 'test_2': 'value_2', 'test_3': 'value_1' };
let fakeTaskProcessVariableModels = [ let fakeTaskProcessVariableModels = [
{id: 'TEST_VAR_1', type: 'string', value: 'test_value_1'}, {id: 'TEST_VAR_1', type: 'string', value: 'test_value_1'},
{id: 'TEST_VAR_2', type: 'string', value: 'test_value_2'}, {id: 'TEST_VAR_2', type: 'string', value: 'test_value_2'},
{id: 'TEST_VAR_3', type: 'string', value: 'test_value_3'} {id: 'TEST_VAR_3', type: 'string', value: 'test_value_3'}
]; ];
let formValues: FormValues = { 'test_1': 'value_1', 'test_2': 'value_2', 'test_3': 'value_1' };
let fakeFormJson = { let fakeFormJson = {
id: '9999', id: '9999',
name: 'FORM_VISIBILITY', name: 'FORM_VISIBILITY',
@ -87,44 +98,46 @@ describe('WidgetVisibilityService', () => {
] ]
}; };
beforeEachProviders(() => { beforeEach( async(() => {
return [ TestBed.configureTestingModule({
HTTP_PROVIDERS, imports: [ HttpModule ],
providers: [
WidgetVisibilityService,
AlfrescoSettingsService, AlfrescoSettingsService,
AlfrescoAuthenticationService, { provide: XHRBackend, useClass: MockBackend }
WidgetVisibilityService ]
];
});
beforeEach(
inject([WidgetVisibilityService], (activitiService: WidgetVisibilityService) => {
jasmine.Ajax.install();
service = activitiService;
}) })
); .compileComponents();
}));
afterEach(() => { it('can instantiate service when inject service',
jasmine.Ajax.uninstall(); inject([WidgetVisibilityService], (service: WidgetVisibilityService) => {
}); expect(service instanceof WidgetVisibilityService).toBe(true);
}));
it('should return the process variables for task', (done) => { it('can instantiate service with "new"', inject([Http], (http: Http) => {
service.getTaskProcessVariableModelsForTask(9999).subscribe( expect(http).not.toBeNull('http should be provided');
(res: TaskProcessVariableModel[]) => { let service = new WidgetVisibilityService(http, null);
expect(res).toBeDefined(); expect(service instanceof WidgetVisibilityService).toBe(true, 'new service should be ok');
expect(res.length).toEqual(3); }));
expect(res[0].id).toEqual('TEST_VAR_1');
expect(res[0].type).toEqual('string');
expect(res[0].value).toEqual('test_value_1');
done();
}
);
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200, it('can provide the mockBackend as XHRBackend',
contentType: 'application/json', inject([XHRBackend], (backend: MockBackend) => {
responseText: JSON.stringify(fakeTaskProcessVariableModels) expect(backend).not.toBeNull('backend should be provided');
}); }));
});
describe('when service is ready', () => {
let backend: MockBackend;
let service: WidgetVisibilityService;
beforeEach(inject([Http, XHRBackend, AlfrescoSettingsService],
(http: Http,
be: MockBackend,
setting: AlfrescoSettingsService) => {
backend = be;
service = new WidgetVisibilityService(http, setting);
}));
it('should evaluate logic operation for two values', () => { it('should evaluate logic operation for two values', () => {
let res: boolean; let res: boolean;
@ -137,11 +150,11 @@ describe('WidgetVisibilityService', () => {
expect(res).toBeTruthy(); expect(res).toBeTruthy();
res = service.evaluateLogicalOperation( 'and not', true, false); res = service.evaluateLogicalOperation( 'and-not', true, false);
expect(res).toBeTruthy(); expect(res).toBeTruthy();
res = service.evaluateLogicalOperation( 'or not', true, true ); res = service.evaluateLogicalOperation( 'or-not', true, true );
expect(res).toBeTruthy(); expect(res).toBeTruthy();
@ -153,11 +166,11 @@ describe('WidgetVisibilityService', () => {
expect(res).toBeFalsy(); expect(res).toBeFalsy();
res = service.evaluateLogicalOperation( 'and not', false, false ); res = service.evaluateLogicalOperation( 'and-not', false, false );
expect(res).toBeFalsy(); expect(res).toBeFalsy();
res = service.evaluateLogicalOperation( 'or not', false, true ); res = service.evaluateLogicalOperation( 'or-not', false, true );
expect(res).toBeFalsy(); expect(res).toBeFalsy();
}); });
@ -206,9 +219,32 @@ describe('WidgetVisibilityService', () => {
expect(res).toBeFalsy(); expect(res).toBeFalsy();
}); });
it('should return the process variables for task', (done) => {
let options = new ResponseOptions({status: 200,
body: fakeTaskProcessVariableModels });
let response = new Response(options);
backend.connections.subscribe((c: MockConnection) => c.mockRespond(response));
service.getTaskProcessVariableModelsForTask('9999').subscribe(
(res: TaskProcessVariableModel[]) => {
expect(res).toBeDefined();
expect(res.length).toEqual(3);
expect(res[0].id).toEqual('TEST_VAR_1');
expect(res[0].type).toEqual('string');
expect(res[0].value).toEqual('test_value_1');
done();
}
);
});
it('should be able to retrieve the value of a process variable', (done) => { it('should be able to retrieve the value of a process variable', (done) => {
service.getTaskProcessVariableModelsForTask(9999).subscribe( let options = new ResponseOptions({status: 200,
body: fakeTaskProcessVariableModels });
let response = new Response(options);
backend.connections.subscribe((c: MockConnection) => c.mockRespond(response));
service.getTaskProcessVariableModelsForTask('9999').subscribe(
(res: TaskProcessVariableModel[]) => { (res: TaskProcessVariableModel[]) => {
expect(res).toBeDefined(); expect(res).toBeDefined();
let varValue = service.getValueFromVariable(formTest, 'TEST_VAR_1', res); let varValue = service.getValueFromVariable(formTest, 'TEST_VAR_1', res);
@ -217,11 +253,6 @@ describe('WidgetVisibilityService', () => {
done(); done();
} }
); );
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200,
contentType: 'application/json',
responseText: JSON.stringify(fakeTaskProcessVariableModels)
});
}); });
it('should be able to retrieve the value of a form variable', () => { it('should be able to retrieve the value of a form variable', () => {
@ -236,25 +267,21 @@ describe('WidgetVisibilityService', () => {
expect(varValue).toBe('form_value_test'); expect(varValue).toBe('form_value_test');
}); });
it('should return undefined if the variable does not exist', (done) => { it('should return undefined if the variable does not exist', (done) => {
service.getTaskProcessVariableModelsForTask(9999).subscribe( let options = new ResponseOptions({status: 200,
body: fakeTaskProcessVariableModels });
let response = new Response(options);
backend.connections.subscribe((c: MockConnection) => c.mockRespond(response));
service.getTaskProcessVariableModelsForTask('9999').subscribe(
(res: TaskProcessVariableModel[]) => { (res: TaskProcessVariableModel[]) => {
let varValue = service.getValueFromVariable(formTest, 'TEST_MYSTERY_VAR', res); let varValue = service.getValueFromVariable(formTest, 'TEST_MYSTERY_VAR', res);
expect(varValue).toBeUndefined(); expect(varValue).toBeUndefined();
done(); done();
} }
); );
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200,
contentType: 'application/json',
responseText: JSON.stringify(fakeTaskProcessVariableModels)
}); });
});
it('should be able to retrieve a field value searching in the form', () => { it('should be able to retrieve a field value searching in the form', () => {
let stubFormWithFields = new FormModel(fakeFormJson); let stubFormWithFields = new FormModel(fakeFormJson);
let formValue = service.getFormValueByName(stubFormWithFields, 'FIELD_WITH_CONDITION'); let formValue = service.getFormValueByName(stubFormWithFields, 'FIELD_WITH_CONDITION');
@ -309,7 +336,12 @@ describe('WidgetVisibilityService', () => {
}); });
it('should retrieve the value for the right field when it is a process variable', (done) => { it('should retrieve the value for the right field when it is a process variable', (done) => {
service.getTaskProcessVariableModelsForTask(9999).subscribe( let options = new ResponseOptions({status: 200,
body: fakeTaskProcessVariableModels });
let response = new Response(options);
backend.connections.subscribe((c: MockConnection) => c.mockRespond(response));
service.getTaskProcessVariableModelsForTask('9999').subscribe(
(res: TaskProcessVariableModel[]) => { (res: TaskProcessVariableModel[]) => {
let visibilityObjTest = new WidgetVisibilityModel(); let visibilityObjTest = new WidgetVisibilityModel();
visibilityObjTest.rightRestResponseId = 'TEST_VAR_2'; visibilityObjTest.rightRestResponseId = 'TEST_VAR_2';
@ -321,11 +353,6 @@ describe('WidgetVisibilityService', () => {
done(); done();
} }
); );
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200,
contentType: 'application/json',
responseText: JSON.stringify(fakeTaskProcessVariableModels)
});
}); });
it('should retrieve the value for the right field when it is a form variable', () => { it('should retrieve the value for the right field when it is a form variable', () => {
@ -363,7 +390,12 @@ describe('WidgetVisibilityService', () => {
}); });
it('should retrieve the value for the left field when it is a process variable', (done) => { it('should retrieve the value for the left field when it is a process variable', (done) => {
service.getTaskProcessVariableModelsForTask(9999).subscribe( let options = new ResponseOptions({status: 200,
body: fakeTaskProcessVariableModels });
let response = new Response(options);
backend.connections.subscribe((c: MockConnection) => c.mockRespond(response));
service.getTaskProcessVariableModelsForTask('9999').subscribe(
(res: TaskProcessVariableModel[]) => { (res: TaskProcessVariableModel[]) => {
let visibilityObjTest = new WidgetVisibilityModel(); let visibilityObjTest = new WidgetVisibilityModel();
visibilityObjTest.leftRestResponseId = 'TEST_VAR_2'; visibilityObjTest.leftRestResponseId = 'TEST_VAR_2';
@ -375,11 +407,6 @@ describe('WidgetVisibilityService', () => {
done(); done();
} }
); );
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200,
contentType: 'application/json',
responseText: JSON.stringify(fakeTaskProcessVariableModels)
});
}); });
it('should retrieve the value for the left field when it is a form variable', () => { it('should retrieve the value for the left field when it is a form variable', () => {
@ -465,7 +492,12 @@ describe('WidgetVisibilityService', () => {
}); });
it('should evaluate the visibility for the field between form value and process var', (done) => { it('should evaluate the visibility for the field between form value and process var', (done) => {
service.getTaskProcessVariableModelsForTask(9999).subscribe( let options = new ResponseOptions({status: 200,
body: fakeTaskProcessVariableModels });
let response = new Response(options);
backend.connections.subscribe((c: MockConnection) => c.mockRespond(response));
service.getTaskProcessVariableModelsForTask('9999').subscribe(
(res: TaskProcessVariableModel[]) => { (res: TaskProcessVariableModel[]) => {
let fakeFormWithField = new FormModel(fakeFormJson); let fakeFormWithField = new FormModel(fakeFormJson);
let visibilityObjTest = new WidgetVisibilityModel(); let visibilityObjTest = new WidgetVisibilityModel();
@ -479,16 +511,15 @@ describe('WidgetVisibilityService', () => {
done(); done();
} }
); );
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200,
contentType: 'application/json',
responseText: JSON.stringify(fakeTaskProcessVariableModels)
}); });
});
it('should evaluate visibility with multiple conditions', (done) => { it('should evaluate visibility with multiple conditions', (done) => {
service.getTaskProcessVariableModelsForTask(9999).subscribe( let options = new ResponseOptions({status: 200,
body: fakeTaskProcessVariableModels });
let response = new Response(options);
backend.connections.subscribe((c: MockConnection) => c.mockRespond(response));
service.getTaskProcessVariableModelsForTask('9999').subscribe(
(res: TaskProcessVariableModel[]) => { (res: TaskProcessVariableModel[]) => {
let fakeFormWithField = new FormModel(fakeFormJson); let fakeFormWithField = new FormModel(fakeFormJson);
let visibilityObjTest = new WidgetVisibilityModel(); let visibilityObjTest = new WidgetVisibilityModel();
@ -507,11 +538,6 @@ describe('WidgetVisibilityService', () => {
done(); done();
} }
); );
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200,
contentType: 'application/json',
responseText: JSON.stringify(fakeTaskProcessVariableModels)
});
}); });
it('should return true when the visibility condition is not valid', () => { it('should return true when the visibility condition is not valid', () => {
@ -552,4 +578,4 @@ describe('WidgetVisibilityService', () => {
expect(fakeFormField.isVisible).toBeFalsy(); expect(fakeFormField.isVisible).toBeFalsy();
}); });
}); });
*/ });

View File

@ -19,7 +19,7 @@ import { Injectable } from '@angular/core';
import { Response, Http, Headers, RequestOptions } from '@angular/http'; import { Response, Http, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Rx'; import { Observable } from 'rxjs/Rx';
import { AlfrescoSettingsService } from 'ng2-alfresco-core'; import { AlfrescoSettingsService } from 'ng2-alfresco-core';
import { FormModel, FormFieldModel } from '../components/widgets/core/index'; import { FormModel, FormFieldModel, TabModel } from '../components/widgets/core/index';
import { WidgetVisibilityModel } from '../models/widget-visibility.model'; import { WidgetVisibilityModel } from '../models/widget-visibility.model';
import { TaskProcessVariableModel } from '../models/task-process-variable.model'; import { TaskProcessVariableModel } from '../models/task-process-variable.model';
@ -33,6 +33,9 @@ export class WidgetVisibilityService {
} }
public updateVisibilityForForm(form: FormModel) { public updateVisibilityForForm(form: FormModel) {
if ( form && form.tabs && form.tabs.length > 0) {
form.tabs.map( tabModel => this.refreshVisibilityForTab(tabModel) );
}
if ( form && form.fields.length > 0 ) { if ( form && form.fields.length > 0 ) {
form.fields form.fields
.map( .map(
@ -55,16 +58,22 @@ export class WidgetVisibilityService {
} }
} }
public refreshVisibilityForTab(tab: TabModel) {
if ( tab.visibilityCondition ) {
tab.isVisible = this.getVisiblityForField(tab.form, tab.visibilityCondition);
}
}
public getVisiblityForField(form: FormModel, visibilityObj: WidgetVisibilityModel): boolean { public getVisiblityForField(form: FormModel, visibilityObj: WidgetVisibilityModel): boolean {
let isLeftFieldPresent = visibilityObj.leftFormFieldId || visibilityObj.leftRestResponseId; let isLeftFieldPresent = visibilityObj.leftFormFieldId || visibilityObj.leftRestResponseId;
if ( !isLeftFieldPresent ) { if ( !isLeftFieldPresent || isLeftFieldPresent === 'null' ) {
return true; return true;
}else { }else {
return this.evaluateVisibilityForField(form, visibilityObj); return this.evaluateVisibilityForField(form, visibilityObj);
} }
} }
private evaluateVisibilityForField(form: FormModel, visibilityObj: WidgetVisibilityModel): boolean { evaluateVisibilityForField(form: FormModel, visibilityObj: WidgetVisibilityModel): boolean {
let leftValue = this.getLeftValue(form, visibilityObj); let leftValue = this.getLeftValue(form, visibilityObj);
let rightValue = this.getRightValue(form, visibilityObj); let rightValue = this.getRightValue(form, visibilityObj);
let actualResult = this.evaluateCondition(leftValue, rightValue, visibilityObj.operator); let actualResult = this.evaluateCondition(leftValue, rightValue, visibilityObj.operator);
@ -79,14 +88,14 @@ export class WidgetVisibilityService {
} }
} }
private getLeftValue(form: FormModel, visibilityObj: WidgetVisibilityModel) { getLeftValue(form: FormModel, visibilityObj: WidgetVisibilityModel) {
if ( visibilityObj.leftRestResponseId ) { if ( visibilityObj.leftRestResponseId ) {
return this.getValueFromVariable(form, visibilityObj.leftRestResponseId, this.processVarList); return this.getValueFromVariable(form, visibilityObj.leftRestResponseId, this.processVarList);
} }
return this.getValueOField(form, visibilityObj.leftFormFieldId); return this.getValueOField(form, visibilityObj.leftFormFieldId);
} }
private getRightValue(form: FormModel, visibilityObj: WidgetVisibilityModel) { getRightValue(form: FormModel, visibilityObj: WidgetVisibilityModel) {
let valueFound = null; let valueFound = null;
if ( visibilityObj.rightRestResponseId ) { if ( visibilityObj.rightRestResponseId ) {
valueFound = this.getValueFromVariable(form, visibilityObj.rightRestResponseId, this.processVarList); valueFound = this.getValueFromVariable(form, visibilityObj.rightRestResponseId, this.processVarList);
@ -98,14 +107,14 @@ export class WidgetVisibilityService {
return valueFound; return valueFound;
} }
private getValueOField(form: FormModel, field: string) { getValueOField(form: FormModel, field: string) {
let value = form.values[field] ? let value = form.values[field] ?
form.values[field] : form.values[field] :
this.getFormValueByName(form, field); this.getFormValueByName(form, field);
return value; return value;
} }
private getFormValueByName(form: FormModel, name: string) { getFormValueByName(form: FormModel, name: string) {
for (let columns of form.json.fields) { for (let columns of form.json.fields) {
for ( let i in columns.fields ) { for ( let i in columns.fields ) {
if ( columns.fields.hasOwnProperty( i ) ) { if ( columns.fields.hasOwnProperty( i ) ) {
@ -118,7 +127,7 @@ export class WidgetVisibilityService {
} }
} }
private getValueFromVariable( form: FormModel, name: string, processVarList: TaskProcessVariableModel[] ) { getValueFromVariable( form: FormModel, name: string, processVarList: TaskProcessVariableModel[] ) {
return this.getFormVariableValue(form, name) || return this.getFormVariableValue(form, name) ||
this.getProcessVariableValue(name, processVarList); this.getProcessVariableValue(name, processVarList);
} }
@ -141,30 +150,30 @@ export class WidgetVisibilityService {
} }
} }
private evaluateLogicalOperation(logicOp, previousValue, newValue): boolean { evaluateLogicalOperation(logicOp, previousValue, newValue): boolean {
switch ( logicOp ) { switch ( logicOp ) {
case 'and': case 'and':
return previousValue && newValue; return previousValue && newValue;
case 'or' : case 'or' :
return previousValue || newValue; return previousValue || newValue;
case 'and not': case 'and-not':
return previousValue && !newValue; return previousValue && !newValue;
case 'or not': case 'or-not':
return previousValue || !newValue; return previousValue || !newValue;
default: default:
console.error( 'NO valid operation!' ); console.error( 'NO valid operation! wrong op request : ' + logicOp );
break; break;
} }
} }
private evaluateCondition(leftValue, rightValue, operator): boolean { evaluateCondition(leftValue, rightValue, operator): boolean {
switch ( operator ) { switch ( operator ) {
case '==': case '==':
return leftValue + '' === rightValue; return String(leftValue) === String(rightValue);
case '<': case '<':
return leftValue < rightValue; return leftValue < rightValue;
case '!=': case '!=':
return leftValue + '' !== rightValue; return String(leftValue) !== String(rightValue);
case '>': case '>':
return leftValue > rightValue; return leftValue > rightValue;
case '>=': case '>=':