Unit tests

This commit is contained in:
Denys Vuika
2016-10-26 10:26:58 +01:00
committed by Vito Albano
parent fe7b05df4f
commit 0ad2c10930
14 changed files with 747 additions and 30 deletions

View File

@@ -74,8 +74,10 @@ export class DynamicTableModel extends FormWidgetModel {
} }
flushValue() { flushValue() {
this.field.value = this.rows.map(r => r.value); if (this.field) {
this.field.updateForm(); this.field.value = this.rows.map(r => r.value);
this.field.updateForm();
}
} }
moveRow(row: DynamicTableRow, offset: number) { moveRow(row: DynamicTableRow, offset: number) {
@@ -152,7 +154,7 @@ export class DynamicTableModel extends FormWidgetModel {
if (column.type === 'Date') { if (column.type === 'Date') {
if (result) { if (result) {
return moment(result.split('T')[0], 'YYYY-M-D').format('DD-MM-YYYY'); return moment(result.split('T')[0], 'YYYY-MM-DD').format('DD-MM-YYYY');
} }
} }

View File

@@ -0,0 +1,209 @@
/*!
* @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 { DynamicTableWidget } from './dynamic-table.widget';
import { DynamicTableModel, DynamicTableRow, DynamicTableColumn } from './../core/index';
describe('DynamicTableWidget', () => {
let widget: DynamicTableWidget;
let table: DynamicTableModel;
beforeEach(() => {
table = new DynamicTableModel(null);
widget = new DynamicTableWidget(null);
widget.content = table;
});
it('should select row on click', () => {
let row = <DynamicTableRow> { selected: false };
widget.onRowClicked(row);
expect(row.selected).toBeTruthy();
expect(widget.content.selectedRow).toBe(row);
});
it('should requre table to select clicked row', () => {
let row = <DynamicTableRow> { selected: false };
widget.content = null;
widget.onRowClicked(row);
expect(row.selected).toBeFalsy();
});
it('should reset selected row', () => {
let row = <DynamicTableRow> { selected: false };
widget.content.rows.push(row);
widget.content.selectedRow = row;
expect(widget.content.selectedRow).toBe(row);
expect(row.selected).toBeTruthy();
widget.onRowClicked(null);
expect(widget.content.selectedRow).toBeNull();
expect(row.selected).toBeFalsy();
});
it('should check selection', () => {
let row = <DynamicTableRow> { selected: false };
widget.content.rows.push(row);
widget.content.selectedRow = row;
expect(widget.hasSelection()).toBeTruthy();
widget.content.selectedRow = null;
expect(widget.hasSelection()).toBeFalsy();
widget.content = null;
expect(widget.hasSelection()).toBeFalsy();
});
it('should require table to move selection up', () => {
widget.content = null;
expect(widget.moveSelectionUp()).toBeFalsy();
});
it('should move selection up', () => {
let row1 = <DynamicTableRow> {};
let row2 = <DynamicTableRow> {};
widget.content.rows.push(...[row1, row2]);
widget.content.selectedRow = row2;
expect(widget.moveSelectionUp()).toBeTruthy();
expect(widget.content.rows.indexOf(row2)).toBe(0);
});
it('should require table to move selection down', () => {
widget.content = null;
expect(widget.moveSelectionDown()).toBeFalsy();
});
it('should move selection down', () => {
let row1 = <DynamicTableRow> { };
let row2 = <DynamicTableRow> { };
widget.content.rows.push(...[row1, row2]);
widget.content.selectedRow = row1;
expect(widget.moveSelectionDown()).toBeTruthy();
expect(widget.content.rows.indexOf(row1)).toBe(1);
});
it('should require table to delete selection', () => {
widget.content = null;
expect(widget.deleteSelection()).toBeFalsy();
});
it('should delete selected row', () => {
let row = <DynamicTableRow> {};
widget.content.rows.push(row);
widget.content.selectedRow = row;
widget.deleteSelection();
expect(widget.content.rows.length).toBe(0);
});
it('should require table to add new row', () => {
widget.content = null;
expect(widget.addNewRow()).toBeFalsy();
});
it('should start editing new row', () => {
expect(widget.editMode).toBeFalsy();
expect(widget.editRow).toBeNull();
expect(widget.addNewRow()).toBeTruthy();
expect(widget.editRow).not.toBeNull();
expect(widget.editMode).toBeTruthy();
});
it('should require table to edit selected row', () => {
widget.content = null;
expect(widget.editSelection()).toBeFalsy();
});
it('should start editing selected row', () => {
expect(widget.editMode).toBeFalsy();
expect(widget.editRow).toBeFalsy();
let row = <DynamicTableRow> { value: true };
widget.content.selectedRow = row;
expect(widget.editSelection()).toBeTruthy();
expect(widget.editMode).toBeTruthy();
expect(widget.editRow).not.toBeNull();
expect(widget.editRow.value).toEqual(row.value);
});
it('should copy row', () => {
let row = <DynamicTableRow> { value: { opt: { key: '1', value: 1 } } };
let copy = widget.copyRow(row);
expect(copy.value).toEqual(row.value);
});
it('should require table to retrieve cell value', () => {
widget.content = null;
expect(widget.getCellValue(null, null)).toBeNull();
});
it('should retrieve cell value', () => {
const value = '<value>';
let row = <DynamicTableRow> { value: { key: value } };
let column = <DynamicTableColumn> { id: 'key' };
expect(widget.getCellValue(row, column)).toBe(value);
});
it('should save changes and add new row', () => {
let row = <DynamicTableRow> { isNew: true, value: { key: 'value' } };
widget.editMode = true;
widget.editRow = row;
widget.onSaveChanges();
expect(row.isNew).toBeFalsy();
expect(widget.content.selectedRow).toBeNull();
expect(widget.content.rows.length).toBe(1);
expect(widget.content.rows[0].value).toEqual(row.value);
});
it('should save changes and update row', () => {
let row = <DynamicTableRow> { isNew: false, value: { key: 'value' } };
widget.editMode = true;
widget.editRow = row;
widget.content.selectedRow = row;
widget.onSaveChanges();
expect(widget.content.selectedRow.value).toEqual(row.value);
});
it('should require table to save changes', () => {
spyOn(console, 'log').and.stub();
widget.editMode = true;
widget.content = null;
widget.onSaveChanges();
expect(widget.editMode).toBeFalsy();
expect(console.log).toHaveBeenCalledWith(widget.ERROR_MODEL_NOT_FOUND);
});
it('should cancel changes', () => {
widget.editMode = true;
widget.editRow = <DynamicTableRow> {};
widget.onCancelChanges();
expect(widget.editMode).toBeFalsy();
expect(widget.editRow).toBeNull();
});
});

View File

@@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { Component, Input, OnInit, ElementRef } from '@angular/core'; import { Component, Input, ElementRef } from '@angular/core';
import { WidgetComponent } from './../widget.component'; import { WidgetComponent } from './../widget.component';
import { DynamicTableModel, DynamicTableRow, DynamicTableColumn } from './../core/index'; import { DynamicTableModel, DynamicTableRow, DynamicTableColumn } from './../core/index';
@@ -25,23 +25,20 @@ import { DynamicTableModel, DynamicTableRow, DynamicTableColumn } from './../cor
templateUrl: './dynamic-table.widget.html', templateUrl: './dynamic-table.widget.html',
styleUrls: ['./dynamic-table.widget.css'] styleUrls: ['./dynamic-table.widget.css']
}) })
export class DynamicTableWidget extends WidgetComponent implements OnInit { export class DynamicTableWidget extends WidgetComponent {
ERROR_MODEL_NOT_FOUND = 'Table model not found';
@Input() @Input()
content: DynamicTableModel; content: DynamicTableModel;
editMode: boolean; editMode: boolean = false;
editRow: DynamicTableRow; editRow: DynamicTableRow = null;
validationSummary: string;
constructor(private elementRef: ElementRef) { constructor(private elementRef: ElementRef) {
super(); super();
} }
ngOnInit() {
this.validationSummary = 'hello world';
}
onRowClicked(row: DynamicTableRow) { onRowClicked(row: DynamicTableRow) {
if (this.content) { if (this.content) {
this.content.selectedRow = row; this.content.selectedRow = row;
@@ -52,25 +49,31 @@ export class DynamicTableWidget extends WidgetComponent implements OnInit {
return !!(this.content && this.content.selectedRow); return !!(this.content && this.content.selectedRow);
} }
moveSelectionUp() { moveSelectionUp(): boolean {
if (this.content) { if (this.content) {
this.content.moveRow(this.content.selectedRow, -1); this.content.moveRow(this.content.selectedRow, -1);
return true;
} }
return false;
} }
moveSelectionDown() { moveSelectionDown(): boolean {
if (this.content) { if (this.content) {
this.content.moveRow(this.content.selectedRow, 1); this.content.moveRow(this.content.selectedRow, 1);
return true;
} }
return false;
} }
deleteSelection() { deleteSelection(): boolean {
if (this.content) { if (this.content) {
this.content.deleteRow(this.content.selectedRow); this.content.deleteRow(this.content.selectedRow);
return true;
} }
return false;
} }
addNewRow() { addNewRow(): boolean {
if (this.content) { if (this.content) {
this.editRow = <DynamicTableRow> { this.editRow = <DynamicTableRow> {
isNew: true, isNew: true,
@@ -78,14 +81,18 @@ export class DynamicTableWidget extends WidgetComponent implements OnInit {
value: {} value: {}
}; };
this.editMode = true; this.editMode = true;
return true;
} }
return false;
} }
editSelection() { editSelection(): boolean {
if (this.content) { if (this.content) {
this.editRow = this.copyRow(this.content.selectedRow); this.editRow = this.copyRow(this.content.selectedRow);
this.editMode = true; this.editMode = true;
return true;
} }
return false;
} }
getCellValue(row: DynamicTableRow, column: DynamicTableColumn): any { getCellValue(row: DynamicTableRow, column: DynamicTableColumn): any {
@@ -106,6 +113,8 @@ export class DynamicTableWidget extends WidgetComponent implements OnInit {
this.content.selectedRow.value = this.copyObject(this.editRow.value); this.content.selectedRow.value = this.copyObject(this.editRow.value);
} }
this.content.flushValue(); this.content.flushValue();
} else {
this.handleError(this.ERROR_MODEL_NOT_FOUND);
} }
this.editMode = false; this.editMode = false;
} }
@@ -115,16 +124,17 @@ export class DynamicTableWidget extends WidgetComponent implements OnInit {
this.editRow = null; this.editRow = null;
} }
private copyRow(row: DynamicTableRow): DynamicTableRow { copyRow(row: DynamicTableRow): DynamicTableRow {
return <DynamicTableRow> { return <DynamicTableRow> {
value: this.copyObject(row.value) value: this.copyObject(row.value)
}; };
} }
private copyObject(obj: any): any { private copyObject(obj: any): any {
let result = Object.assign({}, obj); let result = obj;
if (typeof obj === 'object' && obj !== null && obj !== undefined) { if (typeof obj === 'object' && obj !== null && obj !== undefined) {
result = Object.assign({}, obj);
Object.keys(obj).forEach(key => { Object.keys(obj).forEach(key => {
if (typeof obj[key] === 'object') { if (typeof obj[key] === 'object') {
result[key] = this.copyObject(obj[key]); result[key] = this.copyObject(obj[key]);

View File

@@ -0,0 +1,38 @@
/*!
* @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 { BooleanEditorComponent } from './boolean.editor';
import { DynamicTableRow, DynamicTableColumn } from './../../../core/index';
describe('BooleanEditorComponent', () => {
let component: BooleanEditorComponent;
beforeEach(() => {
component = new BooleanEditorComponent();
});
it('should update row value on change', () => {
let row = <DynamicTableRow> { value: {} };
let column = <DynamicTableColumn> { id: 'key' };
let event = { srcElement: { checked: true } };
component.onValueChanged(row, column, event);
expect(row.value[column.id]).toBeTruthy();
});
});

View File

@@ -27,7 +27,7 @@ import { DynamicTableRow, DynamicTableColumn } from './../../../core/index';
}) })
export class BooleanEditorComponent extends CellEditorComponent { export class BooleanEditorComponent extends CellEditorComponent {
onValueChanged(row: DynamicTableRow, column: DynamicTableColumn, event: Event) { onValueChanged(row: DynamicTableRow, column: DynamicTableColumn, event: any) {
let value: boolean = (<HTMLInputElement>event.srcElement).checked; let value: boolean = (<HTMLInputElement>event.srcElement).checked;
row.value[column.id] = value; row.value[column.id] = value;
} }

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.
*/
import { CellEditorComponent } from './cell.editor';
describe('CellEditorComponent', () => {
class CustomEditor extends CellEditorComponent {
onError(error: any) {
this.handleError(error);
}
}
let component: CustomEditor;
beforeEach(() => {
component = new CustomEditor();
});
it('should handle error', () => {
const error = 'error';
spyOn(console, 'error').and.stub();
component.onError(error);
expect(console.error).toHaveBeenCalledWith(error);
});
});

View File

@@ -29,7 +29,7 @@ export abstract class CellEditorComponent {
@Input() @Input()
column: DynamicTableColumn; column: DynamicTableColumn;
protected handleError(error: any) { handleError(error: any) {
console.error(error); console.error(error);
} }

View File

@@ -0,0 +1,138 @@
/*!
* @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 { ElementRef } from '@angular/core';
import { DateEditorComponent } from './date.editor';
import { DynamicTableModel, DynamicTableRow, DynamicTableColumn/*, DynamicRowValidationSummary*/ } from './../../../core/index';
describe('DateEditorComponent', () => {
let nativeElement: any;
let elementRef: ElementRef;
let component: DateEditorComponent;
let row: DynamicTableRow;
let column: DynamicTableColumn;
let table: DynamicTableModel;
beforeEach(() => {
nativeElement = {
querySelector: function () { return null; }
};
row = <DynamicTableRow> { value: { date: '1879-03-14T00:00:00.000Z' } };
column = <DynamicTableColumn> { id: 'date', type: 'Date' };
table = new DynamicTableModel(null);
table.rows.push(row);
table.columns.push(column);
elementRef = new ElementRef(nativeElement);
component = new DateEditorComponent(elementRef);
component.table = table;
component.row = row;
component.column = column;
});
it('should setup date picker on init', () => {
let trigger = {};
spyOn(nativeElement, 'querySelector').and.returnValue(trigger);
component.ngOnInit();
let settings = component.settings;
expect(settings.type).toBe('date');
expect(settings.future.year()).toBe(moment().year() + 21);
expect(settings.init.isSame(moment('14-03-1879', component.DATE_FORMAT))).toBeTruthy();
expect(component.datePicker.trigger).toBe(trigger);
});
it('should require cell value to setup initial date', () => {
row.value[column.id] = null;
component.ngOnInit();
expect(component.settings.init).toBeUndefined();
});
it('should require dom element to setup trigger', () => {
component = new DateEditorComponent(null);
component.table = table;
component.row = row;
component.column = column;
component.ngOnInit();
expect(component.datePicker.trigger).toBeFalsy();
});
it('should update fow value on change', () => {
component.ngOnInit();
component.datePicker.time = moment('14-03-1879', 'DD-MM-YYYY');
component.onDateSelected(null);
expect(row.value[column.id]).toBe('1879-03-14T00:00:00.000Z');
});
it('should update material textfield on date selected', () => {
component.ngOnInit();
component.datePicker.time = moment('14-03-1879', 'DD-MM-YYYY');
spyOn(component, 'updateMaterialTextField').and.stub();
component.onDateSelected(null);
expect(component.updateMaterialTextField).toHaveBeenCalled();
});
it('should require dom element to update material textfield on change', () => {
component = new DateEditorComponent(null);
component.table = table;
component.row = row;
component.column = column;
component.ngOnInit();
component.datePicker.time = moment('14-03-1879', 'DD-MM-YYYY');
spyOn(component, 'updateMaterialTextField').and.stub();
component.onDateSelected(null);
expect(component.updateMaterialTextField).not.toHaveBeenCalled();
});
it('should require dom element to update material textfield', () => {
let result = component.updateMaterialTextField(null, 'value');
expect(result).toBeFalsy();
});
it('should require native dom element to update material textfield', () => {
elementRef.nativeElement = null;
let result = component.updateMaterialTextField(elementRef, 'value');
expect(result).toBeFalsy();
});
it('should require input element to update material textfield', () => {
spyOn(nativeElement, 'querySelector').and.returnValue(null);
let result = component.updateMaterialTextField(elementRef, 'value');
expect(result).toBeFalsy();
});
it('should update material textfield with new value', () => {
let called = false;
const value = '<value>';
spyOn(nativeElement, 'querySelector').and.returnValue({
MaterialTextfield: {
change: function (val) {
called = true;
expect(val).toBe(value);
}
}
});
component.updateMaterialTextField(elementRef, value);
expect(called).toBeTruthy();
});
});

View File

@@ -29,23 +29,24 @@ export class DateEditorComponent extends CellEditorComponent implements OnInit {
DATE_FORMAT: string = 'DD-MM-YYYY'; DATE_FORMAT: string = 'DD-MM-YYYY';
datePicker: any; datePicker: any;
settings: any;
constructor(private elementRef: ElementRef) { constructor(private elementRef: ElementRef) {
super(); super();
} }
ngOnInit() { ngOnInit() {
let settings: any = { this.settings = {
type: 'date', type: 'date',
future: moment().add(21, 'years') future: moment().add(21, 'years')
}; };
let value = this.table.getCellValue(this.row, this.column); let value = this.table.getCellValue(this.row, this.column);
if (value) { if (value) {
settings.init = moment(value, this.DATE_FORMAT); this.settings.init = moment(value, this.DATE_FORMAT);
} }
this.datePicker = new mdDateTimePicker.default(settings); this.datePicker = new mdDateTimePicker.default(this.settings);
if (this.elementRef) { if (this.elementRef) {
this.datePicker.trigger = this.elementRef.nativeElement.querySelector('#dateInput'); this.datePicker.trigger = this.elementRef.nativeElement.querySelector('#dateInput');
} }
@@ -57,12 +58,12 @@ export class DateEditorComponent extends CellEditorComponent implements OnInit {
this.table.flushValue(); this.table.flushValue();
if (this.elementRef) { if (this.elementRef) {
this.setupMaterialTextField(this.elementRef, componentHandler, newValue); this.updateMaterialTextField(this.elementRef, newValue);
} }
} }
setupMaterialTextField(elementRef: ElementRef, handler: any, value: string): boolean { updateMaterialTextField(elementRef: ElementRef, value: string): boolean {
if (elementRef && handler) { if (elementRef) {
let el = elementRef.nativeElement; let el = elementRef.nativeElement;
if (el) { if (el) {
let container = el.querySelector('.mdl-textfield'); let container = el.querySelector('.mdl-textfield');

View File

@@ -0,0 +1,154 @@
/*!
* @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 { Observable } from 'rxjs/Rx';
import { DropdownEditorComponent } from './dropdown.editor';
import {
DynamicTableModel,
DynamicTableRow,
DynamicTableColumn,
DynamicTableColumnOption,
FormFieldModel,
FormModel
} from './../../../core/index';
import { FormService } from './../../../../../services/form.service';
describe('DropdownEditorComponent', () => {
let component: DropdownEditorComponent;
let formService: FormService;
let form: FormModel;
let table: DynamicTableModel;
let column: DynamicTableColumn;
let row: DynamicTableRow;
beforeEach(() => {
formService = new FormService(null, null);
row = <DynamicTableRow> { value: { dropdown: 'one' } };
column = <DynamicTableColumn> {
id: 'dropdown',
options: [
<DynamicTableColumnOption> { id: '1', name: 'one' },
<DynamicTableColumnOption> { id: '2', name: 'two' }
]
};
table = new DynamicTableModel(null);
form = new FormModel({ taskId: '<task-id>' });
table.field = new FormFieldModel(form, { id: '<field-id>' });
table.rows.push(row);
table.columns.push(column);
component = new DropdownEditorComponent(formService);
component.table = table;
component.row = row;
component.column = column;
});
it('should require table field to setup', () => {
table.field = null;
component.ngOnInit();
expect(component.value).toBeNull();
expect(component.options).toEqual([]);
});
it('should setup with manual mode', () => {
row.value[column.id] = 'two';
component.ngOnInit();
expect(component.options).toEqual(column.options);
expect(component.value).toBe(row.value[column.id]);
});
it('should setup empty columns for manual mode', () => {
column.options = null;
component.ngOnInit();
expect(component.options).toEqual([]);
});
it('should setup with REST mode', () => {
column.optionType = 'rest';
row.value[column.id] = 'twelve';
let restResults = [
<DynamicTableColumnOption> { id: '11', name: 'eleven' },
<DynamicTableColumnOption> { id: '12', name: 'twelve' }
];
spyOn(formService, 'getRestFieldValuesColumn').and.returnValue(
Observable.create(observer => {
observer.next(restResults);
observer.complete();
})
);
component.ngOnInit();
expect(formService.getRestFieldValuesColumn).toHaveBeenCalledWith(
form.taskId,
table.field.id,
column.id
);
expect(column.options).toEqual(restResults);
expect(component.options).toEqual(restResults);
expect(component.value).toBe(row.value[column.id]);
});
it('should create empty options array on REST response', () => {
column.optionType = 'rest';
spyOn(formService, 'getRestFieldValuesColumn').and.returnValue(
Observable.create(observer => {
observer.next(null);
observer.complete();
})
);
component.ngOnInit();
expect(formService.getRestFieldValuesColumn).toHaveBeenCalledWith(
form.taskId,
table.field.id,
column.id
);
expect(column.options).toEqual([]);
expect(component.options).toEqual([]);
expect(component.value).toBe(row.value[column.id]);
});
it('should handle REST error', () => {
column.optionType = 'rest';
const error = 'error';
spyOn(formService, 'getRestFieldValuesColumn').and.returnValue(
Observable.throw(error)
);
spyOn(component, 'handleError').and.stub();
component.ngOnInit();
expect(component.handleError).toHaveBeenCalledWith(error);
});
it('should update row on value change', () => {
let event = { srcElement: { value: 'two' } };
component.onValueChanged(row, column, event);
expect(row.value[column.id]).toBe(column.options[1]);
});
});

View File

@@ -28,7 +28,7 @@ import { FormService } from './../../../../../services/form.service';
}) })
export class DropdownEditorComponent extends CellEditorComponent implements OnInit { export class DropdownEditorComponent extends CellEditorComponent implements OnInit {
value: any; value: any = null;
options: DynamicTableColumnOption[] = []; options: DynamicTableColumnOption[] = [];
constructor(private formService: FormService) { constructor(private formService: FormService) {
@@ -60,7 +60,7 @@ export class DropdownEditorComponent extends CellEditorComponent implements OnIn
} }
} }
onValueChanged(row: DynamicTableRow, column: DynamicTableColumn, event: Event) { onValueChanged(row: DynamicTableRow, column: DynamicTableColumn, event: any) {
let value: any = (<HTMLInputElement>event.srcElement).value; let value: any = (<HTMLInputElement>event.srcElement).value;
value = column.options.find(opt => opt.name === value); value = column.options.find(opt => opt.name === value);
row.value[column.id] = value; row.value[column.id] = value;

View File

@@ -0,0 +1,76 @@
/*!
* @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 { RowEditorComponent } from './row.editor';
import { DynamicTableModel, DynamicTableRow, DynamicTableColumn, DynamicRowValidationSummary } from './../../core/index';
describe('RowEditorComponent', () => {
let component: RowEditorComponent;
beforeEach(() => {
component = new RowEditorComponent();
component.table = new DynamicTableModel(null);
component.row = <DynamicTableRow> {};
component.column = <DynamicTableColumn> {};
});
it('should be valid upon init', () => {
expect(component.validationSummary.isValid).toBeTruthy();
expect(component.validationSummary.text).toBeNull();
});
it('should emit [cancel] event', (done) => {
component.cancel.subscribe(e => {
expect(e.table).toBe(component.table);
expect(e.row).toBe(component.row);
expect(e.column).toBe(component.column);
done();
});
component.onCancelChanges();
});
it('should validate row on save', () => {
spyOn(component.table, 'validateRow').and.callThrough();
component.onSaveChanges();
expect(component.table.validateRow).toHaveBeenCalledWith(component.row);
});
it('should emit [save] event', (done) => {
spyOn(component.table, 'validateRow').and.returnValue(
<DynamicRowValidationSummary> { isValid: true, text: null }
);
component.save.subscribe(e => {
expect(e.table).toBe(component.table);
expect(e.row).toBe(component.row);
expect(e.column).toBe(component.column);
done();
});
component.onSaveChanges();
});
it('should not emit [save] event for invalid row', () => {
spyOn(component.table, 'validateRow').and.returnValue(
<DynamicRowValidationSummary> { isValid: false, text: 'error' }
);
let raised = false;
component.save.subscribe(e => raised = true);
component.onSaveChanges();
expect(raised).toBeFalsy();
});
});

View File

@@ -0,0 +1,47 @@
/*!
* @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 { TextEditorComponent } from './text.editor';
import {
// DynamicTableModel,
DynamicTableRow,
DynamicTableColumn// ,
// DynamicTableColumnOption,
// FormFieldModel,
// FormModel
} from './../../../core/index';
describe('TextEditorComponent', () => {
let editor: TextEditorComponent;
beforeEach(() => {
editor = new TextEditorComponent();
});
it('should update row value on change', () => {
let row = <DynamicTableRow> { value: {} };
let column = <DynamicTableColumn> { id: 'key' };
const value = '<value>';
let event = { srcElement: { value } };
editor.onValueChanged(row, column, event);
expect(row.value[column.id]).toBe(value);
});
});

View File

@@ -27,7 +27,7 @@ import { DynamicTableRow, DynamicTableColumn } from './../../../core/index';
}) })
export class TextEditorComponent extends CellEditorComponent { export class TextEditorComponent extends CellEditorComponent {
onValueChanged(row: DynamicTableRow, column: DynamicTableColumn, event: Event) { onValueChanged(row: DynamicTableRow, column: DynamicTableColumn, event: any) {
let value: any = (<HTMLInputElement>event.srcElement).value; let value: any = (<HTMLInputElement>event.srcElement).value;
row.value[column.id] = value; row.value[column.id] = value;
} }