diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts index 63233e2fac..e9bcf64082 100644 --- a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts @@ -17,12 +17,116 @@ import { it, describe, expect } from '@angular/core/testing'; import { ActivitiForm } from './activiti-form.component'; +import { FormModel, FormOutcomeModel } from './widgets/index'; describe('ActivitiForm', () => { - it('test placeholder', () => { - let form = new ActivitiForm(null); - expect(form).toBeDefined(); + let componentHandler: any; + + beforeEach(() => { + componentHandler = jasmine.createSpyObj('componentHandler', [ + 'upgradeAllRegistered' + ]); + + window['componentHandler'] = componentHandler; + }); + + it('should upgrade MDL content on view checked', () => { + let formComponent = new ActivitiForm(null); + formComponent.ngAfterViewChecked(); + expect(componentHandler.upgradeAllRegistered).toHaveBeenCalled(); + }); + + it('should setup MDL content only if component handler available', () => { + let formComponent = new ActivitiForm(null); + expect(formComponent.setupMaterialComponents()).toBeTruthy(); + + window['componentHandler'] = null; + expect(formComponent.setupMaterialComponents()).toBeFalsy(); + }); + + it('should start loading form on init', () => { + let formComponent = new ActivitiForm(null); + spyOn(formComponent, 'loadForm').and.stub(); + formComponent.ngOnInit(); + expect(formComponent.loadForm).toHaveBeenCalled(); + }); + + it('should check form', () => { + let formComponent = new ActivitiForm(null); + expect(formComponent.hasForm()).toBeFalsy(); + formComponent.form = new FormModel(); + expect(formComponent.hasForm()).toBeTruthy(); + }); + + it('should allow title if task name available', () => { + let formComponent = new ActivitiForm(null); + let formModel = new FormModel(); + formComponent.form = formModel; + + expect(formComponent.showTitle).toBeTruthy(); + expect(formModel.taskName).toBe(FormModel.UNSET_TASK_NAME); + expect(formComponent.isTitleEnabled()).toBeTruthy(); + + // override property as it's the readonly one + Object.defineProperty(formModel, 'taskName', { + enumerable: false, + configurable: false, + writable: false, + value: null + }); + + expect(formComponent.isTitleEnabled()).toBeFalsy(); + }); + + it('should not allow title', () => { + let formComponent = new ActivitiForm(null); + let formModel = new FormModel(); + + formComponent.form = formModel; + formComponent.showTitle = false; + + expect(formModel.taskName).toBe(FormModel.UNSET_TASK_NAME); + expect(formComponent.isTitleEnabled()).toBeFalsy(); + }); + + it('should not enable outcome button when model missing', () => { + let formComponent = new ActivitiForm(null); + expect(formComponent.isOutcomeButtonEnabled(null)).toBeFalsy(); + }); + + it('should enable custom outcome buttons', () => { + let formComponent = new ActivitiForm(null); + let formModel = new FormModel(); + let outcome = new FormOutcomeModel(formModel, { id: 'action1', name: 'Action 1' }); + expect(formComponent.isOutcomeButtonEnabled(outcome)).toBeTruthy(); + }); + + + it('should allow controlling [complete] button visibility', () => { + let formComponent = new ActivitiForm(null); + + let formModel = new FormModel(); + let outcome = new FormOutcomeModel(formModel, { id: '$save', name: FormOutcomeModel.SAVE_ACTION }); + + formComponent.showSaveButton = true; + expect(formComponent.isOutcomeButtonEnabled(outcome)).toBeTruthy(); + + formComponent.showSaveButton = false; + expect(formComponent.isOutcomeButtonEnabled(outcome)).toBeFalsy(); + }); + + it('should allow controlling [save] button visibility', () => { + let formComponent = new ActivitiForm(null); + + let formModel = new FormModel(); + let outcome = new FormOutcomeModel(formModel, { id: '$save', name: FormOutcomeModel.COMPLETE_ACTION }); + + formComponent.showCompleteButton = true; + expect(formComponent.isOutcomeButtonEnabled(outcome)).toBeTruthy(); + + formComponent.showCompleteButton = false; + expect(formComponent.isOutcomeButtonEnabled(outcome)).toBeFalsy(); }); }); diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.ts b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.ts index b8eec25efb..52a6d71688 100644 --- a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.ts +++ b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.ts @@ -39,12 +39,12 @@ declare var componentHandler; * ActivitiForm can show 3 forms searching by 3 type of params: * 1) Form attached to a task passing the {taskId}. * 2) Form that are only defined with the {formId} (in this case you receive only the form definition and the form will not be - * attached to any process, usefull in case you want to use Activitiform as form designer), in this case you can pass also other 2 + * attached to any process, useful in case you want to use ActivitiForm as form designer), in this case you can pass also other 2 * parameters: * - {saveOption} as parameter to tell what is the function to call on the save action. * - {data} to fill the form field with some data, the id of the form must to match the name of the field of the provided data object. * 3) Form that are only defined with the {formName} (in this case you receive only the form definition and the form will not be - * attached to any process, usefull in case you want to use Activitiform as form designer), + * attached to any process, useful in case you want to use ActivitiForm as form designer), * in this case you can pass also other 2 parameters: * - {saveOption} as parameter to tell what is the function to call on the save action. * - {data} to fill the form field with some data, the id of the form must to match the name of the field of the provided data object. @@ -122,56 +122,55 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { } isTitleEnabled(): boolean { - return this.form.taskName && this.showTitle; + if (this.showTitle) { + if (this.form && this.form.taskName) { + return true; + } + } + return false; } - isOutcomeButtonEnabled(outcome: any): boolean { - if (outcome.name === 'Complete') { - return this.showCompleteButton; + isOutcomeButtonEnabled(outcome: FormOutcomeModel): boolean { + if (outcome && outcome.name) { + if (outcome.name === FormOutcomeModel.COMPLETE_ACTION) { + return this.showCompleteButton; + } + if (outcome.name === FormOutcomeModel.SAVE_ACTION) { + return this.showSaveButton; + } + return true; } - if (outcome.name === 'Save') { - return this.showSaveButton; - } - return true; + return false; } ngOnInit() { - if (this.taskId) { - this.loadForm(this.taskId); - } - if (this.formId) { - this.getFormDefinitionById(); - } - if (this.formName) { - this.getFormDefinitionByName(); - } + this.loadForm(); } ngAfterViewChecked() { - // workaround for MDL issues with dynamic components - if (componentHandler) { - componentHandler.upgradeAllRegistered(); - } + this.setupMaterialComponents(); } ngOnChanges(changes: {[propertyName: string]: SimpleChange}) { let taskId = changes['taskId']; if (taskId && taskId.currentValue) { - this.loadForm(taskId.currentValue); + this.getFormByTaskId(taskId.currentValue); + return; } let formId = changes['formId']; if (formId && formId.currentValue) { - this.getFormDefinitionById(); + this.getFormDefinitionByFormId(formId.currentValue); + return; } let formName = changes['formName']; if (formName && formName.currentValue) { - this.getFormDefinitionByName(); + this.getFormDefinitionByFormName(formName.currentValue); + return; } } - onOutcomeClicked(outcome: FormOutcomeModel, event?: Event) { if (!this.readOnly && outcome) { if (outcome.isSystem) { @@ -197,18 +196,36 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { } onRefreshClicked() { + this.loadForm(); + } + + loadForm() { if (this.taskId) { - this.loadForm(this.taskId); + this.getFormByTaskId(this.taskId); + return; } + if (this.formId) { - this.getFormDefinitionById(); + this.getFormDefinitionByFormId(this.formId); + return; } + if (this.formName) { - this.getFormDefinitionByName(); + this.getFormDefinitionByFormName(this.formName); + return; } } - private loadForm(taskId: string) { + setupMaterialComponents(): boolean { + // workaround for MDL issues with dynamic components + if (componentHandler) { + componentHandler.upgradeAllRegistered(); + return true; + } + return false; + } + + private getFormByTaskId(taskId: string) { let data = this.data; this.formService .getTaskForm(taskId) @@ -221,12 +238,12 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { ); } - private getFormDefinitionById() { + private getFormDefinitionByFormId(formId: string) { this.formService - .getFormDefinitionById(this.formId) + .getFormDefinitionById(formId) .subscribe( form => { - console.log('Get Form By definition Id', form); + // console.log('Get Form By definition Id', form); this.form = this.parseForm(form); this.formLoaded.emit(this.form.values); }, @@ -234,14 +251,14 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { ); } - private getFormDefinitionByName() { + private getFormDefinitionByFormName(formName: string) { this.formService - .getFormDefinitionByName(this.formName) + .getFormDefinitionByName(formName) .subscribe( id => { this.formService.getFormDefinitionById(id).subscribe( form => { - console.log('Get Form By Form definition Name', form); + // console.log('Get Form By Form definition Name', form); this.form = this.parseForm(form); this.formLoaded.emit(this.form.values); }, @@ -255,7 +272,7 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { private saveTaskForm() { this.formService.saveTaskForm(this.form.taskId, this.form.values).subscribe( (response) => { - console.log('Saved task', response); + // console.log('Saved task', response); this.formSaved.emit(this.form.values); }, (err) => console.log(err) @@ -267,7 +284,7 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { .completeTaskForm(this.form.taskId, this.form.values, outcome) .subscribe( (response) => { - console.log('Completed task', response); + // console.log('Completed task', response); this.formCompleted.emit(this.form.values); }, (err) => console.log(err) @@ -284,7 +301,7 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { private getFormDefinitionOutcomes(form: FormModel): FormOutcomeModel[] { return [ - new FormOutcomeModel(form, { id: '$custom', name: 'Save', isSystem: true }) + new FormOutcomeModel(form, { id: '$custom', name: FormOutcomeModel.SAVE_ACTION, isSystem: true }) ]; } } diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.spec.ts new file mode 100644 index 0000000000..54b43944fa --- /dev/null +++ b/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.spec.ts @@ -0,0 +1,97 @@ +/*! + * @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 { it, describe, expect, beforeEach } from '@angular/core/testing'; +import { ContainerWidget } from './container.widget'; +import { FormModel } from './../core/form.model'; +import { ContainerModel } from './../core/container.model'; +import { FormFieldTypes } from './../core/form-field-types'; + +describe('ContainerWidget', () => { + + let componentHandler; + + beforeEach(() => { + componentHandler = jasmine.createSpyObj('componentHandler', [ + 'upgradeAllRegistered' + ]); + + window['componentHandler'] = componentHandler; + }); + + it('should upgrade MDL content on view init', () => { + let container = new ContainerWidget(); + container.ngAfterViewInit(); + expect(componentHandler.upgradeAllRegistered).toHaveBeenCalled(); + }); + + it('should setup MDL content only if component handler available', () => { + let container = new ContainerWidget(); + expect(container.setupMaterialComponents()).toBeTruthy(); + + window['componentHandler'] = null; + expect(container.setupMaterialComponents()).toBeFalsy(); + }); + + it('should toggle underlying group container', () => { + let container = new ContainerModel(new FormModel(), { + type: FormFieldTypes.GROUP, + params: { + allowCollapse: true + } + }); + + let widget = new ContainerWidget(); + widget.content = container; + + expect(container.isExpanded).toBeTruthy(); + widget.onExpanderClicked(); + expect(container.isExpanded).toBeFalsy(); + widget.onExpanderClicked(); + expect(container.isExpanded).toBeTruthy(); + }); + + it('should toggle only collapsible container', () => { + let container = new ContainerModel(new FormModel(), { + type: FormFieldTypes.GROUP + }); + + let widget = new ContainerWidget(); + widget.content = container; + + expect(container.isExpanded).toBeTruthy(); + widget.onExpanderClicked(); + expect(container.isExpanded).toBeTruthy(); + }); + + it('should toggle only group container', () => { + let container = new ContainerModel(new FormModel(), { + type: FormFieldTypes.CONTAINER, + params: { + allowCollapse: true + } + }); + + let widget = new ContainerWidget(); + widget.content = container; + + expect(container.isExpanded).toBeTruthy(); + widget.onExpanderClicked(); + expect(container.isExpanded).toBeTruthy(); + }); + +}); diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.ts b/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.ts index 12e962b10e..50e14bc604 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.ts @@ -46,10 +46,16 @@ export class ContainerWidget implements AfterViewInit { } ngAfterViewInit() { + this.setupMaterialComponents(); + } + + setupMaterialComponents(): boolean { // workaround for MDL issues with dynamic components if (componentHandler) { componentHandler.upgradeAllRegistered(); + return true; } + return false; } } diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-outcome.model.ts b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-outcome.model.ts index 6b7905bdaa..f0eb0abb05 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-outcome.model.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-outcome.model.ts @@ -20,6 +20,9 @@ import { FormModel } from './form.model'; export class FormOutcomeModel extends FormWidgetModel { + static SAVE_ACTION: string = 'Save'; // Activiti 'Save' action name + static COMPLETE_ACTION: string = 'Complete'; // Activiti 'Complete' action name + private _id: string; private _name: string; diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/widget.component.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/widget.component.spec.ts new file mode 100644 index 0000000000..d57b2e54f9 --- /dev/null +++ b/ng2-components/ng2-activiti-form/src/components/widgets/widget.component.spec.ts @@ -0,0 +1,55 @@ +/*! + * @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 { it, describe, expect, beforeEach } from '@angular/core/testing'; +import { WidgetComponent } from './widget.component'; +import { FormFieldModel } from './core/form-field.model'; + +describe('WidgetComponent', () => { + + let componentHandler; + + beforeEach(() => { + componentHandler = jasmine.createSpyObj('componentHandler', [ + 'upgradeAllRegistered' + ]); + + window['componentHandler'] = componentHandler; + }); + + it('should upgrade MDL content on view init', () => { + let component = new WidgetComponent(); + component.ngAfterViewInit(); + expect(componentHandler.upgradeAllRegistered).toHaveBeenCalled(); + }); + + it('should setup MDL content only if component handler available', () => { + let component = new WidgetComponent(); + expect(component.setupMaterialComponents()).toBeTruthy(); + + window['componentHandler'] = null; + expect(component.setupMaterialComponents()).toBeFalsy(); + }); + + it('should check field', () => { + let component = new WidgetComponent(); + + expect(component.hasField()).toBeFalsy(); + component.field = new FormFieldModel(null); + expect(component.hasField()).toBeTruthy(); + }); +}); diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/widget.component.ts b/ng2-components/ng2-activiti-form/src/components/widgets/widget.component.ts index 7b4123954b..ec08a747cc 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/widget.component.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/widget.component.ts @@ -34,10 +34,16 @@ export class WidgetComponent implements AfterViewInit { } ngAfterViewInit() { + this.setupMaterialComponents(); + } + + setupMaterialComponents(): boolean { // workaround for MDL issues with dynamic components if (componentHandler) { componentHandler.upgradeAllRegistered(); + return true; } + return false; } }