#572 activiti form model tests and code improvements

- full test coverage for model layer
This commit is contained in:
Denys Vuika
2016-08-16 13:55:50 +01:00
parent 42cfdd093d
commit c55e976f67
5 changed files with 274 additions and 47 deletions

View File

@@ -16,11 +16,13 @@
*/ */
import { it, describe, expect } from '@angular/core/testing'; import { it, describe, expect } from '@angular/core/testing';
import { ActivitiForm } from './activiti-form.component';
describe('ActivitiForm', () => { describe('ActivitiForm', () => {
it('test placeholder', () => { it('test placeholder', () => {
expect(true).toBeTruthy(); let form = new ActivitiForm(null);
expect(form).toBeDefined();
}); });
}); });

View File

@@ -214,7 +214,7 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
.getTaskForm(taskId) .getTaskForm(taskId)
.subscribe( .subscribe(
form => { form => {
this.form = new FormModel(form, data, null, this.readOnly); this.form = new FormModel(form, data, this.readOnly);
this.formLoaded.emit(this.form.values); this.formLoaded.emit(this.form.values);
}, },
err => console.log(err) err => console.log(err)
@@ -227,7 +227,7 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
.subscribe( .subscribe(
form => { form => {
console.log('Get Form By definition Id', form); console.log('Get Form By definition Id', form);
this.form = new FormModel(form, this.data, this.formSaved, this.readOnly); this.form = this.parseForm(form);
this.formLoaded.emit(this.form.values); this.formLoaded.emit(this.form.values);
}, },
err => console.log(err) err => console.log(err)
@@ -242,7 +242,7 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
this.formService.getFormDefinitionById(id).subscribe( this.formService.getFormDefinitionById(id).subscribe(
form => { form => {
console.log('Get Form By Form definition Name', form); console.log('Get Form By Form definition Name', form);
this.form = new FormModel(form, this.data, this.formSaved, this.readOnly); this.form = this.parseForm(form);
this.formLoaded.emit(this.form.values); this.formLoaded.emit(this.form.values);
}, },
err => console.log(err) err => console.log(err)
@@ -273,4 +273,18 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
(err) => console.log(err) (err) => console.log(err)
); );
} }
private parseForm(json: any): FormModel {
let form = new FormModel(json, this.data, this.readOnly);
if (!json.fields) {
form.outcomes = this.getFormDefinitionOutcomes(form);
}
return form;
}
private getFormDefinitionOutcomes(form: FormModel): FormOutcomeModel[] {
return [
new FormOutcomeModel(form, { id: '$custom', name: 'Save', isSystem: true })
];
}
} }

View File

@@ -39,6 +39,7 @@ export class FormOutcomeModel extends FormWidgetModel {
if (json) { if (json) {
this._id = json.id; this._id = json.id;
this._name = json.name; this._name = json.name;
this.isSystem = json.isSystem ? true : false;
} }
} }
} }

View File

