igniteui-angular-sovn
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
1,119 lines (878 loc) • 321 kB
text/typescript
import { DebugElement } from '@angular/core';
import { fakeAsync, TestBed, tick, flush, ComponentFixture } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { IgxInputDirective } from '../../directives/input/input.directive';
import { IgxGridComponent } from './grid.component';
import { UIInteractions, wait } from '../../test-utils/ui-interactions.spec';
import { configureTestSuite } from '../../test-utils/configure-suite';
import {
IgxNumberFilteringOperand,
IgxDateFilteringOperand,
IgxBooleanFilteringOperand,
IgxStringFilteringOperand,
IgxDateTimeFilteringOperand,
IgxTimeFilteringOperand
} from '../../data-operations/filtering-condition';
import { IgxDatePickerComponent } from '../../date-picker/date-picker.component';
import { IgxGridFilteringCellComponent } from '../filtering/base/grid-filtering-cell.component';
import { IgxGridHeaderComponent } from '../headers/grid-header.component';
import { IgxGridFilteringRowComponent } from '../filtering/base/grid-filtering-row.component';
import { GridFunctions, GridSelectionFunctions } from '../../test-utils/grid-functions.spec';
import { IgxBadgeComponent } from '../../badge/badge.component';
import { DefaultSortingStrategy, SortingDirection } from '../../data-operations/sorting-strategy';
import { IgxGridHeaderGroupComponent } from '../headers/grid-header-group.component';
import { changei18n, getCurrentResourceStrings } from '../../core/i18n/resources';
import { DatePipe } from '@angular/common';
import { FilteringExpressionsTree, IFilteringExpressionsTree } from '../../data-operations/filtering-expressions-tree';
import { FilteringLogic, IFilteringExpression } from '../../data-operations/filtering-expression.interface';
import { IgxChipComponent } from '../../chips/chip.component';
import { DisplayDensity } from '../../core/density';
import { SampleTestData } from '../../test-utils/sample-test-data.spec';
import {
IgxGridFilteringComponent,
IgxGridFilteringScrollComponent,
IgxGridFilteringMCHComponent,
IgxGridFilteringTemplateComponent,
IgxGridFilteringESFEmptyTemplatesComponent,
IgxGridFilteringESFTemplatesComponent,
IgxGridFilteringESFLoadOnDemandComponent,
CustomFilteringStrategyComponent,
IgxGridExternalESFComponent,
IgxGridExternalESFTemplateComponent,
IgxGridDatesFilteringComponent,
LoadOnDemandFilterStrategy
} from '../../test-utils/grid-samples.spec';
import { GridSelectionMode, FilterMode } from '../common/enums';
import { ControlsFunction } from '../../test-utils/controls-functions.spec';
import { FilteringStrategy, FormattedValuesFilteringStrategy } from '../../data-operations/filtering-strategy';
import { IgxInputGroupComponent } from '../../input-group/public_api';
import { formatDate } from '../../core/utils';
import { IgxCalendarComponent } from '../../calendar/calendar.component';
const DEBOUNCETIME = 30;
const FILTER_UI_ROW = 'igx-grid-filtering-row';
const FILTER_UI_CELL = 'igx-grid-filtering-cell';
const GRID_RESIZE_CLASS = '.igx-grid-th__resize-line';
describe('IgxGrid - Filtering Row UI actions #grid', () => {
configureTestSuite((() => {
return TestBed.configureTestingModule({
imports: [
NoopAnimationsModule,
IgxGridFilteringComponent,
IgxGridFilteringScrollComponent,
IgxGridFilteringMCHComponent,
IgxGridFilteringTemplateComponent,
IgxGridDatesFilteringComponent
]
});
}));
describe(null, () => {
let fix: ComponentFixture<any>;
let grid: IgxGridComponent;
const today = SampleTestData.today;
beforeEach(fakeAsync(() => {
fix = TestBed.createComponent(IgxGridFilteringComponent);
fix.detectChanges();
grid = fix.componentInstance.grid;
}));
// UI tests string column, empty input
it('UI tests on string column changing conditions', fakeAsync(() => {
GridFunctions.clickFilterCellChip(fix, 'ProductName');
const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW));
const reset = filterUIRow.queryAll(By.css('button'))[0];
const close = filterUIRow.queryAll(By.css('button'))[1];
const input = filterUIRow.query(By.directive(IgxInputDirective));
expect(grid.rowList.length).toEqual(8);
// iterate over not unary conditions when input is empty
// starts with
GridFunctions.openFilterDDAndSelectCondition(fix, 2);
expect(grid.rowList.length).toEqual(8);
verifyFilterRowUI(input, close, reset);
// does not contain
GridFunctions.openFilterDDAndSelectCondition(fix, 1);
expect(grid.rowList.length).toEqual(8);
verifyFilterRowUI(input, close, reset);
// iterate over unary conditions
GridFunctions.openFilterDDAndSelectCondition(fix, 6);
expect(grid.rowList.length).toEqual(4);
verifyFilterRowUI(input, close, reset, false);
GridFunctions.openFilterDDAndSelectCondition(fix, 0);
expect(grid.rowList.length).toEqual(4);
verifyFilterRowUI(input, close, reset, false);
}));
// UI tests string column with value in input
it('UI tests on string column', fakeAsync(() => {
GridFunctions.clickFilterCellChip(fix, 'ProductName');
const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW));
const input = filterUIRow.query(By.directive(IgxInputDirective));
const reset = filterUIRow.queryAll(By.css('button'))[0];
const close = filterUIRow.queryAll(By.css('button'))[1];
expect(grid.rowList.length).toEqual(8);
// iterate over not unary conditions and fill the input
// starts with
GridFunctions.openFilterDDAndSelectCondition(fix, 2);
GridFunctions.typeValueInFilterRowInput('Net', fix, input);
tick();
fix.detectChanges();
verifyFilterUIPosition(filterUIRow, grid);
verifyFilterRowUI(input, close, reset, false);
expect(grid.rowList.length).toEqual(1);
expect(grid.getCellByColumn(0, 'ID').value).toEqual(2);
// ends with
GridFunctions.openFilterDDAndSelectCondition(fix, 3);
GridFunctions.typeValueInFilterRowInput('script', fix, input);
expect(grid.rowList.length).toEqual(2);
verifyFilterRowUI(input, close, reset, false);
// does not contain
GridFunctions.openFilterDDAndSelectCondition(fix, 1);
GridFunctions.typeValueInFilterRowInput('script', fix, input);
verifyFilterRowUI(input, close, reset, false);
expect(grid.rowList.length).toEqual(6);
}));
// UI tests number column
it('UI tests on number column changing conditions', fakeAsync(() => {
GridFunctions.clickFilterCellChip(fix, 'Downloads');
const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW));
let input = filterUIRow.query(By.directive(IgxInputDirective));
const reset = filterUIRow.queryAll(By.css('button'))[0];
const close = filterUIRow.queryAll(By.css('button'))[1];
expect(grid.rowList.length).toEqual(8);
verifyFilterRowUI(input, close, reset);
// does not equal
GridFunctions.openFilterDDAndSelectCondition(fix, 1);
expect(grid.rowList.length).toEqual(8);
verifyFilterRowUI(input, close, reset);
// greater than
GridFunctions.openFilterDDAndSelectCondition(fix, 2);
expect(grid.rowList.length).toEqual(8);
verifyFilterRowUI(input, close, reset);
// iterate over unary conditions
// empty
GridFunctions.openFilterDDAndSelectCondition(fix, 6);
expect(grid.rowList.length).toEqual(1);
verifyFilterRowUI(input, close, reset, false);
// not empty
GridFunctions.openFilterDDAndSelectCondition(fix, 7);
expect(grid.rowList.length).toEqual(7);
verifyFilterRowUI(input, close, reset, false);
// changing from unary to not unary condition when input is empty - filtering should keep its state
// open dropdown
GridFunctions.openFilterDDAndSelectCondition(fix, 0);
input = filterUIRow.query(By.directive(IgxInputDirective));
expect(grid.rowList.length).toEqual(7);
verifyFilterRowUI(input, close, reset, false);
}));
it('UI tests on number column', fakeAsync(() => {
GridFunctions.clickFilterCellChip(fix, 'Downloads');
const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW));
const input = filterUIRow.query(By.directive(IgxInputDirective));
const reset = filterUIRow.queryAll(By.css('button'))[0];
const close = filterUIRow.queryAll(By.css('button'))[1];
// iterate over not unary conditions and fill the input
// does not equal
GridFunctions.openFilterDDAndSelectCondition(fix, 1);
GridFunctions.typeValueInFilterRowInput(100, fix, input);
expect(grid.rowList.length).toEqual(7);
verifyFilterRowUI(input, close, reset, false);
// less than
GridFunctions.openFilterDDAndSelectCondition(fix, 3);
expect(grid.rowList.length).toEqual(3);
verifyFilterRowUI(input, close, reset, false);
// greater than or equal to
GridFunctions.openFilterDDAndSelectCondition(fix, 4);
GridFunctions.typeValueInFilterRowInput(254, fix, input);
expect(grid.rowList.length).toEqual(3);
verifyFilterRowUI(input, close, reset, false);
}));
// UI tests boolean column
it('UI tests on boolean column', fakeAsync(() => {
GridFunctions.clickFilterCellChip(fix, 'Released');
const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW));
const reset = filterUIRow.queryAll(By.css('button'))[0];
const close = filterUIRow.queryAll(By.css('button'))[1];
const input = filterUIRow.query(By.directive(IgxInputDirective));
tick();
expect(grid.rowList.length).toEqual(8);
verifyFilterUIPosition(filterUIRow, grid);
// false condition
GridFunctions.openFilterDDAndSelectCondition(fix, 2);
expect(grid.rowList.length).toEqual(2);
verifyFilterRowUI(input, close, reset, false);
// true condition
GridFunctions.openFilterDDAndSelectCondition(fix, 1);
expect(grid.rowList.length).toEqual(3);
verifyFilterRowUI(input, close, reset, false);
// (all) condition
GridFunctions.openFilterDDAndSelectCondition(fix, 0);
expect(grid.rowList.length).toEqual(8);
verifyFilterRowUI(input, close, reset, false);
// not null condition
GridFunctions.openFilterDDAndSelectCondition(fix, 6);
expect(grid.rowList.length).toEqual(6);
verifyFilterRowUI(input, close, reset, false);
}));
it('UI tests on boolean column open dropdown', fakeAsync(() => {
GridFunctions.clickFilterCellChip(fix, 'Released');
const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW));
const input = filterUIRow.query(By.directive(IgxInputDirective));
const prefix = GridFunctions.getFilterRowPrefix(fix);
input.triggerEventHandler('click', null);
tick(DEBOUNCETIME);
fix.detectChanges();
GridFunctions.verifyFilteringDropDownIsOpened(fix);
UIInteractions.triggerEventHandlerKeyDown(' ', prefix);
tick(DEBOUNCETIME);
fix.detectChanges();
GridFunctions.verifyFilteringDropDownIsOpened(fix, false);
UIInteractions.triggerEventHandlerKeyDown('Enter', input);
tick(DEBOUNCETIME);
fix.detectChanges();
GridFunctions.verifyFilteringDropDownIsOpened(fix);
UIInteractions.triggerEventHandlerKeyDown('Tab', prefix);
tick(DEBOUNCETIME);
fix.detectChanges();
GridFunctions.verifyFilteringDropDownIsOpened(fix, false);
UIInteractions.triggerEventHandlerKeyDown(' ', input);
tick(DEBOUNCETIME);
fix.detectChanges();
GridFunctions.verifyFilteringDropDownIsOpened(fix);
}));
// UI tests date column
it('UI - should correctly filter date column', fakeAsync(() => {
GridFunctions.clickFilterCellChip(fix, 'ReleaseDate');
const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW));
const reset = filterUIRow.queryAll(By.css('button'))[0];
const close = filterUIRow.queryAll(By.css('button'))[1];
const input = filterUIRow.query(By.directive(IgxInputDirective));
const expectedResults = GridFunctions.createDateFilterConditions(grid, today);
// Today condition
GridFunctions.openFilterDDAndSelectCondition(fix, 4);
expect(grid.rowList.length).toEqual(1);
verifyFilterRowUI(input, close, reset, false);
verifyFilterUIPosition(filterUIRow, grid);
expect(grid.rowList.length).toEqual(1);
// This Month condition
GridFunctions.openFilterDDAndSelectCondition(fix, 6);
verifyFilterRowUI(input, close, reset, false);
expect(grid.rowList.length).toEqual(expectedResults[5]);
// Last Month condition
GridFunctions.openFilterDDAndSelectCondition(fix, 7);
verifyFilterRowUI(input, close, reset, false);
expect(grid.rowList.length).toEqual(expectedResults[0]);
// Empty condition
GridFunctions.openFilterDDAndSelectCondition(fix, 12);
verifyFilterRowUI(input, close, reset, false);
expect(grid.rowList.length).toEqual(2);
}));
it('UI - should correctly filter date column by \'equals\' filtering conditions', fakeAsync(() => {
pending('This should be tested in the e2e test');
GridFunctions.clickFilterCellChip(fix, 'ReleaseDate');
const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW));
const input = filterUIRow.query(By.directive(IgxInputDirective));
GridFunctions.openFilterDDAndSelectCondition(fix, 0);
input.triggerEventHandler('click', null);
tick();
fix.detectChanges();
const outlet = document.getElementsByClassName('igx-grid__outlet')[0];
const calendar = outlet.getElementsByClassName('igx-calendar')[0];
const currentDay = calendar.querySelector('.igx-calendar__date--current');
currentDay.dispatchEvent(new Event('click'));
flush();
fix.detectChanges();
input.triggerEventHandler('change', null);
tick();
fix.detectChanges();
expect(grid.rowList.length).toEqual(1);
}));
it('Should correctly select month from month view datepicker/calendar component', fakeAsync(() => {
pending('This should be tested in the e2e test');
const filteringCells = fix.debugElement.queryAll(By.css(FILTER_UI_CELL));
filteringCells[4].query(By.css('igx-chip')).nativeElement.click();
tick();
fix.detectChanges();
const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW));
const filterIcon = filterUIRow.query(By.css('igx-icon'));
const input = filterUIRow.query(By.directive(IgxInputDirective));
filterIcon.nativeElement.click();
tick();
fix.detectChanges();
input.nativeElement.click();
tick();
fix.detectChanges();
const outlet = document.getElementsByClassName('igx-grid__outlet')[0];
let calendar = outlet.getElementsByClassName('igx-calendar')[0];
calendar.querySelector('.igx-calendar__date--current');
const monthView = calendar.querySelector('.igx-calendar-picker__date');
monthView.dispatchEvent(new Event('click'));
tick();
fix.detectChanges();
const firstMonth = calendar.querySelector('.igx-calendar__month');
const firstMonthText = (firstMonth as HTMLElement).innerText;
firstMonth.dispatchEvent(new Event('click'));
tick();
fix.detectChanges();
calendar = outlet.getElementsByClassName('igx-calendar')[0];
const month = calendar.querySelector('.igx-calendar-picker__date');
expect(month.innerHTML.trim()).toEqual(firstMonthText);
}));
it('Should correctly select year from year view datepicker/calendar component', fakeAsync(() => {
pending('This should be tested in the e2e test');
const filteringCells = fix.debugElement.queryAll(By.css(FILTER_UI_CELL));
filteringCells[4].query(By.css('igx-chip')).nativeElement.click();
tick();
fix.detectChanges();
const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW));
const filterIcon = filterUIRow.query(By.css('igx-icon'));
const input = filterUIRow.query(By.directive(IgxInputDirective));
filterIcon.nativeElement.click();
tick();
fix.detectChanges();
input.nativeElement.click();
tick();
fix.detectChanges();
const outlet = document.getElementsByClassName('igx-grid__outlet')[0];
let calendar = outlet.getElementsByClassName('igx-calendar')[0];
const monthView = calendar.querySelectorAll('.igx-calendar-picker__date')[1];
monthView.dispatchEvent(new Event('click'));
tick();
fix.detectChanges();
const firstMonth = calendar.querySelectorAll('.igx-calendar__year')[0];
firstMonth.dispatchEvent(new Event('click'));
tick();
fix.detectChanges();
calendar = outlet.getElementsByClassName('igx-calendar')[0];
const month = calendar.querySelectorAll('.igx-calendar-picker__date')[1];
const expectedResult = today.getFullYear() - 3;
expect(month.innerHTML.trim()).toEqual(expectedResult.toString());
}));
// UI tests custom column
it('UI tests on custom column', fakeAsync(() => {
GridFunctions.clickFilterCellChip(fix, 'AnotherField');
const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW));
const input = filterUIRow.query(By.directive(IgxInputDirective));
const reset = filterUIRow.queryAll(By.css('button'))[0];
const close = filterUIRow.queryAll(By.css('button'))[1];
GridFunctions.typeValueInFilterRowInput('a', fix, input);
expect(grid.rowList.length).toEqual(1);
expect(grid.getCellByColumn(0, 'AnotherField').value).toMatch('custom');
verifyFilterRowUI(input, close, reset, false);
}));
it('Removing second condition removes the And/Or button', fakeAsync(() => {
const filteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And, 'ProductName');
const expression = {
fieldName: 'ProductName',
searchVal: 'g',
condition: IgxStringFilteringOperand.instance().condition('contains')
};
const expression1 = {
fieldName: 'ProductName',
searchVal: 'I',
condition: IgxStringFilteringOperand.instance().condition('contains')
};
filteringExpressionsTree.filteringOperands.push(expression);
filteringExpressionsTree.filteringOperands.push(expression1);
grid.filter('ProductName', null, filteringExpressionsTree);
fix.detectChanges();
GridFunctions.clickFilterCellChip(fix, 'ProductName');
const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW));
verifyFilterUIPosition(filterUIRow, grid);
expect(grid.rowList.length).toEqual(2);
let andButton = fix.debugElement.queryAll(By.css('#operand'));
expect(andButton.length).toEqual(1);
// remove the second chip
const secondChip = filterUIRow.queryAll(By.css('igx-chip'))[1];
ControlsFunction.clickChipRemoveButton(secondChip.nativeElement);
tick();
fix.detectChanges();
expect(grid.rowList.length).toEqual(3);
andButton = fix.debugElement.queryAll(By.css('#operand'));
expect(andButton.length).toEqual(0);
}));
it('When filter column with value 0 and dataType number, filtering chip should be applied', fakeAsync(() => {
GridFunctions.clickFilterCellChip(fix, 'Downloads');
GridFunctions.typeValueInFilterRowInput(0, fix);
GridFunctions.closeFilterRow(fix);
const gridheaders = fix.debugElement.queryAll(By.css('igx-grid-header'));
const headerOfTypeNumber = gridheaders.find(gh => gh.nativeElement.classList.contains('igx-grid-th--number'));
const filterCellsForTypeNumber = headerOfTypeNumber.parent.query(By.css(FILTER_UI_CELL));
expect(filterCellsForTypeNumber.queryAll(By.css('.igx-filtering-chips')).length).toBe(1);
}));
it('Should correctly create FilteringExpressionsTree and populate filterUI.', fakeAsync(() => {
const filteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And, 'ProductName');
const expression = {
fieldName: 'ProductName',
searchVal: 'Ignite',
condition: IgxStringFilteringOperand.instance().condition('startsWith')
};
filteringExpressionsTree.filteringOperands.push(expression);
grid.filteringExpressionsTree = filteringExpressionsTree;
fix.detectChanges();
expect(grid.rowList.length).toEqual(2);
GridFunctions.clickFilterCellChip(fix, 'ProductName');
GridFunctions.openFilterDD(fix.debugElement);
fix.detectChanges();
const filterUIContainer = fix.debugElement.queryAll(By.css(FILTER_UI_ROW))[0];
const input = filterUIContainer.query(By.directive(IgxInputDirective));
expect(ControlsFunction.getDropDownSelectedItem(filterUIContainer).nativeElement.textContent).toMatch('Starts With');
expect(input.nativeElement.value).toMatch('Ignite');
}));
it('Should complete the filter when clicking the commit icon', fakeAsync(() => {
const filterValue = 'an';
GridFunctions.clickFilterCellChip(fix, 'ProductName');
GridFunctions.typeValueInFilterRowInput(filterValue, fix);
const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW));
const filterChip = filterUIRow.query(By.directive(IgxChipComponent));
expect(filterChip).toBeTruthy();
expect(filterChip.componentInstance.selected).toBeTruthy();
grid.filteringRow.onCommitClick();
tick(100);
fix.detectChanges();
expect(filterChip.componentInstance.selected).toBeFalsy();
}));
it('Should complete the filter when focusing out of the input', fakeAsync(() => {
const filterValue = 'an';
GridFunctions.clickFilterCellChip(fix, 'ProductName');
tick(16); // onConditionsChanged rAF
GridFunctions.typeValueInFilterRowInput(filterValue, fix);
const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW));
const filterChip = filterUIRow.query(By.directive(IgxChipComponent));
expect(filterChip).toBeTruthy();
expect(filterChip.componentInstance.selected).toBeTruthy();
grid.nativeElement.focus();
fix.detectChanges();
tick(100);
expect(filterChip.componentInstance.selected).toBeFalsy();
}));
it('UI - should use dropdown mode for the date picker', fakeAsync(() => {
GridFunctions.clickFilterCellChip(fix, 'ReleaseDate');
const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW));
const datePicker = filterUIRow.query(By.css('igx-date-picker'));
expect(datePicker.componentInstance.mode).toBe('dropdown');
}));
it('Should not select all filter chips when switching columns', fakeAsync(() => {
const filteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And, 'ProductName');
const expression = {
fieldName: 'ProductName',
searchVal: 'Ignite',
condition: IgxStringFilteringOperand.instance().condition('startsWith')
};
const expression1 = {
fieldName: 'ProductName',
searchVal: 'Angular',
condition: IgxStringFilteringOperand.instance().condition('contains')
};
filteringExpressionsTree.filteringOperands.push(expression);
filteringExpressionsTree.filteringOperands.push(expression1);
grid.filter('ProductName', null, filteringExpressionsTree);
fix.detectChanges();
GridFunctions.clickFilterCellChip(fix, 'Downloads');
const columnProductName = GridFunctions.getColumnHeader('ProductName', fix);
columnProductName.triggerEventHandler('click', { stopPropagation: () => { } });
fix.detectChanges();
const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW));
const filterChips = filterUIRow.queryAll(By.directive(IgxChipComponent));
const input = filterUIRow.query(By.directive(IgxInputDirective));
expect(filterChips.length).toEqual(2);
expect(filterChips[0].componentInstance.selected).toBeFalsy();
expect(filterChips[1].componentInstance.selected).toBeFalsy();
expect(input.nativeElement.value).toMatch('');
}));
it('should render Filter chip for filterable columns and render empty cell for a column when filterable is set to false',
fakeAsync(() => {
grid.width = '1500px';
fix.detectChanges();
const filteringCells = GridFunctions.getFilteringCells(fix);
const filteringChips = GridFunctions.getFilteringChips(fix);
expect(filteringCells.length).toBe(8);
expect(filteringChips.length).toBe(7);
let idCellChips = GridFunctions.getFilteringChipPerIndex(fix, 0);
expect(idCellChips.length).toBe(0);
grid.getColumnByName('ID').filterable = true;
fix.detectChanges();
// tick(100);
idCellChips = GridFunctions.getFilteringChipPerIndex(fix, 0);
expect(idCellChips.length).toBe(1);
}));
it('should render correct input and dropdown in filter row for different column types',
fakeAsync(/** showHideArrowButtons rAF */() => {
pending('This should be tested in the e2e test');
const filteringCells = fix.debugElement.queryAll(By.css(FILTER_UI_CELL));
const stringCellChip = filteringCells[1].query(By.css('igx-chip'));
const numberCellChip = filteringCells[2].query(By.css('igx-chip'));
const boolCellChip = filteringCells[3].query(By.css('igx-chip'));
const dateCellChip = filteringCells[4].query(By.css('igx-chip'));
// open for string
stringCellChip.triggerEventHandler('click', null);
fix.detectChanges();
checkUIForType('string', fix.debugElement);
// close
let filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW));
let close = filterUIRow.queryAll(By.css('button'))[1];
close.nativeElement.click();
fix.detectChanges();
// open for number
numberCellChip.nativeElement.click();
fix.detectChanges();
checkUIForType('number', fix.debugElement);
// close
filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW));
close = filterUIRow.queryAll(By.css('button'))[1];
close.nativeElement.click();
fix.detectChanges();
// open for date
dateCellChip.nativeElement.click();
fix.detectChanges();
checkUIForType('date', fix.debugElement);
// close
filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW));
close = filterUIRow.queryAll(By.css('button'))[1];
close.nativeElement.click();
fix.detectChanges();
// open for bool
boolCellChip.nativeElement.click();
fix.detectChanges();
checkUIForType('bool', fix.debugElement);
// close
filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW));
close = filterUIRow.queryAll(By.css('button'))[1];
close.nativeElement.click();
fix.detectChanges();
}));
it('should apply multiple conditions to grid immediately while the filter row is still open', fakeAsync(() => {
pending('This should be tested in the e2e test');
const filteringCells = fix.debugElement.queryAll(By.css(FILTER_UI_CELL));
const stringCellChip = filteringCells[1].query(By.css('igx-chip'));
const numberCellChip = filteringCells[2].query(By.css('igx-chip'));
const boolCellChip = filteringCells[3].query(By.css('igx-chip'));
const dateCellChip = filteringCells[4].query(By.css('igx-chip'));
// open for string
stringCellChip.nativeElement.click();
fix.detectChanges();
GridFunctions.filterBy('Starts With', 'I', fix);
expect(grid.rowList.length).toEqual(2);
GridFunctions.filterBy('Ends With', 'r', fix);
expect(grid.rowList.length).toEqual(1);
// Reset and Close
GridFunctions.resetFilterRow(fix);
GridFunctions.closeFilterRow(fix);
// open for number
numberCellChip.nativeElement.click();
fix.detectChanges();
GridFunctions.filterBy('Less Than', '100', fix);
expect(grid.rowList.length).toEqual(3);
GridFunctions.filterBy('Greater Than', '10', fix);
expect(grid.rowList.length).toEqual(1);
// Reset and Close
GridFunctions.resetFilterRow(fix);
GridFunctions.closeFilterRow(fix);
// open for bool
boolCellChip.nativeElement.click();
fix.detectChanges();
GridFunctions.filterBy('False', '', fix);
expect(grid.rowList.length).toEqual(2);
GridFunctions.filterBy('Empty', '', fix);
expect(grid.rowList.length).toEqual(3);
// Reset and Close
GridFunctions.resetFilterRow(fix);
GridFunctions.closeFilterRow(fix);
// open for date
dateCellChip.nativeElement.click();
fix.detectChanges();
GridFunctions.filterBy('Today', '', fix);
expect(grid.rowList.length).toEqual(1);
GridFunctions.filterBy('Null', '', fix);
expect(grid.rowList.length).toEqual(0);
}));
it('should render navigation arrows in the filtering row when chips don\'t fit.', fakeAsync(() => {
const filteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And, 'ProductName');
for (let i = 0; i < 10; i++) {
const expression = {
fieldName: 'ProductName',
searchVal: 'I',
condition: IgxStringFilteringOperand.instance().condition('startsWith')
};
filteringExpressionsTree.filteringOperands.push(expression);
}
grid.filter('ProductName', null, filteringExpressionsTree);
fix.detectChanges();
GridFunctions.clickFilterCellChip(fix, 'ProductName');
tick(500);
fix.detectChanges();
expect(GridFunctions.getFilterRowLeftArrowButton(fix)).not.toBe(null);
expect(GridFunctions.getFilterRowRightArrowButton(fix)).not.toBe(null);
}));
it('should update UI when chip is removed from filter row.', fakeAsync(() => {
grid.filter('ProductName', 'I', IgxStringFilteringOperand.instance().condition('startsWith'));
fix.detectChanges();
expect(grid.rowList.length).toEqual(2);
GridFunctions.clickFilterCellChip(fix, 'ProductName');
// remove from row
const filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW));
GridFunctions.removeFilterChipByIndex(0, filterUIRow);
tick(100);
fix.detectChanges();
expect(grid.rowList.length).toEqual(8);
}));
it('should not render chip in header if condition that requires value is applied and then value is cleared in filter row.',
fakeAsync(() => {
grid.filter('ProductName', 'I', IgxStringFilteringOperand.instance().condition('startsWith'));
fix.detectChanges();
GridFunctions.clickFilterCellChip(fix, 'ProductName');
tick(100);
fix.detectChanges();
const clearButton = GridFunctions.getFilterRowInputClearIcon(fix);
clearButton.triggerEventHandler('click', null);
tick(100);
fix.detectChanges();
GridFunctions.closeFilterRow(fix);
tick(100);
fix.detectChanges();
// check no condition is applied
expect(grid.rowList.length).toEqual(8);
const filteringChips = GridFunctions.getFilteringChips(fix);
expect(GridFunctions.getChipText(filteringChips[1])).toEqual('Filter');
}));
it('should reset the filter chips area when changing grid width', fakeAsync(() => {
grid.width = '300px';
fix.detectChanges();
tick(100);
const filteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And, 'ProductName');
const expression1 = {
fieldName: 'ProductName',
searchVal: 'Ignite',
condition: IgxStringFilteringOperand.instance().condition('startsWith')
};
const expression2 = {
fieldName: 'ProductName',
searchVal: 'test',
condition: IgxStringFilteringOperand.instance().condition('contains')
};
filteringExpressionsTree.filteringOperands.push(expression1);
filteringExpressionsTree.filteringOperands.push(expression2);
grid.filter('ProductName', null, filteringExpressionsTree);
fix.detectChanges();
GridFunctions.clickFilterCellChip(fix, 'ProductName');
tick(100);
fix.detectChanges();
expect(GridFunctions.getFilterRowLeftArrowButton(fix)).not.toBeNull();
expect(GridFunctions.getFilterRowRightArrowButton(fix)).not.toBeNull();
grid.width = '900px';
fix.detectChanges();
tick(200);
expect(GridFunctions.getFilterRowLeftArrowButton(fix)).toBeNull();
expect(GridFunctions.getFilterRowRightArrowButton(fix)).toBeNull();
}));
it('Should correctly update filtering row rendered when changing current column by clicking on a header.', fakeAsync(() => {
pending('This should be tested in the e2e test');
const headers = fix.debugElement.queryAll(By.directive(IgxGridHeaderComponent));
const numberHeader = headers[2];
const boolHeader = headers[3];
const dateHeader = headers[4];
const initialChips = fix.debugElement.queryAll(By.directive(IgxChipComponent));
const stringCellChip = initialChips[0].nativeElement;
stringCellChip.click();
fix.detectChanges();
checkUIForType('string', fix.debugElement);
// Click on number column.
numberHeader.nativeElement.click();
fix.detectChanges();
checkUIForType('number', fix.debugElement);
// Click on boolean column
boolHeader.nativeElement.click();
fix.detectChanges();
checkUIForType('bool', fix.debugElement);
// Click on date column
dateHeader.nativeElement.click();
fix.detectChanges();
checkUIForType('date', fix.debugElement);
}));
it('Should correctly render read-only input when selecting read-only condition and should create a chip.', fakeAsync(() => {
GridFunctions.clickFilterCellChip(fix, 'ProductName');
GridFunctions.openFilterDD(fix.debugElement);
fix.detectChanges();
const filteringRow = fix.debugElement.query(By.directive(IgxGridFilteringRowComponent));
const dropdownList = fix.debugElement.query(By.css('div.igx-drop-down__list-scroll'));
const input = filteringRow.query(By.directive(IgxInputDirective));
GridFunctions.selectFilteringCondition('Empty', dropdownList);
fix.detectChanges();
const chips = filteringRow.queryAll(By.directive(IgxChipComponent));
expect(chips.length).toEqual(1);
expect(chips[0].componentInstance.selected).toBeTruthy();
expect(GridFunctions.getChipText(chips[0])).toEqual('Empty');
expect(input.properties.readOnly).toBeTruthy();
}));
it('Should focus input .', fakeAsync(() => {
GridFunctions.clickFilterCellChip(fix, 'ProductName');
// Open dropdown
GridFunctions.openFilterDD(fix.debugElement);
fix.detectChanges();
const filteringRow = fix.debugElement.query(By.directive(IgxGridFilteringRowComponent));
const dropdownList = fix.debugElement.query(By.css('div.igx-drop-down__list-scroll'));
const input = filteringRow.query(By.directive(IgxInputDirective));
// Select condition with input
GridFunctions.selectFilteringCondition('Contains', dropdownList);
// Check focus is kept
expect(document.activeElement).toEqual(input.nativeElement);
// Set input and confirm
GridFunctions.typeValueInFilterRowInput('a', fix, input);
// Check a chip is created after input and is marked as selected.
const filterChip = filteringRow.query(By.directive(IgxChipComponent));
expect(filterChip).toBeTruthy();
expect(filterChip.componentInstance.selected).toBeTruthy();
expect(input.componentInstance.value).toEqual('a');
UIInteractions.triggerEventHandlerKeyDown('Enter', input);
fix.detectChanges();
// Check focus is kept and chips is no longer selected.
expect(filterChip.componentInstance.selected).toBeFalsy();
expect(grid.rowList.length).toEqual(3);
expect(document.activeElement).toEqual(input.nativeElement);
expect(input.componentInstance.value).toEqual(null);
GridFunctions.clickChip(filterChip);
fix.detectChanges();
expect(document.activeElement).toEqual(input.nativeElement);
expect(input.componentInstance.value).toEqual('a');
expect(filterChip.componentInstance.selected).toBeTruthy();
}));
it('should update UI when filtering via the API.', fakeAsync(() => {
grid.width = '1600px';
grid.columnList.get(1).width = '400px';
fix.detectChanges();
const filteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And, 'ProductName');
const expression = {
fieldName: 'ProductName',
searchVal: 'Ignite',
condition: IgxStringFilteringOperand.instance().condition('startsWith')
};
const expression1 = {
fieldName: 'ProductName',
searchVal: 'Angular',
condition: IgxStringFilteringOperand.instance().condition('contains')
};
filteringExpressionsTree.filteringOperands.push(expression);
filteringExpressionsTree.filteringOperands.push(expression1);
grid.filter('ProductName', null, filteringExpressionsTree);
grid.filter('Released', true, IgxBooleanFilteringOperand.instance().condition('false'));
fix.detectChanges();
expect(grid.rowList.length).toEqual(0);
const filteringCells = GridFunctions.getFilteringCells(fix);
const stringCellChips = filteringCells[1].queryAll(By.css('igx-chip'));
const boolCellChips = filteringCells[3].queryAll(By.css('igx-chip'));
const strConnector = filteringCells[1].query(By.css('.igx-filtering-chips__connector'));
expect(strConnector.nativeElement.textContent.trim()).toBe('And');
expect(stringCellChips.length).toBe(2);
expect(boolCellChips.length).toBe(1);
expect(GridFunctions.getChipText(stringCellChips[0])).toBe('Ignite');
expect(GridFunctions.getChipText(stringCellChips[1])).toBe('Angular');
expect(GridFunctions.getChipText(boolCellChips[0])).toBe('False');
}));
it('should display view more icon in filter cell if chips don\'t fit in the cell.', fakeAsync(() => {
grid.columnList.get(1).width = '200px';
fix.detectChanges();
const filteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And, 'ProductName');
const expression = {
fieldName: 'ProductName',
searchVal: 'Ignite',
condition: IgxStringFilteringOperand.instance().condition('startsWith')
};
const expression1 = {
fieldName: 'ProductName',
searchVal: 'for',
condition: IgxStringFilteringOperand.instance().condition('contains')
};
filteringExpressionsTree.filteringOperands.push(expression);
filteringExpressionsTree.filteringOperands.push(expression1);
grid.filter('ProductName', null, filteringExpressionsTree);
fix.detectChanges();
// check 1 chip and view more icon is displayed.
const chips = GridFunctions.getFilterChipsForColumn('ProductName', fix);
expect(chips.length).toEqual(1);
const fcIndicator = GridFunctions.getFilterIndicatorForColumn('ProductName', fix);
const indicatorBadge = fcIndicator[0].query(By.directive(IgxBadgeComponent));
expect(indicatorBadge).toBeTruthy();
expect(indicatorBadge.nativeElement.innerText.trim()).toEqual('1');
}));
it('should select chip when open it from filter cell', fakeAsync(() => {
grid.filter('ProductName', 'Ignite', IgxStringFilteringOperand.instance().condition('startsWith'));
fix.detectChanges();
GridFunctions.clickFilterCellChipUI(fix, 'ProductName');
tick(100);
fix.detectChanges();
const filteringRow = fix.debugElement.query(By.directive(IgxGridFilteringRowComponent));
const filterChip = filteringRow.query(By.directive(IgxChipComponent));
const input = filteringRow.query(By.directive(IgxInputDirective));
expect(filterChip).toBeTruthy();
expect(filterChip.componentInstance.selected).toBeTruthy();
expect(input.componentInstance.value).toEqual('Ignite');
}));
it('Should allow setting filtering conditions through filteringExpressionsTree.', fakeAsync(() => {
grid.columnList.get(1).width = '200px';
fix.detectChanges();
// Add initial filtering conditions
const gridFilteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And);
const columnsFilteringTree = new FilteringExpressionsTree(FilteringLogic.And, 'ProductName');
columnsFilteringTree.filteringOperands = [
{ fieldName: 'ProductName', searchVal: 'a', condition: IgxStringFilteringOperand.instance().condition('contains') },
{ fieldName: 'ProductName', searchVal: 'o', condition: IgxStringFilteringOperand.instance().condition('contains') }
];
gridFilteringExpressionsTree.filteringOperands.push(columnsFilteringTree);
grid.filteringExpressionsTree = gridFilteringExpressionsTree;
fix.detectChanges();
const colChips = GridFunctions.getFilterChipsForColumn('ProductName', fix);
const colOperands = GridFunctions.getFilterOperandsForColumn('ProductName', fix);
const colIndicator = GridFunctions.getFilterIndicatorForColumn('ProductName', fix);
expect(grid.rowList.length).toEqual(2);
expect(colChips.length).toEqual(1);
expect(GridFunctions.getChipText(colChips[0])).toEqual('a');
expect(colOperands.length).toEqual(0);
const indicatorBadge = colIndicator[0].query(By.directive(IgxBadgeComponent));
expect(indicatorBadge).toBeTruthy();
expect(indicatorBadge.nativeElement.innerText.trim()).toEqual('1');
}));
it('Should close FilterRow when Escape is pressed.', fakeAsync(() => {
GridFunctions.clickFilterCellChip(fix, 'ProductName');
let filteringRow = fix.debugElement.query(By.directive(IgxGridFilteringRowComponent));
UIInteractions.triggerKeyDownEvtUponElem('Escape', filteringRow.nativeElement, true);
tick(100);
fix.detectChanges();
filteringRow = fix.debugElement.query(By.directive(IgxGridFilteringRowComponent));
expect(filteringRow).toBeNull();
}));
it('Should correctly load default resource strings for filter row', fakeAsync(() => {
GridFunctions.clickFilterCellChip(fix, 'ProductName');
const filteringRow = fix.debugElement.query(By.directive(IgxGridFilteringRowComponent));
expect(filteringRow).toBeDefined();
const editingBtns = filteringRow.query(By.css('.igx-grid__filtering-row-editing-buttons'));
const reset = editingBtns.queryAll(By.css('button'))[0];
expect(reset.nativeElement.childNodes[1].textContent.trim()).toBe('Reset');
}));
it('Should correctly change resource strings for filter row using Changei18n.', fakeAsync(() => {
fix = TestBed.createComponent(IgxGridFilteringComponent);
const strings = getCurrentResourceStrings();
strings.igx_grid_filter = 'My filter';
strings.igx_grid_filter_row_close = 'My close';
changei18n(strings);
fix.detectChanges();
const initialChips = GridFunctions.getFilteringChips(fix);
expect(GridFunctions.getChipText(initialChips[0])).toBe('My filter');
GridFunctions.clickFilterCellChip(fix, 'ProductName');
const filteringRow = fix.debugElement.query(By.directive(IgxGridFilteringRowComponent));
expect(filteringRow).toBeDefined();
const editingBtns = filteringRow.query(By.css('.igx-grid__filtering-row-editing-buttons'));
const reset = editingBtns.queryAll(By.css('button'))[0];
const close = editingBtns.queryAll(By.css('button'))[1];
expect(close.nativeElement.childNodes[1].textContent.trim()).toBe('My close');
expect(reset.nativeElement.childNodes[1].textContent.trim()).toBe('Reset');
changei18n({
igx_grid_filter: 'Filter',
igx_grid_filter_row_close: 'Close'
});
}));
it('Should correctly change resource strings for filter row.', fakeAsync(() => {
fix = TestBed.createComponent(IgxGridFilteringComponent);
grid = fix.componentInstance.grid;
grid.resourceStrings = Object.assign({}, grid.resourceStrings, {
igx_grid_filter: 'My filter',
igx_grid_filter_row_close: 'My close'
});
fix.detectChanges();
const initialChips = G