mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-31 17:38:48 +00:00
Unit tests
This commit is contained in:
@@ -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');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@@ -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]);
|
||||||
|
@@ -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();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@@ -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');
|
||||||
|
@@ -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]);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@@ -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;
|
||||||
|
@@ -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();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@@ -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);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user