UNPKG

igniteui-angular-sovn

Version:

Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps

1,159 lines (984 loc) 51.5 kB
import { TestBed, fakeAsync, tick } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { FilteringLogic, IFilteringExpression } from '../../data-operations/filtering-expression.interface'; import { IgxGridComponent } from './grid.component'; import { configureTestSuite } from '../../test-utils/configure-suite'; import { IgxChipComponent } from '../../chips/public_api'; import { IgxStringFilteringOperand, IgxNumberFilteringOperand, IgxBooleanFilteringOperand, IgxDateFilteringOperand, IgxTimeFilteringOperand, IgxDateTimeFilteringOperand } from '../../data-operations/filtering-condition'; import { FilteringExpressionsTree } from '../../data-operations/filtering-expressions-tree'; import { SampleTestData } from '../../test-utils/sample-test-data.spec'; import { GridFunctions, GridSummaryFunctions } from '../../test-utils/grid-functions.spec'; import { IgxGridFilteringComponent, CustomFilter, IgxGridFilteringBindingComponent } from '../../test-utils/grid-samples.spec'; import { NoopFilteringStrategy } from '../../data-operations/filtering-strategy'; import { ExpressionUI } from '../filtering/excel-style/common'; describe('IgxGrid - Filtering actions #grid', () => { configureTestSuite((() => { return TestBed.configureTestingModule({ imports: [ IgxGridFilteringComponent, NoopAnimationsModule ] }); })); let fix; let grid; beforeEach(fakeAsync(() => { fix = TestBed.createComponent(IgxGridFilteringComponent); fix.detectChanges(); grid = fix.componentInstance.grid; })); it('should correctly filter by \'string\' filtering conditions', fakeAsync(() => { // Contains filter grid.filter('ProductName', 'Ignite', IgxStringFilteringOperand.instance().condition('contains'), true); fix.detectChanges(); expect(grid.rowList.length).toEqual(2); expect(grid.getCellByColumn(0, 'ID').value).toEqual(1); expect(grid.getCellByColumn(1, 'ID').value).toEqual(3); // Clear filtering grid.clearFilter('ProductName'); fix.detectChanges(); expect(grid.rowList.length).toEqual(8); // StartsWith filter grid.filter('ProductName', 'Net', IgxStringFilteringOperand.instance().condition('startsWith'), true); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); expect(grid.getCellByColumn(0, 'ID').value).toEqual(2); // EndsWith filter grid.clearFilter('ProductName'); fix.detectChanges(); grid.filter('ProductName', 'Script', IgxStringFilteringOperand.instance().condition('endsWith'), true); fix.detectChanges(); expect(grid.rowList.length).toEqual(2); // DoesNotContain filter grid.clearFilter('ProductName'); fix.detectChanges(); grid.filter('ProductName', 'Ignite', IgxStringFilteringOperand.instance().condition('doesNotContain'), true); fix.detectChanges(); expect(grid.rowList.length).toEqual(6); // Equals filter grid.clearFilter('ProductName'); fix.detectChanges(); grid.filter('ProductName', 'NetAdvantage', IgxStringFilteringOperand.instance().condition('equals'), true); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); // DoesNotEqual filter grid.clearFilter('ProductName'); fix.detectChanges(); grid.filter('ProductName', 'NetAdvantage', IgxStringFilteringOperand.instance().condition('doesNotEqual'), true); fix.detectChanges(); expect(grid.rowList.length).toEqual(7); // Null filter grid.clearFilter('ProductName'); fix.detectChanges(); grid.filter('ProductName', null, IgxStringFilteringOperand.instance().condition('null'), true); fix.detectChanges(); expect(grid.rowList.length).toEqual(3); // NotNull filter grid.clearFilter('ProductName'); fix.detectChanges(); grid.filter('ProductName', null, IgxStringFilteringOperand.instance().condition('notNull'), true); fix.detectChanges(); expect(grid.rowList.length).toEqual(5); // Empty filter grid.clearFilter('ProductName'); fix.detectChanges(); grid.filter('ProductName', null, IgxStringFilteringOperand.instance().condition('empty'), true); fix.detectChanges(); expect(grid.rowList.length).toEqual(4); // NotEmpty filter grid.clearFilter('ProductName'); fix.detectChanges(); grid.filter('ProductName', null, IgxStringFilteringOperand.instance().condition('notEmpty'), true); fix.detectChanges(); expect(grid.rowList.length).toEqual(4); // Ignorecase filter 'false' grid.clearFilter('ProductName'); fix.detectChanges(); grid.filter('ProductName', 'Ignite UI for Angular', IgxStringFilteringOperand.instance().condition('equals'), false); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); // Custom Filter grid.clearFilter('ProductName'); fix.detectChanges(); grid.filter('AnotherField', '', CustomFilter.instance().condition('custom'), false); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); })); it('should correctly filter by \'number\' filtering conditions', fakeAsync(() => { // DoesNotEqual filter grid.filter('Downloads', 254, IgxNumberFilteringOperand.instance().condition('doesNotEqual')); fix.detectChanges(); expect(grid.rowList.length).toEqual(7); // Equal filter grid.clearFilter('Downloads'); fix.detectChanges(); expect(grid.rowList.length).toEqual(8); grid.filter('Downloads', 127, IgxNumberFilteringOperand.instance().condition('equals'), true); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); // GreaterThan filter grid.clearFilter('Downloads'); fix.detectChanges(); grid.filter('Downloads', 100, IgxNumberFilteringOperand.instance().condition('greaterThan'), true); fix.detectChanges(); expect(grid.rowList.length).toEqual(4); // LessThan filter grid.clearFilter('Downloads'); fix.detectChanges(); grid.filter('Downloads', 100, IgxNumberFilteringOperand.instance().condition('lessThan'), true); fix.detectChanges(); expect(grid.rowList.length).toEqual(3); // GreaterThanOrEqualTo filter grid.clearFilter('Downloads'); fix.detectChanges(); grid.filter('Downloads', 100, IgxNumberFilteringOperand.instance().condition('greaterThanOrEqualTo'), true); fix.detectChanges(); expect(grid.rowList.length).toEqual(5); // LessThanOrEqualTo filter grid.clearFilter('Downloads'); fix.detectChanges(); grid.filter('Downloads', 20, IgxNumberFilteringOperand.instance().condition('lessThanOrEqualTo'), true); fix.detectChanges(); expect(grid.rowList.length).toEqual(3); // Null filter grid.clearFilter('Downloads'); fix.detectChanges(); grid.filter('Downloads', null, IgxNumberFilteringOperand.instance().condition('null'), true); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); // NotNull filter grid.clearFilter('Downloads'); fix.detectChanges(); grid.filter('Downloads', null, IgxNumberFilteringOperand.instance().condition('notNull'), true); fix.detectChanges(); expect(grid.rowList.length).toEqual(7); // Empty filter grid.clearFilter('Downloads'); fix.detectChanges(); grid.filter('Downloads', null, IgxNumberFilteringOperand.instance().condition('empty'), true); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); // NotEmpty filter grid.clearFilter('Downloads'); fix.detectChanges(); grid.filter('Downloads', null, IgxNumberFilteringOperand.instance().condition('notEmpty'), true); fix.detectChanges(); expect(grid.rowList.length).toEqual(7); })); it('should correctly filter by \'boolean\' filtering conditions', fakeAsync(() => { // Empty filter grid.filter('Released', null, IgxBooleanFilteringOperand.instance().condition('empty')); fix.detectChanges(); expect(grid.rowList.length).toEqual(3); // False filter grid.clearFilter('Released'); fix.detectChanges(); expect(grid.rowList.length).toEqual(8); grid.filter('Released', null, IgxBooleanFilteringOperand.instance().condition('false')); fix.detectChanges(); expect(grid.rowList.length).toEqual(2); // True filter grid.clearFilter('Released'); fix.detectChanges(); grid.filter('Released', null, IgxBooleanFilteringOperand.instance().condition('true')); fix.detectChanges(); expect(grid.rowList.length).toEqual(3); // NotEmpty filter grid.clearFilter('Released'); fix.detectChanges(); grid.filter('Released', null, IgxBooleanFilteringOperand.instance().condition('notEmpty')); fix.detectChanges(); expect(grid.rowList.length).toEqual(5); // NotNull filter grid.clearFilter('Released'); fix.detectChanges(); grid.filter('Released', null, IgxBooleanFilteringOperand.instance().condition('notNull')); fix.detectChanges(); expect(grid.rowList.length).toEqual(6); // Null filter grid.clearFilter('Released'); fix.detectChanges(); grid.filter('Released', null, IgxBooleanFilteringOperand.instance().condition('null')); fix.detectChanges(); expect(grid.rowList.length).toEqual(2); })); it('should correctly filter by \'date\' filtering conditions', fakeAsync(() => { const cal = SampleTestData.timeGenerator; const today = SampleTestData.today; // Fill expected results based on the current date const expectedResults = GridFunctions.createDateFilterConditions(grid, today); // After filter grid.filter('ReleaseDate', cal.timedelta(today, 'day', 4), IgxDateFilteringOperand.instance().condition('after')); fix.detectChanges(); expect(grid.rowList.length).toEqual(2); // Before filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); expect(grid.rowList.length).toEqual(8); grid.filter('ReleaseDate', cal.timedelta(today, 'day', 4), IgxDateFilteringOperand.instance().condition('before')); fix.detectChanges(); expect(grid.rowList.length).toEqual(4); // DoesNotEqual filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', cal.timedelta(today, 'day', 15), IgxDateFilteringOperand.instance().condition('doesNotEqual')); fix.detectChanges(); expect(grid.rowList.length).toEqual(7); // Equals filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', cal.timedelta(today, 'day', 15), IgxDateFilteringOperand.instance().condition('equals')); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); // LastMonth filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('lastMonth')); fix.detectChanges(); expect(grid.rowList.length).toEqual(expectedResults[0]); // NextMonth filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('nextMonth')); fix.detectChanges(); expect(grid.rowList.length).toEqual(expectedResults[1]); // ThisYear filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('thisYear')); fix.detectChanges(); expect(grid.rowList.length).toEqual(expectedResults[2]); // LastYear filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('lastYear')); fix.detectChanges(); expect(grid.rowList.length).toEqual(expectedResults[4]); // NextYear filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('nextYear')); fix.detectChanges(); expect(grid.rowList.length).toEqual(expectedResults[3]); // Null filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('null')); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); // NotNull filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('notNull')); fix.detectChanges(); expect(grid.rowList.length).toEqual(7); // Empty filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('empty')); fix.detectChanges(); expect(grid.rowList.length).toEqual(2); // NotEmpty filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('notEmpty')); fix.detectChanges(); expect(grid.rowList.length).toEqual(6); // Today filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('today')); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); // Yesterday filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('yesterday')); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); })); it('should correctly filter by \'time\' filtering conditions', fakeAsync(() => { const cal = SampleTestData.timeGenerator; const today = SampleTestData.todayFullDate; // At, Not At, Before, After, At or Before // At or After, Empty, Not Empty, Null, Not Null // At 11:15:35 grid.filter('ReleaseTime', cal.timedelta(today, 'hour', 1), IgxTimeFilteringOperand.instance().condition('at')); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); // Not At 09:15:35 grid.clearFilter('ReleaseTime'); fix.detectChanges(); expect(grid.rowList.length).toEqual(8); grid.filter('ReleaseTime', cal.timedelta(today, 'hour', -1), IgxTimeFilteringOperand.instance().condition('not_at')); fix.detectChanges(); expect(grid.rowList.length).toEqual(7); // Before 10:25:35 grid.clearFilter('ReleaseTime'); fix.detectChanges(); expect(grid.rowList.length).toEqual(8); grid.filter('ReleaseTime', cal.timedelta(today, 'minute', +10), IgxTimeFilteringOperand.instance().condition('before')); fix.detectChanges(); expect(grid.rowList.length).toEqual(4); // After 10:15:55 grid.clearFilter('ReleaseTime'); fix.detectChanges(); expect(grid.rowList.length).toEqual(8); grid.filter('ReleaseTime', cal.timedelta(today, 'second', +20), IgxTimeFilteringOperand.instance().condition('after')); fix.detectChanges(); expect(grid.rowList.length).toEqual(2); // At or Before 10:25:35 grid.clearFilter('ReleaseTime'); fix.detectChanges(); expect(grid.rowList.length).toEqual(8); grid.filter('ReleaseTime', cal.timedelta(today, 'minute', +10), IgxTimeFilteringOperand.instance().condition('at_before')); fix.detectChanges(); expect(grid.rowList.length).toEqual(5); // At or After 10:15:55 grid.clearFilter('ReleaseTime'); fix.detectChanges(); expect(grid.rowList.length).toEqual(8); grid.filter('ReleaseTime', cal.timedelta(today, 'second', +20), IgxTimeFilteringOperand.instance().condition('at_after')); fix.detectChanges(); expect(grid.rowList.length).toEqual(3); // Empty filter grid.clearFilter('ReleaseTime'); fix.detectChanges(); expect(grid.rowList.length).toEqual(8); grid.filter('ReleaseTime', null, IgxTimeFilteringOperand.instance().condition('empty')); fix.detectChanges(); expect(grid.rowList.length).toEqual(2); // NotEmpty filter grid.clearFilter('ReleaseTime'); fix.detectChanges(); expect(grid.rowList.length).toEqual(8); grid.filter('ReleaseTime', null, IgxTimeFilteringOperand.instance().condition('notEmpty')); fix.detectChanges(); expect(grid.rowList.length).toEqual(6); // Null filter grid.clearFilter('ReleaseTime'); fix.detectChanges(); expect(grid.rowList.length).toEqual(8); grid.filter('ReleaseTime', null, IgxTimeFilteringOperand.instance().condition('null')); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); // NotNull filter grid.clearFilter('ReleaseTime'); fix.detectChanges(); expect(grid.rowList.length).toEqual(8); grid.filter('ReleaseTime', null, IgxTimeFilteringOperand.instance().condition('notNull')); fix.detectChanges(); expect(grid.rowList.length).toEqual(7); })); it('should correctly filter by \'dateTime\' filtering conditions', fakeAsync(() => { const cal = SampleTestData.timeGenerator; const today = SampleTestData.todayFullDate; // Equals 11:15:35 grid.filter('ReleaseDateTime', cal.timedelta(today, 'hour', 1), IgxDateTimeFilteringOperand.instance().condition('equals')); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); // Does not equal 11:15:35 grid.filter('ReleaseDateTime', cal.timedelta(today, 'hour', 1), IgxDateTimeFilteringOperand.instance().condition('doesNotEqual')); fix.detectChanges(); expect(grid.rowList.length).toEqual(7); })); it('should correctly filter with earliest/latest \'date\' values', fakeAsync(() => { const earliest = new Date(SampleTestData.timeGenerator.timedelta(SampleTestData.today, 'month', -1).getTime() + 7200 * 1000); const latest = new Date(SampleTestData.timeGenerator.timedelta(SampleTestData.today, 'month', 1).getTime() - 7200 * 1000); // Before filter expect(grid.rowList.length).toEqual(8); grid.filter('ReleaseDate', earliest, IgxDateFilteringOperand.instance().condition('before')); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); // After filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', earliest, IgxDateFilteringOperand.instance().condition('after')); fix.detectChanges(); expect(grid.rowList.length).toEqual(5); // DoesNotEqual filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', earliest, IgxDateFilteringOperand.instance().condition('doesNotEqual')); fix.detectChanges(); expect(grid.rowList.length).toEqual(7); // Equals filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', earliest, IgxDateFilteringOperand.instance().condition('equals')); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); // Before filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', latest, IgxDateFilteringOperand.instance().condition('before')); fix.detectChanges(); expect(grid.rowList.length).toEqual(5); // After filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', latest, IgxDateFilteringOperand.instance().condition('after')); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); })); it('should correctly filter by \'date\' filtering conditions when dates are ISO 8601 strings', fakeAsync(() => { const cal = SampleTestData.timeGenerator; const today = SampleTestData.today; grid.data = grid.data.map(rec => { const newRec = Object.assign({}, rec) as any; newRec.ReleaseDate = rec.ReleaseDate ? rec.ReleaseDate.toISOString() : rec.ReleaseDate; return newRec; }); // Fill expected results based on the current date const expectedResults = GridFunctions.createDateFilterConditions(grid, today); // After filter grid.filter('ReleaseDate', cal.timedelta(today, 'day', 4), IgxDateFilteringOperand.instance().condition('after')); fix.detectChanges(); expect(grid.rowList.length).toEqual(2); // Before filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); expect(grid.rowList.length).toEqual(8); grid.filter('ReleaseDate', cal.timedelta(today, 'day', 4), IgxDateFilteringOperand.instance().condition('before')); fix.detectChanges(); expect(grid.rowList.length).toEqual(4); // DoesNotEqual filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', cal.timedelta(today, 'day', 15), IgxDateFilteringOperand.instance().condition('doesNotEqual')); fix.detectChanges(); expect(grid.rowList.length).toEqual(7); // Equals filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', cal.timedelta(today, 'day', 15), IgxDateFilteringOperand.instance().condition('equals')); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); // LastMonth filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('lastMonth')); fix.detectChanges(); expect(grid.rowList.length).toEqual(expectedResults[0]); // NextMonth filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('nextMonth')); fix.detectChanges(); expect(grid.rowList.length).toEqual(expectedResults[1]); // ThisYear filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('thisYear')); fix.detectChanges(); expect(grid.rowList.length).toEqual(expectedResults[2]); // LastYear filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('lastYear')); fix.detectChanges(); expect(grid.rowList.length).toEqual(expectedResults[4]); // NextYear filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('nextYear')); fix.detectChanges(); expect(grid.rowList.length).toEqual(expectedResults[3]); // Null filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('null')); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); // NotNull filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('notNull')); fix.detectChanges(); expect(grid.rowList.length).toEqual(7); // Empty filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('empty')); fix.detectChanges(); expect(grid.rowList.length).toEqual(2); // NotEmpty filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('notEmpty')); fix.detectChanges(); expect(grid.rowList.length).toEqual(6); // Today filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('today')); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); // Yesterday filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('yesterday')); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); })); it('should correctly filter by \'date\' filtering conditions when dates are miliseconds numbers', fakeAsync(() => { const cal = SampleTestData.timeGenerator; const today = SampleTestData.today; grid.data = grid.data.map(rec => { const newRec = Object.assign({}, rec) as any; newRec.ReleaseDate = rec.ReleaseDate ? rec.ReleaseDate.getTime() : rec.ReleaseDate; return newRec; }); // Fill expected results based on the current date const expectedResults = GridFunctions.createDateFilterConditions(grid, today); // After filter grid.filter('ReleaseDate', cal.timedelta(today, 'day', 4), IgxDateFilteringOperand.instance().condition('after')); fix.detectChanges(); expect(grid.rowList.length).toEqual(2); // Before filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); expect(grid.rowList.length).toEqual(8); grid.filter('ReleaseDate', cal.timedelta(today, 'day', 4), IgxDateFilteringOperand.instance().condition('before')); fix.detectChanges(); expect(grid.rowList.length).toEqual(4); // DoesNotEqual filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', cal.timedelta(today, 'day', 15), IgxDateFilteringOperand.instance().condition('doesNotEqual')); fix.detectChanges(); expect(grid.rowList.length).toEqual(7); // Equals filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', cal.timedelta(today, 'day', 15), IgxDateFilteringOperand.instance().condition('equals')); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); // LastMonth filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('lastMonth')); fix.detectChanges(); expect(grid.rowList.length).toEqual(expectedResults[0]); // NextMonth filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('nextMonth')); fix.detectChanges(); expect(grid.rowList.length).toEqual(expectedResults[1]); // ThisYear filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('thisYear')); fix.detectChanges(); expect(grid.rowList.length).toEqual(expectedResults[2]); // LastYear filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('lastYear')); fix.detectChanges(); expect(grid.rowList.length).toEqual(expectedResults[4]); // NextYear filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('nextYear')); fix.detectChanges(); expect(grid.rowList.length).toEqual(expectedResults[3]); // Null filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('null')); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); // NotNull filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('notNull')); fix.detectChanges(); expect(grid.rowList.length).toEqual(7); // Empty filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('empty')); fix.detectChanges(); expect(grid.rowList.length).toEqual(2); // NotEmpty filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('notEmpty')); fix.detectChanges(); expect(grid.rowList.length).toEqual(6); // Today filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('today')); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); // Yesterday filter grid.clearFilter('ReleaseDate'); fix.detectChanges(); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('yesterday')); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); })); it('should exclude null and undefined values when filter by \'false\'', fakeAsync(() => { expect(grid.rowList.length).toEqual(8); grid.filter('Released', false, IgxStringFilteringOperand.instance().condition('equals'), true); fix.detectChanges(); expect(grid.rowList.length).toEqual(2); expect(grid.getCellByColumn(0, 'Released').value).toBe(false); expect(grid.getCellByColumn(1, 'Released').value).toBe(false); })); it('should correctly apply multiple filtering through API', fakeAsync(() => { spyOn(grid.filtering, 'emit'); spyOn(grid.filteringDone, 'emit'); const gridExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And); gridExpressionsTree.filteringOperands = [ { fieldName: 'Downloads', searchVal: 20, condition: IgxNumberFilteringOperand.instance().condition('greaterThanOrEqualTo') }, { fieldName: 'ID', searchVal: 4, condition: IgxNumberFilteringOperand.instance().condition('greaterThan') } ]; grid.filteringExpressionsTree = gridExpressionsTree; tick(30); fix.detectChanges(); expect(grid.filtering.emit).toHaveBeenCalledTimes(0); expect(grid.filteringDone.emit).toHaveBeenCalledTimes(0); expect(grid.rowList.length).toEqual(3); expect(grid.filteringExpressionsTree.filteringOperands.length).toEqual(2); let expression = grid.filteringExpressionsTree.filteringOperands[0] as IFilteringExpression; expect(expression).toBeDefined(); expression = grid.filteringExpressionsTree.filteringOperands[1] as IFilteringExpression; expect(expression).toBeDefined(); grid.clearFilter(); tick(30); fix.detectChanges(); expect(grid.rowList.length).toEqual(8); expect(grid.filteringExpressionsTree.filteringOperands.length).toEqual(0); })); it('should correctly apply global filtering', fakeAsync(() => { spyOn(grid.filtering, 'emit'); spyOn(grid.filteringDone, 'emit'); grid.filteringLogic = FilteringLogic.Or; grid.filterGlobal('some', IgxStringFilteringOperand.instance().condition('contains')); tick(30); fix.detectChanges(); expect(grid.filteringExpressionsTree.filteringOperands.length).toEqual(grid.columnList.length); expect(grid.rowList.length).toEqual(1); const filteringExpressions = grid.filteringExpressionsTree; const args = { owner: grid, cancel: false, filteringExpressions }; expect(grid.filtering.emit).toHaveBeenCalledWith(args); expect(grid.filteringDone.emit).toHaveBeenCalledWith(filteringExpressions); })); it('Should render chip when filtering using the API.', fakeAsync(() => { const firstHeaderCell = fix.debugElement.query(By.css('.header-release-date')); let filteringChips = firstHeaderCell.parent.queryAll(By.directive(IgxChipComponent)); expect(filteringChips.length).toEqual(1); let chipContent = filteringChips[0].query(By.css('.igx-chip__content')).nativeElement.innerText; expect(chipContent).toEqual('Filter'); grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('today')); fix.detectChanges(); filteringChips = firstHeaderCell.parent.queryAll(By.directive(IgxChipComponent)); expect(filteringChips.length).toEqual(1); chipContent = filteringChips[0].query(By.css('.igx-chip__content')).nativeElement.innerText; expect(chipContent).not.toEqual('Filter'); grid.clearFilter('ReleaseDate'); fix.detectChanges(); filteringChips = firstHeaderCell.parent.queryAll(By.directive(IgxChipComponent)); expect(filteringChips.length).toEqual(1); chipContent = filteringChips[0].query(By.css('.igx-chip__content')).nativeElement.innerText; expect(chipContent).toEqual('Filter'); })); it('Should correctly apply two conditions to two columns at once.', fakeAsync(() => { const colDownloadsExprTree = new FilteringExpressionsTree(FilteringLogic.And, 'Downloads'); colDownloadsExprTree.filteringOperands = [ { fieldName: 'Downloads', searchVal: 20, condition: IgxNumberFilteringOperand.instance().condition('greaterThanOrEqualTo') }, { fieldName: 'Downloads', searchVal: 100, condition: IgxNumberFilteringOperand.instance().condition('lessThanOrEqualTo') } ]; const colIdExprTree = new FilteringExpressionsTree(FilteringLogic.And, 'ID'); colIdExprTree.filteringOperands = [ { fieldName: 'ID', searchVal: 1, condition: IgxNumberFilteringOperand.instance().condition('greaterThan') }, { fieldName: 'ID', searchVal: 5, condition: IgxNumberFilteringOperand.instance().condition('lessThan') } ]; const gridExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And); gridExpressionsTree.filteringOperands = [colDownloadsExprTree, colIdExprTree]; grid.filteringExpressionsTree = gridExpressionsTree; fix.detectChanges(); expect(grid.rowList.length).toEqual(1); expect(grid.filteringExpressionsTree.filteringOperands.length).toEqual(2); grid.clearFilter(); fix.detectChanges(); expect(grid.rowList.length).toEqual(8); expect(grid.filteringExpressionsTree.filteringOperands.length).toEqual(0); })); it('Should correctly apply two conditions to number column.', fakeAsync(() => { const filteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And, 'Downloads'); const expression = { fieldName: 'Downloads', searchVal: 50, condition: IgxNumberFilteringOperand.instance().condition('greaterThan') }; const expression1 = { fieldName: 'Downloads', searchVal: 500, condition: IgxNumberFilteringOperand.instance().condition('lessThan') }; filteringExpressionsTree.filteringOperands.push(expression); filteringExpressionsTree.filteringOperands.push(expression1); grid.filter('Downloads', null, filteringExpressionsTree); fix.detectChanges(); expect(grid.rowList.length).toEqual(3); expect((grid.filteringExpressionsTree.filteringOperands[0] as FilteringExpressionsTree).filteringOperands.length).toEqual(2); })); it('Should correctly apply two conditions to string column.', 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(); expect(grid.rowList.length).toEqual(1); expect((grid.filteringExpressionsTree.filteringOperands[0] as FilteringExpressionsTree).filteringOperands.length).toEqual(2); })); it('Should correctly apply two conditions to date column.', fakeAsync(() => { const today: Date = new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate(), 0, 0, 0); const filteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.Or, 'ReleaseDate'); const expression = { fieldName: 'ReleaseDate', searchVal: null, condition: IgxDateFilteringOperand.instance().condition('yesterday') }; const expression1 = { fieldName: 'ReleaseDate', searchVal: today, condition: IgxDateFilteringOperand.instance().condition('after') }; filteringExpressionsTree.filteringOperands.push(expression); filteringExpressionsTree.filteringOperands.push(expression1); grid.filter('ReleaseDate', null, filteringExpressionsTree); fix.detectChanges(); expect(grid.rowList.length).toEqual(4); expect((grid.filteringExpressionsTree.filteringOperands[0] as FilteringExpressionsTree).filteringOperands.length).toEqual(2); })); it('Should correctly update summary.', fakeAsync(() => { const gridExpressionsTree = new FilteringExpressionsTree(FilteringLogic.Or); const filteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.Or, 'ReleaseDate'); const expression = { fieldName: 'ReleaseDate', searchVal: null, condition: IgxDateFilteringOperand.instance().condition('yesterday') }; filteringExpressionsTree.filteringOperands.push(expression); gridExpressionsTree.filteringOperands.push(filteringExpressionsTree); grid.filteringExpressionsTree = gridExpressionsTree; fix.detectChanges(); tick(100); expect(grid.rowList.length).toEqual(1); const summaryRow = fix.debugElement.query(By.css('igx-grid-summary-row')); GridSummaryFunctions.verifyColumnSummaries(summaryRow, 0, ['Count'], ['1']); })); it('should correctly show and hide the "No records found." message.', fakeAsync(() => { grid.filter('ProductName', 'asdf', IgxStringFilteringOperand.instance().condition('contains'), true); fix.detectChanges(); let noRecordsSpan = fix.debugElement.query(By.css('.igx-grid__tbody-message')); expect(grid.rowList.length).toEqual(0); expect(noRecordsSpan).toBeTruthy(); expect(noRecordsSpan.nativeElement.innerText).toBe('No records found.'); grid.filteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And); fix.detectChanges(); noRecordsSpan = fix.debugElement.query(By.css('.igx-grid__tbody-message')); expect(grid.rowList.length).toEqual(8); expect(noRecordsSpan).toBeFalsy(); })); it('Should generate the expressions UI list correctly.', fakeAsync(() => { const filteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.Or, 'ProductName'); const expression = { fieldName: 'ProductName', searchVal: 'Ignite', condition: IgxStringFilteringOperand.instance().condition('startsWith') }; const expression1 = new FilteringExpressionsTree(FilteringLogic.And, 'ProductName'); const expression11 = { fieldName: 'ProductName', searchVal: 'Angular', condition: IgxStringFilteringOperand.instance().condition('contains') }; const expression12 = { fieldName: 'ProductName', searchVal: 'jQuery', condition: IgxStringFilteringOperand.instance().condition('contains') }; const expression2 = new FilteringExpressionsTree(FilteringLogic.And, 'ProductName'); const expression21 = { fieldName: 'ProductName', searchVal: 'Angular', condition: IgxStringFilteringOperand.instance().condition('contains') }; const expression22 = { fieldName: 'ProductName', searchVal: 'jQuery', condition: IgxStringFilteringOperand.instance().condition('contains') }; expression1.filteringOperands.push(expression11); expression1.filteringOperands.push(expression12); expression2.filteringOperands.push(expression21); expression2.filteringOperands.push(expression22); filteringExpressionsTree.filteringOperands.push(expression); filteringExpressionsTree.filteringOperands.push(expression1); filteringExpressionsTree.filteringOperands.push(expression2); grid.filter('ProductName', null, filteringExpressionsTree); const expressionUIs: ExpressionUI[] = []; grid.filteringService.generateExpressionsList(grid.filteringExpressionsTree, grid.filteringLogic, expressionUIs); verifyExpressionUI(expressionUIs[0], expression, FilteringLogic.Or, undefined); verifyExpressionUI(expressionUIs[1], expression11, FilteringLogic.And, FilteringLogic.Or); verifyExpressionUI(expressionUIs[2], expression12, FilteringLogic.Or, FilteringLogic.And); verifyExpressionUI(expressionUIs[3], expression21, FilteringLogic.And, FilteringLogic.Or); verifyExpressionUI(expressionUIs[4], expression22, null, FilteringLogic.And); })); it('Should do nothing when clearing filter of non-existing column.', fakeAsync(() => { grid.filter('ProductName', 'ignite', IgxStringFilteringOperand.instance().condition('contains'), true); fix.detectChanges(); expect(grid.rowList.length).toEqual(2); grid.clearFilter('NonExistingColumnName'); fix.detectChanges(); expect(grid.rowList.length).toEqual(2); })); it('Should always emit filteringDone with proper eventArgs, even when column does not exist', fakeAsync(() => { spyOn(grid.filtering, 'emit'); spyOn(grid.filteringDone, 'emit'); grid.filteringLogic = FilteringLogic.Or; grid.filter('Nonexisting', 'ignite', IgxStringFilteringOperand.instance().condition('contains'), true); tick(100); fix.detectChanges(); expect(grid.rowList.length).toEqual(0); const args = grid.filteringExpressionsTree.find('Nonexisting') as FilteringExpressionsTree; expect(grid.filtering.emit).toHaveBeenCalledWith({ owner: grid, cancel: false, filteringExpressions: args }); expect(grid.filteringDone.emit).toHaveBeenCalledWith(args); })); it('Should emit filteringDone when filtering globally', fakeAsync(() => { spyOn(grid.filtering, 'emit'); spyOn(grid.filteringDone, 'emit'); grid.filteringLogic = FilteringLogic.Or; grid.filterGlobal('some', IgxStringFilteringOperand.instance().condition('contains')); tick(100); fix.detectChanges(); const args = { owner: grid, cancel: false, filteringExpressions: grid.filteringExpressionsTree }; expect(grid.filtering.emit).toHaveBeenCalledWith(args); expect(grid.filteringDone.emit).toHaveBeenCalledWith(grid.filteringExpressionsTree); })); it('Should keep existing expressionTree when filtering with a null expressionTree.', fakeAsync(() => { spyOn(grid.filtering, 'emit'); spyOn(grid.filteringDone, 'emit'); const expression1 = new FilteringExpressionsTree(FilteringLogic.Or, 'ProductName'); const expression11 = { fieldName: 'ProductName', searchVal: 'Angular', condition: IgxStringFilteringOperand.instance().condition('contains') }; // Verify results after filtering. expression1.filteringOperands.push(expression11); grid.filter('ProductName', null, expression1); tick(30); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); expect(GridFunctions.getCurrentCellFromGrid(grid, 0, 1).value).toBe('Ignite UI for Angular'); const args = { owner: grid, cancel: false, filteringExpressions: expression1 }; expect(grid.filtering.emit).toHaveBeenCalledWith(args); expect(grid.filteringDone.emit).toHaveBeenCalledWith(expression1); // Verify that passing null for expressionTree with a new searchVal will keep the existing expressionTree. grid.filter('ProductName', 'ignite', null); tick(30); fix.detectChanges(); expect(grid.rowList.length).toEqual(1); expect(GridFunctions.getCurrentCellFromGrid(grid, 0, 1).value).toBe('Ignite UI for Angular'); expect(grid.filtering.emit).toHaveBeenCalledWith(args); expect(grid.filteringDone.emit).toHaveBeenCalledWith(expression1); })); it('Should throw descriptive error when filter() is called without condition', fakeAsync(() => { expect(() => { grid.filter('Downloads', 100); fix.detectChanges(); }).toThrowError('Invalid condition or Expression Tree!'); })); it('Should not clear previous filtering when filterGlobal() is called with invalid condition', fakeAsync(() => { spyOn(grid.filtering, 'emit'); spyOn(grid.filteringDone, 'emit'); grid.filter('Downloads', 100, IgxNumberFilteringOperand.instance().condition('greaterThan'), true); tick(30); fix.detectChanges(); expect(grid.rowList.length).toEqual(4); expect(grid.getCellByColumn(0, 'Downloads').value).toEqual(254); const args = { owner: grid, cancel: false, filteringExpressions: grid.filteringExpressionsTree.find('Downloads') }; expect(grid.filtering.emit).toHaveBeenCalledWith(args); expect(grid.filteringDone.emit).toHaveBeenCalledWith(grid.filteringExpressionsTree.find('Downloads')); // Execute global filtering with invalid condition. grid.filterGlobal(1000, null); fix.detectChanges(); expect(grid.rowList.length).toEqual(4); expect(grid.getCellByColumn(0, 'Downloads').value).toEqual(254); expect(grid.filtering.emit).toHaveBeenCalledTimes(1); expect(grid.filteringDone.emit).toHaveBeenCalledTimes(1); })); it('Should disable filtering feature when using NoopFilteringStrategy.', fakeAsync(() => { spyOn(grid.filtering, 'emit'); spyOn(grid.filteringDone, 'emit'); // Use the NoopFilteringStrategy. grid.filterStrategy = NoopFilteringStrategy.instance(); fix.detectChanges(); grid.filter('ProductName', 'some value', IgxStringFilteringOperand.instance().condition('contains')); tick(30); fix.detectChanges(); // Verify the grid is not filtered, because of the noop filter strategy. expect(grid.rowList.length).toBe(8); expect(GridFunctions.getCurrentCellFromGrid(grid, 0, 1).value).toBe('Ignite UI for JavaScript'); expect(GridFunctions.getCurrentCellFromGrid(grid, 1, 1).value).toBe('NetAdvantage'); const filteringExpressions = grid.filteringExpressionsTree.find('ProductName'); const args = { owner: grid, cancel: false, filteringExpressions }; expect(grid.filtering.emit).toHaveBeenCalledWith(args); expect(grid.filteringDone.emit).toHaveBeenCalledWith(filteringExpressions); })); }); describe('IgxGrid - Filtering expression tree bindings #grid', () => { configureTestSuite((() => { return TestBed.configureTestingModule({ imports: [ NoopAnimationsModule, IgxGridFilteringBindingComponent ] }); })); let fix; let grid: IgxGridComponent; beforeEach(