@@ -17,6 +17,10 @@
import { it, describe, expect } from '@angular/core/testing'; import { it, describe, expect } from '@angular/core/testing';
import { FormModel } from './form.model'; import { FormModel } from './form.model';
import { TabModel } from './tab.model';
import { ContainerModel } from './container.model';
import { FormOutcomeModel } from './form-outcome.model';
import { FormValues } from './form-values';
describe('FormModel', () => { describe('FormModel', () => {
@@ -55,8 +59,237 @@ describe('FormModel', () => {
}); });
it('should set readonly state from params', () => { it('should set readonly state from params', () => {
let form = new FormModel({}, null, null, true); let form = new FormModel({}, null, true);
expect(form.readOnly).toBeTruthy(); expect(form.readOnly).toBeTruthy();
}); });
it('should check tabs', () => {
let form = new FormModel();
form.tabs = null;
expect(form.hasTabs()).toBeFalsy();
form.tabs = [];
expect(form.hasTabs()).toBeFalsy();
form.tabs = [new TabModel(null)];
expect(form.hasTabs()).toBeTruthy();
});
it('should check fields', () => {
let form = new FormModel();
form.fields = null;
expect(form.hasFields()).toBeFalsy();
form.fields = [];
expect(form.hasFields()).toBeFalsy();
form.fields = [new ContainerModel(null)];
expect(form.hasFields()).toBeTruthy();
});
it('should check outcomes', () => {
let form = new FormModel();
form.outcomes = null;
expect(form.hasOutcomes()).toBeFalsy();
form.outcomes = [];
expect(form.hasOutcomes()).toBeFalsy();
form.outcomes = [new FormOutcomeModel(null)];
expect(form.hasOutcomes()).toBeTruthy();
});
it('should parse tabs', () => {
let json = {
tabs: [
{ id: 'tab1' },
{ id: 'tab2' }
]
};
let form = new FormModel(json);
expect(form.tabs.length).toBe(2);
expect(form.tabs[0].id).toBe('tab1');
expect(form.tabs[1].id).toBe('tab2');
});
it('should parse fields', () => {
let json = {
fields: [
{ id: 'field1' },
{ id: 'field2' }
]
};
let form = new FormModel(json);
expect(form.fields.length).toBe(2);
expect(form.fields[0].id).toBe('field1');
expect(form.fields[1].id).toBe('field2');
});
it('should parse fields from the definition', () => {
let json = {
fields: null,
formDefinition: {
fields: [
{ id: 'field1' },
{ id: 'field2' }
]
}
};
let form = new FormModel(json);
expect(form.fields.length).toBe(2);
expect(form.fields[0].id).toBe('field1');
expect(form.fields[1].id).toBe('field2');
});
it('should convert missing fields to empty collection', () => {
let json = {
fields: null
};
let form = new FormModel(json);
expect(form.fields).toBeDefined();
expect(form.fields.length).toBe(0);
});
it('should put fields into corresponding tabs', () => {
let json = {
tabs: [
{ id: 'tab1' },
{ id: 'tab2' }
],
fields: [
{ id: 'field1', tab: 'tab1' },
{ id: 'field2', tab: 'tab2' },
{ id: 'field3', tab: 'tab1' },
{ id: 'field4', tab: 'missing-tab' }
]
};
let form = new FormModel(json);
expect(form.tabs.length).toBe(2);
expect(form.fields.length).toBe(4);
let tab1 = form.tabs[0];
expect(tab1.fields.length).toBe(2);
expect(tab1.fields[0].id).toBe('field1');
expect(tab1.fields[1].id).toBe('field3');
let tab2 = form.tabs[1];
expect(tab2.fields.length).toBe(1);
expect(tab2.fields[0].id).toBe('field2');
});
it('should apply external data', () => {
let data: FormValues = {
field1: 'one',
field2: 'two'
};
let json = {
fields: [
{
fieldType: 'ContainerRepresentation',
id: 'container1',
type: 'container',
numberOfColumns: 2,
fields: {
'1': [
{
fieldType: 'FormFieldRepresentation',
type: 'text',
id: 'field1'
}
],
'2': [
{
fieldType: 'FormFieldRepresentation',
type: 'text',
id: 'field2'
},
{
fieldType: 'FormFieldRepresentation',
type: 'text',
id: 'field3',
value: 'original-value'
}
]
}
}
]
};
let form = new FormModel(json, data);
expect(form.fields.length).toBe(1);
let container = form.fields[0];
expect(container.columns.length).toBe(2);
let column1 = container.columns[0];
let column2 = container.columns[1];
expect(column1.fields.length).toBe(1);
expect(column2.fields.length).toBe(2);
let field1 = column1.fields[0];
expect(field1.id).toBe('field1');
expect(field1.value).toBe('one');
let field2 = column2.fields[0];
expect(field2.id).toBe('field2');
expect(field2.value).toBe('two');
let field3 = column2.fields[1];
expect(field3.id).toBe('field3');
expect(field3.value).toBe('original-value');
});
it('should create standard form outcomes', () => {
let json = {
fields: [
{ id: 'container1' }
]
};
let form = new FormModel(json);
expect(form.outcomes.length).toBe(2);
expect(form.outcomes[0].id).toBe(FormModel.SAVE_OUTCOME);
expect(form.outcomes[0].isSystem).toBeTruthy();
expect(form.outcomes[1].id).toBe(FormModel.COMPLETE_OUTCOME);
expect(form.outcomes[1].isSystem).toBeTruthy();
});
it('should create outcomes only when fields available', () => {
let json = {
fields: null
};
let form = new FormModel(json);
expect(form.outcomes.length).toBe(0);
});
it('should use custom form outcomes', () => {
let json = {
fields: [
{ id: 'container1' }
],
outcomes: [
{ id: 'custom-1', name: 'custom 1' }
]
};
let form = new FormModel(json);
expect(form.outcomes.length).toBe(2);
expect(form.outcomes[0].id).toBe(FormModel.SAVE_OUTCOME);
expect(form.outcomes[0].isSystem).toBeTruthy();
expect(form.outcomes[1].id).toBe('custom-1');
expect(form.outcomes[1].isSystem).toBeFalsy();
});
}); });

