#1091 - fix typeahead widget

This commit is contained in:
Vito Albano 2016-11-15 15:12:24 +00:00 committed by Mario Romano
parent 29c5b61c00
commit e114534bc5
3 changed files with 177 additions and 15 deletions

View File

@ -1,6 +1,6 @@
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label typeahead-widget"
[class.is-dirty]="value"
[class.typeahead-widget__invalid]="!field.isValid" id="typehead-div">
[class.typeahead-widget__invalid]="!field.isValid" id="typehead-div" *ngIf="field.isVisible">
<input class="mdl-textfield__input"
type="text"
[attr.id]="field.id"
@ -14,6 +14,7 @@
<div class="typeahead-autocomplete mdl-shadow--2dp" *ngIf="options.length > 0 && popupVisible">
<ul>
<li *ngFor="let item of options"
[attr.id]="field.id +'-'+item.id"
class="mdl-menu__item"
(click)="onItemClick(item, $event)">
{{item.name}}

View File

@ -21,16 +21,23 @@ import { FormService } from '../../../services/form.service';
import { FormModel } from '../core/form.model';
import { FormFieldModel } from '../core/form-field.model';
import { FormFieldOption } from '../core/form-field-option';
import { CoreModule } from 'ng2-alfresco-core';
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { EcmModelService } from '../../../services/ecm-model.service';
import { WidgetVisibilityService } from '../../../services/widget-visibility.service';
import { FormFieldTypes } from '../core/form-field-types';
describe('TypeaheadWidget', () => {
let formService: FormService;
let widget: TypeaheadWidget;
let visibilityService: WidgetVisibilityService;
beforeEach(() => {
formService = new FormService(null, null);
widget = new TypeaheadWidget(formService);
widget.field = new FormFieldModel(new FormModel());
visibilityService = new WidgetVisibilityService(null, null, null);
widget = new TypeaheadWidget(formService, visibilityService);
widget.field = new FormFieldModel(new FormModel({ taskId: 'task-id' }));
});
it('should request field values from service', () => {
@ -53,7 +60,17 @@ describe('TypeaheadWidget', () => {
expect(formService.getRestFieldValues).toHaveBeenCalledWith(taskId, fieldId);
});
it('should handle error when requesting fields', () => {
it('should handle error when requesting fields with task id', () => {
const taskId = '<form-id>';
const fieldId = '<field-id>';
let form = new FormModel({
taskId: taskId
});
widget.field = new FormFieldModel(form, {
id: fieldId
});
const err = 'Error';
spyOn(formService, 'getRestFieldValues').and.returnValue(Observable.throw(err));
spyOn(widget, 'handleError').and.callThrough();
@ -64,6 +81,27 @@ describe('TypeaheadWidget', () => {
expect(widget.handleError).toHaveBeenCalledWith(err);
});
it('should handle error when requesting fields with process id', () => {
const processDefinitionId = '<process-id>';
const fieldId = '<field-id>';
let form = new FormModel({
processDefinitionId: processDefinitionId
});
widget.field = new FormFieldModel(form, {
id: fieldId
});
const err = 'Error';
spyOn(formService, 'getRestFieldValuesByProcessId').and.returnValue(Observable.throw(err));
spyOn(widget, 'handleError').and.callThrough();
widget.ngOnInit();
expect(formService.getRestFieldValuesByProcessId).toHaveBeenCalled();
expect(widget.handleError).toHaveBeenCalledWith(err);
});
it('should log error to console by default', () => {
spyOn(console, 'error').and.stub();
widget.handleError('Err');
@ -143,7 +181,7 @@ describe('TypeaheadWidget', () => {
id: '1',
name: 'name'
};
spyOn(visibilityService, 'refreshVisibility').and.stub();
widget.onItemClick(option, null);
expect(widget.field.value).toBe(option.id);
expect(widget.value).toBe(option.name);
@ -157,7 +195,6 @@ describe('TypeaheadWidget', () => {
]);
observer.complete();
}));
widget.field.value = '2';
widget.ngOnInit();
@ -337,4 +374,122 @@ describe('TypeaheadWidget', () => {
done();
}, 200);
});
describe('when template is ready', () => {
let typeaheadWidget: TypeaheadWidget;
let fixture: ComponentFixture<TypeaheadWidget>;
let element: HTMLElement;
let componentHandler;
let stubFormService;
let fakeOptionList: FormFieldOption[] = [{
id: '1',
name: 'Fake Name 1 '
}, {
id: '2',
name: 'Fake Name 2'
}, { id: '3', name: 'Fake Name 3' }];
beforeEach(async(() => {
componentHandler = jasmine.createSpyObj('componentHandler', ['upgradeAllRegistered', 'upgradeElement']);
window['componentHandler'] = componentHandler;
TestBed.configureTestingModule({
imports: [CoreModule],
declarations: [TypeaheadWidget],
providers: [FormService, EcmModelService, WidgetVisibilityService]
}).compileComponents().then(() => {
fixture = TestBed.createComponent(TypeaheadWidget);
typeaheadWidget = fixture.componentInstance;
element = fixture.nativeElement;
});
}));
afterEach(() => {
fixture.destroy();
TestBed.resetTestingModule();
});
describe('and typeahead is populated via taskId', () => {
beforeEach(async(() => {
stubFormService = fixture.debugElement.injector.get(FormService);
visibilityService = fixture.debugElement.injector.get(WidgetVisibilityService);
spyOn(visibilityService, 'refreshVisibility').and.stub();
spyOn(stubFormService, 'getRestFieldValues').and.returnValue(Observable.of(fakeOptionList));
typeaheadWidget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
id: 'typeahead-id',
name: 'typeahead-name',
type: FormFieldTypes.TYPEAHEAD,
readOnly: false
});
typeaheadWidget.field.isVisible = true;
fixture.detectChanges();
}));
it('should show visible typeahead widget', async(() => {
expect(element.querySelector('#typeahead-id')).toBeDefined();
expect(element.querySelector('#typeahead-id')).not.toBeNull();
}));
it('should show typeahead options', async(() => {
typeaheadWidget.value = 'F';
typeaheadWidget.onKeyUp(null);
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(element.querySelector('#typeahead-id-1')).toBeDefined();
expect(element.querySelector('#typeahead-id-1')).not.toBeNull();
expect(element.querySelector('#typeahead-id-2')).toBeDefined();
expect(element.querySelector('#typeahead-id-2')).not.toBeNull();
expect(element.querySelector('#typeahead-id-3')).toBeDefined();
expect(element.querySelector('#typeahead-id-3')).not.toBeNull();
});
}));
it('should hide not visibile typeahead', async(() => {
typeaheadWidget.field.isVisible = false;
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(element.querySelector('#typeahead-id')).toBeNull();
});
}));
});
describe('and typeahead is populated via processDefinitionId', () => {
beforeEach(async(() => {
stubFormService = fixture.debugElement.injector.get(FormService);
visibilityService = fixture.debugElement.injector.get(WidgetVisibilityService);
spyOn(visibilityService, 'refreshVisibility').and.stub();
spyOn(stubFormService, 'getRestFieldValuesByProcessId').and.returnValue(Observable.of(fakeOptionList));
typeaheadWidget.field = new FormFieldModel(new FormModel({ processDefinitionId: 'fake-process-id' }), {
id: 'typeahead-id',
name: 'typeahead-name',
type: FormFieldTypes.TYPEAHEAD,
readOnly: 'false'
});
typeaheadWidget.field.emptyOption = { id: 'empty', name: 'Choose one...' };
typeaheadWidget.field.isVisible = true;
fixture.detectChanges();
}));
it('should show visible typeahead widget', async(() => {
expect(element.querySelector('#typeahead-id')).toBeDefined();
expect(element.querySelector('#typeahead-id')).not.toBeNull();
}));
it('should show typeahead options', async(() => {
typeaheadWidget.value = 'F';
typeaheadWidget.onKeyUp(null);
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(element.querySelector('#typeahead-id-1')).toBeDefined();
expect(element.querySelector('#typeahead-id-1')).not.toBeNull();
expect(element.querySelector('#typeahead-id-2')).toBeDefined();
expect(element.querySelector('#typeahead-id-2')).not.toBeNull();
expect(element.querySelector('#typeahead-id-3')).toBeDefined();
expect(element.querySelector('#typeahead-id-3')).not.toBeNull();
});
}));
});
});
});

