UNPKG

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
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