View File

@@ -24,6 +24,8 @@ import { FormOutcomeModel } from './form-outcome.model';
export class FormModel { export class FormModel {
static UNSET_TASK_NAME: string = 'Nameless task'; static UNSET_TASK_NAME: string = 'Nameless task';
static SAVE_OUTCOME: string = '$save';
static COMPLETE_OUTCOME: string = '$complete';
private _id: string; private _id: string;
private _name: string; private _name: string;
@@ -71,7 +73,7 @@ export class FormModel {
return this.outcomes && this.outcomes.length > 0; return this.outcomes && this.outcomes.length > 0;
} }
constructor(json?: any, data?: any, saveOption?: any, readOnly: boolean = false) { constructor(json?: any, data?: FormValues, readOnly: boolean = false) {
this.readOnly = readOnly; this.readOnly = readOnly;
if (json) { if (json) {
this._json = json; this._json = json;
@@ -104,25 +106,15 @@ export class FormModel {
} }
} }
} }
if (this.isATaskForm()) { if (json.fields) {
let saveOutcome = new FormOutcomeModel(this, {id: '$save', name: 'Save'}); let saveOutcome = new FormOutcomeModel(this, { id: FormModel.SAVE_OUTCOME, name: 'Save', isSystem: true });
saveOutcome.isSystem = true; let completeOutcome = new FormOutcomeModel(this, {id: FormModel.COMPLETE_OUTCOME, name: 'Complete', isSystem: true });
let completeOutcome = new FormOutcomeModel(this, {id: '$complete', name: 'Complete'});
completeOutcome.isSystem = true;
let customOutcomes = (json.outcomes || []).map(obj => new FormOutcomeModel(this, obj)); let customOutcomes = (json.outcomes || []).map(obj => new FormOutcomeModel(this, obj));
this.outcomes = [saveOutcome].concat( this.outcomes = [saveOutcome].concat(
customOutcomes.length > 0 ? customOutcomes : [completeOutcome] customOutcomes.length > 0 ? customOutcomes : [completeOutcome]
); );
} else {
if (saveOption && saveOption.observers.length > 0) {
let saveOutcome = new FormOutcomeModel(this, {id: '$custom', name: 'Save'});
saveOutcome.isSystem = true;
this.outcomes = [saveOutcome];
}
} }
} }
} }
@@ -130,12 +122,10 @@ export class FormModel {
private parseContainerFields(json: any): ContainerModel[] { private parseContainerFields(json: any): ContainerModel[] {
let fields = []; let fields = [];
if (json) { if (json.fields) {
if (json.fields) { fields = json.fields;
fields = json.fields; } else if (json.formDefinition && json.formDefinition.fields) {
} else if (json.formDefinition && json.formDefinition.fields) { fields = json.formDefinition.fields;
fields = json.formDefinition.fields;
}
} }
return fields.map(obj => new ContainerModel(this, obj)); return fields.map(obj => new ContainerModel(this, obj));
@@ -143,32 +133,19 @@ export class FormModel {
// Loads external data and overrides field values // Loads external data and overrides field values
// Typically used when form definition and form data coming from different sources // Typically used when form definition and form data coming from different sources
private loadData(data: any) { private loadData(data: FormValues) {
for (let i = 0; i < this.fields.length; i++) { for (let i = 0; i < this.fields.length; i++) {
let containerModel = this.fields[i]; let container = this.fields[i];
if (containerModel) { for (let i = 0; i < container.columns.length; i++) {
for (let i = 0; i < containerModel.columns.length; i++) { let column = container.columns[i];
let containerModelColumn = containerModel.columns[i]; for (let i = 0; i < column.fields.length; i++) {
if (containerModelColumn) { let field = column.fields[i];
for (let i = 0; i < containerModelColumn.fields.length; i++) { if (data[field.id]) {
let formField = containerModelColumn.fields[i]; field.json.value = data[field.id];
if (data[formField.id]) { field.value = data[field.id];
formField.value = data[formField.id];
formField.json.value = data[formField.id];
}
}
} }
} }
} }
} }
} }
/**
* Check if the form is associated to a task or if is only the form definition
* @returns {boolean}
*/
private isATaskForm(): boolean {
return this._json.fields ? true : false;
}
} }