View File

@ -19,6 +19,7 @@ import { Component, OnInit } from '@angular/core';
import { FormService } from './../../../services/form.service';
import { WidgetComponent } from './../widget.component';
import { FormFieldOption } from './../core/form-field-option';
import { WidgetVisibilityService } from '../../../services/widget-visibility.service';
@Component({
moduleId: module.id,
@ -33,15 +34,16 @@ export class TypeaheadWidget extends WidgetComponent implements OnInit {
value: string;
options: FormFieldOption[] = [];
constructor(private formService: FormService) {
constructor(private formService: FormService,
private visibilityService: WidgetVisibilityService) {
super();
}
ngOnInit() {
if (this.field.form.processDefinitionId) {
this.getValuesByProcessDefinitionId();
} else {
if (this.field.form.taskId) {
this.getValuesByTaskId();
} else {
this.getValuesByProcessDefinitionId();
}
}
@ -113,7 +115,7 @@ export class TypeaheadWidget extends WidgetComponent implements OnInit {
onBlur() {
setTimeout(() => {
this.flushValue();
this.checkVisibility(this.field);
this.checkVisibility();
}, 200);
}
@ -141,7 +143,7 @@ export class TypeaheadWidget extends WidgetComponent implements OnInit {
if (item) {
this.field.value = item.id;
this.value = item.name;
this.checkVisibility(this.field);
this.checkVisibility();
}
if (event) {
event.preventDefault();
@ -152,4 +154,8 @@ export class TypeaheadWidget extends WidgetComponent implements OnInit {
console.error(error);
}
checkVisibility() {
this.visibilityService.refreshVisibility(this.field.form);
}
}