UNPKG

igniteui-angular-sovn

Version:

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

983 lines (799 loc) 85.9 kB
import { TestBed, ComponentFixture, waitForAsync, fakeAsync, tick } from '@angular/core/testing'; import { IgxGridComponent } from './grid.component'; import { DebugElement, QueryList } from '@angular/core'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { IgxColumnComponent } from '../columns/column.component'; import { IgxColumnGroupComponent } from '../columns/column-group.component'; import { By } from '@angular/platform-browser'; import { DefaultSortingStrategy, SortingDirection } from '../../data-operations/sorting-strategy'; import { IgxStringFilteringOperand } from '../../data-operations/filtering-condition'; import { configureTestSuite } from '../../test-utils/configure-suite'; import { IgxGridHeaderComponent } from '../headers/grid-header.component'; import { GridSummaryFunctions, GridFunctions } from '../../test-utils/grid-functions.spec'; import { wait } from '../../test-utils/ui-interactions.spec'; import { DropPosition } from '../moving/moving.service'; import { OneGroupOneColGridComponent, OneGroupThreeColsGridComponent, BlueWhaleGridComponent, ColumnGroupTestComponent, ColumnGroupFourLevelTestComponent, ThreeGroupsThreeColumnsGridComponent, NestedColGroupsGridComponent, StegosaurusGridComponent, OneColPerGroupGridComponent, NestedColumnGroupsGridComponent, DynamicGridComponent, NestedColGroupsWithTemplatesGridComponent, DynamicColGroupsGridComponent } from '../../test-utils/grid-mch-sample.spec'; import { CellType } from '../common/grid.interface'; const GRID_COL_THEAD_TITLE_CLASS = 'igx-grid-th__title'; const GRID_COL_GROUP_THEAD_TITLE_CLASS = 'igx-grid-thead__title'; const GRID_COL_GROUP_THEAD_GROUP_CLASS = 'igx-grid-thead__group'; /* eslint-disable max-len */ describe('IgxGrid - multi-column headers #grid', () => { let fixture: ComponentFixture<any>; let grid: IgxGridComponent; let componentInstance; configureTestSuite(); beforeAll(waitForAsync(() => { TestBed.configureTestingModule({ imports: [ NoopAnimationsModule, OneGroupOneColGridComponent, OneGroupThreeColsGridComponent, BlueWhaleGridComponent, ColumnGroupTestComponent, ColumnGroupFourLevelTestComponent, ThreeGroupsThreeColumnsGridComponent, NestedColGroupsGridComponent, StegosaurusGridComponent, OneColPerGroupGridComponent, NestedColumnGroupsGridComponent, DynamicGridComponent, NestedColGroupsWithTemplatesGridComponent, DynamicColGroupsGridComponent ] }) .compileComponents(); })); describe('Initialization and rendering tests: ', () => { it('should initialize a grid with column groups', () => { fixture = TestBed.createComponent(ColumnGroupTestComponent); fixture.detectChanges(); grid = fixture.componentInstance.grid; const expectedColumnGroups = 5; const expectedLevel = 2; const groupHeaders = GridFunctions.getColumnGroupHeaders(fixture); expect(groupHeaders.length).toEqual(expectedColumnGroups); expect(grid.getColumnByName('ContactName').level).toEqual(expectedLevel); }); it('Should render column group headers correctly.', fakeAsync(() => { fixture = TestBed.createComponent(BlueWhaleGridComponent); fixture.detectChanges(); componentInstance = fixture.componentInstance; grid = componentInstance.grid; const columnWidthPx = parseInt(componentInstance.columnWidth, 10); // 2 levels of column group and 1 level of columns const gridHeadersDepth = 3; const firstGroupChildrenCount = 100; const secondGroupChildrenCount = 2; const secondSubGroupChildrenCount = 50; const secondSubGroupHeadersDepth = 2; const firstGroup = GridFunctions.getColumnGroupHeaders(fixture)[0]; testColumnGroupHeaderRendering(firstGroup, firstGroupChildrenCount * columnWidthPx, gridHeadersDepth * grid.defaultRowHeight, componentInstance.firstGroupTitle, 'firstGroupColumn', firstGroupChildrenCount); let horizontalScroll = grid.headerContainer.getScroll(); let scrollToNextGroup = firstGroupChildrenCount * columnWidthPx + columnWidthPx; horizontalScroll.scrollLeft = scrollToNextGroup; tick(); fixture.detectChanges(); const secondGroup = GridFunctions.getColumnGroupHeaders(fixture)[1]; testColumnGroupHeaderRendering(secondGroup, secondGroupChildrenCount * secondSubGroupChildrenCount * columnWidthPx, gridHeadersDepth * grid.defaultRowHeight, componentInstance.secondGroupTitle, 'secondSubGroup', 0); const secondSubGroups = secondGroup.queryAll(By.css('.secondSubGroup')); testColumnGroupHeaderRendering(secondSubGroups[0], secondSubGroupChildrenCount * columnWidthPx, secondSubGroupHeadersDepth * grid.defaultRowHeight, componentInstance.secondSubGroupTitle, 'secondSubGroupColumn', secondSubGroupChildrenCount); testColumnGroupHeaderRendering(secondSubGroups[1], secondSubGroupChildrenCount * columnWidthPx, secondSubGroupHeadersDepth * grid.defaultRowHeight, componentInstance.secondSubGroupTitle, 'secondSubGroupColumn', secondSubGroupChildrenCount); horizontalScroll = grid.headerContainer.getScroll(); scrollToNextGroup = horizontalScroll.scrollLeft + secondSubGroupHeadersDepth * secondSubGroupChildrenCount * columnWidthPx; horizontalScroll.scrollLeft = scrollToNextGroup; tick(); fixture.detectChanges(); const idColumn = fixture.debugElement.query(By.css('.lonelyId')); testColumnHeaderRendering(idColumn, columnWidthPx, gridHeadersDepth * grid.defaultRowHeight, componentInstance.idHeaderTitle); const companyNameColumn = GridFunctions.getColumnHeader('CompanyName', fixture); testColumnHeaderRendering(companyNameColumn, columnWidthPx, 2 * grid.defaultRowHeight, componentInstance.companyNameTitle); const personDetailsColumn = GridFunctions.getColumnGroupHeader('Person Details', fixture); testColumnGroupHeaderRendering(personDetailsColumn, 2 * columnWidthPx, 2 * grid.defaultRowHeight, componentInstance.personDetailsTitle, 'personDetailsColumn', 2); })); it('Should render dynamic column group header correctly (#12165).', () => { fixture = TestBed.createComponent(BlueWhaleGridComponent) as ComponentFixture<BlueWhaleGridComponent>; (fixture as ComponentFixture<BlueWhaleGridComponent>).componentInstance.firstGroupRepeats = 1; (fixture as ComponentFixture<BlueWhaleGridComponent>).componentInstance.secondGroupRepeats = 1; fixture.detectChanges(); componentInstance = fixture.componentInstance; grid = componentInstance.grid; const columnWidthPx = parseInt(componentInstance.columnWidth, 10); // 2 levels of column group and 1 level of columns const gridHeadersDepth = 3; let firstGroupChildrenCount = 1; let firstGroup = GridFunctions.getColumnGroupHeaders(fixture)[0]; testColumnGroupHeaderRendering(firstGroup, firstGroupChildrenCount * columnWidthPx, gridHeadersDepth * grid.defaultRowHeight, componentInstance.firstGroupTitle, 'firstGroupColumn', firstGroupChildrenCount); let allHeaders = GridFunctions.getColumnHeaders(fixture).map<IgxGridHeaderComponent>(x => x.componentInstance); let firstSixHeaders = allHeaders.slice(0, 6).map(x => x.column.field); expect(allHeaders.length).toEqual(14); expect(firstSixHeaders).toEqual(['ID', 'ID', 'ID', 'ID', 'CompanyName', 'ContactName']); (componentInstance as BlueWhaleGridComponent).extraMissingColumn = true; fixture.detectChanges(); firstGroupChildrenCount = 2; firstGroup = GridFunctions.getColumnGroupHeaders(fixture)[0]; testColumnGroupHeaderRendering(firstGroup, firstGroupChildrenCount * columnWidthPx, gridHeadersDepth * grid.defaultRowHeight, componentInstance.firstGroupTitle, 'firstGroupColumn', firstGroupChildrenCount); allHeaders = GridFunctions.getColumnHeaders(fixture).map<IgxGridHeaderComponent>(x => x.componentInstance); firstSixHeaders = allHeaders.slice(0, 6).map(x => x.column.field); expect(allHeaders.length).toEqual(15); expect(firstSixHeaders).toEqual(['ID', 'Missing', 'ID', 'ID', 'ID', 'CompanyName']); }); it('Should not render empty column group.', () => { fixture = TestBed.createComponent(ColumnGroupTestComponent); fixture.detectChanges(); const ci = fixture.componentInstance; // Empty column group should not be displayed const emptyColGroup = GridFunctions.getColumnGroupHeader('Empty Header', fixture); expect(parseInt(ci.emptyColGroup.width, 10)).toBe(0); expect(emptyColGroup).toBeUndefined(); }); it('Should render headers correctly when having a column per group.', () => { fixture = TestBed.createComponent(OneColPerGroupGridComponent); fixture.detectChanges(); const ci = fixture.componentInstance; grid = ci.grid; const addressColGroup = GridFunctions.getColumnGroupHeader('Address Group', fixture); const addressColGroupDepth = 2; // one-level children const addressColGroupChildrenCount = 1; testColumnGroupHeaderRendering(addressColGroup, parseInt(ci.columnWidth, 10), addressColGroupDepth * grid.defaultRowHeight, ci.addressColGroupTitle, 'addressCol', addressColGroupChildrenCount); const addressCol = GridFunctions.getColumnHeader('Address', fixture); testColumnHeaderRendering(addressCol, parseInt(ci.columnWidth, 10), grid.defaultRowHeight, ci.addressColTitle); const phoneColGroup = GridFunctions.getColumnGroupHeader('Phone Group', fixture); const phoneColGroupDepth = 2; // one-level children const phoneColGroupChildrenCount = 1; testColumnGroupHeaderRendering(phoneColGroup, parseInt(ci.phoneColWidth, 10), phoneColGroupDepth * grid.defaultRowHeight, ci.phoneColGroupTitle, 'phoneCol', phoneColGroupChildrenCount); const phoneCol = GridFunctions.getColumnHeader('Phone', fixture); testColumnHeaderRendering(phoneCol, parseInt(ci.phoneColWidth, 10), grid.defaultRowHeight, ci.phoneColTitle); const faxColGroup = GridFunctions.getColumnGroupHeader('Fax Group', fixture); const faxColGroupDepth = 2; // one-level children const faxColGroupChildrenCount = 1; testColumnGroupHeaderRendering(faxColGroup, parseInt(ci.faxColWidth, 10), faxColGroupDepth * grid.defaultRowHeight, ci.faxColGroupTitle, 'faxCol', faxColGroupChildrenCount); const faxCol = GridFunctions.getColumnHeader('Fax', fixture); testColumnHeaderRendering(faxCol, parseInt(ci.faxColWidth, 10), grid.defaultRowHeight, ci.faxColTitle); }); it('Should render headers correctly when having nested column groups.', () => { fixture = TestBed.createComponent(NestedColumnGroupsGridComponent); fixture.detectChanges(); NestedColGroupsTests.testHeadersRendering(fixture); }); it('Should render headers correctly when having nested column groups with huge header text.', () => { fixture = TestBed.createComponent(NestedColumnGroupsGridComponent); fixture.detectChanges(); const ci = fixture.componentInstance; grid = ci.grid; const title = 'Lorem Ipsum is simply dummy text of the printing and typesetting' + ' industry.Lorem Ipsum has been the industry\'s standard dummy text ever since' + ' the 1500s, when an unknown printer took a galley of type and scrambled it to' + ' make a type specimen book. It has survived not only five centuries, but also the' + ' leap into electronic typesetting, remaining essentially unchanged.It was popularised' + ' in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and' + ' more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.'; ci.masterColGroupTitle = ci.firstSlaveColGroupTitle = ci.secondSlaveColGroupTitle = ci.addressColTitle = ci.phoneColTitle = ci.faxColTitle = ci.cityColTitle = title; fixture.detectChanges(); NestedColGroupsTests.testHeadersRendering(fixture); }); it('Should correctly initialize column group templates.', () => { fixture = TestBed.createComponent(NestedColGroupsWithTemplatesGridComponent); fixture.detectChanges(); const ci = fixture.componentInstance; const locationColGroup = ci.locationColGroup; const contactInfoColGroup = ci.contactInfoColGroup; expect(locationColGroup.headerTemplate).toBeDefined(); expect(contactInfoColGroup.headerTemplate).toBeUndefined(); const headerSpans: DebugElement[] = fixture.debugElement.queryAll(By.css('.col-group-template')); expect(headerSpans.length).toBe(1); expect(headerSpans[0].nativeElement.textContent).toMatch('Column group template'); }); it('Should correctly change column group templates dynamically.', () => { fixture = TestBed.createComponent(NestedColGroupsWithTemplatesGridComponent); fixture.detectChanges(); componentInstance = fixture.componentInstance; const locationColGroup = componentInstance.locationColGroup; const genInfoColGroup = componentInstance.genInfoColGroup; const headerTemplate = componentInstance.dynamicColGroupTemplate; locationColGroup.headerTemplate = headerTemplate; genInfoColGroup.headerTemplate = headerTemplate; fixture.detectChanges(); let headerSpans: DebugElement[] = fixture.debugElement.queryAll(By.css('.dynamic-col-group-template')); expect(headerSpans.length).toBe(2); headerSpans.forEach(headerSpan => { expect(headerSpan.nativeElement.textContent).toMatch('Dynamic column group template'); }); locationColGroup.headerTemplate = null; fixture.detectChanges(); headerSpans = fixture.debugElement.queryAll(By.css('.dynamic-col-group-template')); expect(headerSpans.length).toBe(1); headerSpans.forEach(headerSpan => { expect(headerSpan.nativeElement.textContent).toMatch('Dynamic column group template'); }); headerSpans = fixture.debugElement.queryAll(By.css('.col-group-template')); expect(headerSpans.length).toBe(0); headerSpans = fixture.debugElement.queryAll(By.css('.' + GRID_COL_GROUP_THEAD_TITLE_CLASS)); expect(headerSpans[1].nativeElement.textContent).toBe('Location'); }); it('There shouldn\'t be any errors when dynamically removing a column group with filtering enabled', () => { fixture = TestBed.createComponent(DynamicColGroupsGridComponent); fixture.detectChanges(); grid = fixture.componentInstance.grid; let columnLength = grid.columnList.length; let firstColumnGroup = grid.columnList.first; let expectedColumnName = 'First'; let expectedColumnListLength = 10; expect(firstColumnGroup.header).toEqual(expectedColumnName); expect(expectedColumnListLength).toEqual(columnLength); fixture.componentInstance.columnGroups = fixture.componentInstance.columnGroups.splice(1, fixture.componentInstance.columnGroups.length - 1); fixture.detectChanges(); fixture.componentInstance.columnGroups = fixture.componentInstance.columnGroups.splice(1, fixture.componentInstance.columnGroups.length - 1); fixture.detectChanges(); firstColumnGroup = grid.columnList.first; expectedColumnName = 'Third'; columnLength = grid.columnList.length; expectedColumnListLength = 3; expect(firstColumnGroup.header).toEqual(expectedColumnName); expect(expectedColumnListLength).toEqual(columnLength); }); it('There shouldn\'t be any errors when dynamically removing or adding a column in column group', () => { fixture = TestBed.createComponent(DynamicColGroupsGridComponent); fixture.detectChanges(); grid = fixture.componentInstance.grid; expect(grid.columnList.length).toEqual(10); expect(() => { // Delete column fixture.componentInstance.columnGroups[0].columns.splice(0, 1); fixture.detectChanges(); }).not.toThrow(); expect(grid.columnList.length).toEqual(9); expect(() => { // Add column fixture.componentInstance.columnGroups[0].columns.push({ field: 'Fax', type: 'string' }); fixture.detectChanges(); }).not.toThrow(); expect(grid.columnList.length).toEqual(10); expect(() => { // Update column fixture.componentInstance.columnGroups[0].columns[1] = { field: 'City', type: 'string' }; fixture.detectChanges(); }).not.toThrow(); expect(grid.columnList.length).toEqual(10); }); it('There shouldn\'t be any errors when the grid is grouped by a column that isn\'t defined', () => { fixture = TestBed.createComponent(ColumnGroupTestComponent); fixture.componentInstance.hideGroupedColumns = true; fixture.detectChanges(); grid = fixture.componentInstance.grid; expect(() => { grid.groupBy({ fieldName: 'NonExistentFieldName', dir: SortingDirection.Desc, ignoreCase: false, strategy: DefaultSortingStrategy.instance() }); fixture.detectChanges(); }).not.toThrow(); }); it('should set title attribute on column group header spans', () => { fixture = TestBed.createComponent(ColumnGroupTestComponent); fixture.detectChanges(); grid = fixture.componentInstance.grid; const generalGroup = grid.columnList.find(c => c.header === 'General Information'); generalGroup.title = 'General Information Title'; fixture.detectChanges(); const headers = fixture.debugElement.queryAll(By.css('.' + GRID_COL_GROUP_THEAD_TITLE_CLASS)); const generalHeader = headers.find(h => h.nativeElement.textContent === 'General Information'); const addressHeader = headers.find(h => h.nativeElement.textContent === 'Address Information'); expect(generalHeader.nativeElement.firstElementChild.title).toBe('General Information Title'); expect(addressHeader.nativeElement.firstElementChild.title).toBe('Address Information'); }); }); describe('Columns widths tests (1 group 1 column) ', () => { beforeEach(fakeAsync(() => { fixture = TestBed.createComponent(OneGroupOneColGridComponent); fixture.detectChanges(); componentInstance = fixture.componentInstance; grid = fixture.componentInstance.grid; })); it('Width should be correct. Column group with column. No width.', () => { grid.ngAfterViewInit(); fixture.detectChanges(); const locationColGroup = getColGroup(grid, 'Location'); expect(parseInt(locationColGroup.width, 10) + grid.scrollSize).toBe(parseInt(componentInstance.gridWrapperWidthPx, 10)); const cityColumn = grid.getColumnByName('City'); expect(parseInt(cityColumn.width, 10) + grid.scrollSize).toBe(parseInt(componentInstance.gridWrapperWidthPx, 10)); }); it('Width should be correct. Column group with column. Width in px.', () => { const gridWidth = '600px'; const gridWidthPx = parseInt(gridWidth, 10); grid.width = gridWidth; fixture.detectChanges(); const locationColGroup = getColGroup(grid, 'Location'); expect(parseInt(locationColGroup.width, 10) + grid.scrollSize).toBe(gridWidthPx); const cityColumn = grid.getColumnByName('City'); expect(parseInt(cityColumn.width, 10) + grid.scrollSize).toBe(gridWidthPx); }); it('Width should be correct. Column group with column. Width in percent.', () => { const gridWidth = '50%'; grid.width = gridWidth; fixture.detectChanges(); const locationColGroup = getColGroup(grid, 'Location'); const gridWidthInPx = ((parseInt(gridWidth, 10) / 100) * parseInt(componentInstance.gridWrapperWidthPx, 10) - grid.scrollSize) + 'px'; expect(locationColGroup.width).toBe(gridWidthInPx); const cityColumn = grid.getColumnByName('City'); expect(cityColumn.width).toBe(gridWidthInPx); }); it('Width should be correct. Column group with column. Column width in px.', () => { const gridColWidth = '200px'; grid.columnWidth = gridColWidth; fixture.detectChanges(); const locationColGroup = getColGroup(grid, 'Location'); expect(locationColGroup.width).toBe(gridColWidth); const cityColumn = grid.getColumnByName('City'); expect(cityColumn.width).toBe(gridColWidth); }); it('Width should be correct. Column group with column. Column width in percent.', () => { const gridColWidth = '50%'; grid.columnWidth = gridColWidth; fixture.detectChanges(); const locationColGroup = getColGroup(grid, 'Location'); const expectedWidth = (grid.calcWidth / 2) + 'px'; expect(locationColGroup.width).toBe(expectedWidth); const cityColumn = grid.getColumnByName('City'); expect(cityColumn.width).toBe(gridColWidth); }); it('Width should be correct. Column group with column. Column with width in px.', () => { const columnWidth = '200px'; componentInstance.columnWidth = columnWidth; fixture.detectChanges(); const locationColGroup = getColGroup(grid, 'Location'); expect(locationColGroup.width).toBe(columnWidth); const cityColumn = grid.getColumnByName('City'); expect(cityColumn.width).toBe(columnWidth); }); it('Width should be correct. Column group with column. Column with width in percent.', () => { const columnWidth = '50%'; componentInstance.columnWidth = columnWidth; fixture.detectChanges(); const locationColGroup = getColGroup(grid, 'Location'); const expectedWidth = (grid.calcWidth / 2) + 'px'; expect(locationColGroup.width).toBe(expectedWidth); const cityColumn = grid.getColumnByName('City'); expect(cityColumn.width).toBe(columnWidth); }); it('Should not throw exception if multi-column header columns width is set as number', () => { expect(() => { const cityColumn = grid.getColumnByName('City'); (cityColumn.width as any) = 55; fixture.detectChanges(); }).not.toThrow(); }); }); describe('Columns widths tests (1 group 3 columns) ', () => { beforeEach(fakeAsync(() => { fixture = TestBed.createComponent(OneGroupThreeColsGridComponent); fixture.detectChanges(); componentInstance = fixture.componentInstance; grid = fixture.componentInstance.grid; })); it('Width should be correct. Column group with three columns. No width.', () => { const scrWitdh = grid.nativeElement.querySelector('.igx-grid__tbody-scrollbar').getBoundingClientRect().width; const availableWidth = (parseInt(componentInstance.gridWrapperWidthPx, 10) - scrWitdh).toString(); const locationColGroup = getColGroup(grid, 'Location'); const colWidth = Math.floor(parseInt(availableWidth, 10) / 3); const colWidthPx = colWidth + 'px'; expect(locationColGroup.width).toBe((Math.round(colWidth) * 3) + 'px'); const countryColumn = grid.getColumnByName('Country'); expect(countryColumn.width).toBe(colWidthPx); const regionColumn = grid.getColumnByName('Region'); expect(regionColumn.width).toBe(colWidthPx); const cityColumn = grid.getColumnByName('City'); expect(cityColumn.width).toBe(colWidthPx); }); it('Width should be correct. Column group with three columns. Width in px.', () => { const gridWidth = '600px'; grid.width = gridWidth; fixture.detectChanges(); const scrWitdh = grid.nativeElement.querySelector('.igx-grid__tbody-scrollbar').getBoundingClientRect().width; const gridWidthInPx = parseInt(gridWidth, 10) - scrWitdh; const colWidth = Math.floor(gridWidthInPx / 3); const colWidthPx = colWidth + 'px'; const locationColGroup = getColGroup(grid, 'Location'); expect(locationColGroup.width).toBe((Math.round(colWidth) * 3) + 'px'); const countryColumn = grid.getColumnByName('Country'); expect(countryColumn.width).toBe(colWidthPx); const regionColumn = grid.getColumnByName('Region'); expect(regionColumn.width).toBe(colWidthPx); const cityColumn = grid.getColumnByName('City'); expect(cityColumn.width).toBe(colWidthPx); }); it('Width should be correct. Column group with three columns. Columns with mixed width - px and percent.', async () => { const col1 = grid.getColumnByName('Country'); const col2 = grid.getColumnByName('Region'); const col3 = grid.getColumnByName('City'); col1.width = '200px'; col2.width = '20%'; col3.width = '50%'; fixture.detectChanges(); // check group has correct size. let locationColGroup = getColGroup(grid, 'Location'); let expectedWidth = (200 + Math.floor(grid.calcWidth * 0.7)) + 'px'; expect(locationColGroup.width).toBe(expectedWidth); // check header and content have same size. const col1Header = grid.getColumnByName('Country').headerCell.nativeElement; const cell1 = (grid.gridAPI.get_row_by_index(0).cells as QueryList<CellType>).first.nativeElement; expect(col1Header.offsetWidth).toEqual(cell1.offsetWidth); let col2Header = grid.getColumnByName('Region').headerCell.nativeElement; let cell2 = (grid.gridAPI.get_row_by_index(0).cells as QueryList<CellType>).toArray()[1].nativeElement; expect(col2Header.offsetWidth - cell2.offsetWidth).toBeLessThanOrEqual(1); let col3Header = grid.getColumnByName('City').headerCell.nativeElement; let cell3 = (grid.gridAPI.get_row_by_index(0).cells as QueryList<CellType>).toArray()[2].nativeElement; expect(col3Header.offsetWidth).toEqual(cell3.offsetWidth); // check that if grid is resized, group size is updated. componentInstance.gridWrapperWidthPx = '500'; fixture.detectChanges(); await wait(100); fixture.detectChanges(); locationColGroup = getColGroup(grid, 'Location'); expectedWidth = (200 + Math.floor(grid.calcWidth * 0.7)) + 'px'; expect(locationColGroup.width).toBe(expectedWidth); col2Header = grid.getColumnByName('Region').headerCell.nativeElement; cell2 = (grid.gridAPI.get_row_by_index(0).cells as QueryList<CellType>).toArray()[1].nativeElement; expect(col2Header.offsetWidth - cell2.offsetWidth).toBeLessThanOrEqual(1); col3Header = grid.getColumnByName('City').headerCell.nativeElement; cell3 = (grid.gridAPI.get_row_by_index(0).cells as QueryList<CellType>).toArray()[2].nativeElement; expect(col3Header.offsetWidth).toEqual(cell3.offsetWidth); }); it('Width should be correct. Column group with three columns. Columns with mixed width - px, percent and null.', () => { const col1 = grid.getColumnByName('Country'); const col2 = grid.getColumnByName('Region'); const col3 = grid.getColumnByName('City'); col1.width = '200px'; col2.width = '20%'; col3.width = null; fixture.detectChanges(); // check group has correct size. Should fill available space in grid since one column has no width. const locationColGroup = getColGroup(grid, 'Location'); const expectedWidth = grid.calcWidth - 1 + 'px'; expect(locationColGroup.width).toBe(expectedWidth); // check header and content have same size. const col1Header = grid.getColumnByName('Country').headerCell.nativeElement; const cell1 = (grid.gridAPI.get_row_by_index(0).cells as QueryList<CellType>).toArray()[0].nativeElement; expect(col1Header.offsetWidth).toEqual(cell1.offsetWidth); const col2Header = grid.getColumnByName('Region').headerCell.nativeElement; const cell2 = (grid.gridAPI.get_row_by_index(0).cells as QueryList<CellType>).toArray()[1].nativeElement; expect(col2Header.offsetWidth - cell2.offsetWidth).toBeLessThanOrEqual(1); const col3Header = grid.getColumnByName('City').headerCell.nativeElement; const cell3 = (grid.gridAPI.get_row_by_index(0).cells as QueryList<CellType>).toArray()[2].nativeElement; expect(col3Header.offsetWidth).toEqual(cell3.offsetWidth); }); it('Width should be correct. Column group with three columns. Width in percent.', () => { const gridWidth = '50%'; grid.width = gridWidth; fixture.detectChanges(); const scrWitdh = grid.nativeElement.querySelector('.igx-grid__tbody-scrollbar').getBoundingClientRect().width; const gridWidthInPx = (parseInt(gridWidth, 10) / 100) * parseInt(componentInstance.gridWrapperWidthPx, 10) - scrWitdh; const colWidth = Math.floor(gridWidthInPx / 3); const colWidthPx = colWidth + 'px'; const locationColGroup = getColGroup(grid, 'Location'); expect(locationColGroup.width).toBe((Math.round(colWidth) * 3) + 'px'); const countryColumn = grid.getColumnByName('Country'); expect(countryColumn.width).toBe(colWidthPx); const regionColumn = grid.getColumnByName('Region'); expect(regionColumn.width).toBe(colWidthPx); const cityColumn = grid.getColumnByName('City'); expect(cityColumn.width).toBe(colWidthPx); }); it('Width should be correct. Column group with three columns. Column width in px.', () => { const gridColWidth = '200px'; grid.columnWidth = gridColWidth; fixture.detectChanges(); const locationColGroup = getColGroup(grid, 'Location'); const gridWidth = parseInt(gridColWidth, 10) * 3; expect(locationColGroup.width).toBe(gridWidth + 'px'); const countryColumn = grid.getColumnByName('Country'); expect(countryColumn.width).toBe(gridColWidth); const regionColumn = grid.getColumnByName('Region'); expect(regionColumn.width).toBe(gridColWidth); const cityColumn = grid.getColumnByName('City'); expect(cityColumn.width).toBe(gridColWidth); }); it('Width should be correct. Colum group with three columns. Column width in percent.', () => { const gridColWidth = '20%'; grid.columnWidth = gridColWidth; fixture.detectChanges(); const locationColGroup = getColGroup(grid, 'Location'); const expectedWidth = (Math.floor(grid.calcWidth * 0.2) * 3) + 'px'; expect(locationColGroup.width).toBe(expectedWidth); const countryColumn = grid.getColumnByName('Country'); expect(countryColumn.width).toBe(gridColWidth); const regionColumn = grid.getColumnByName('Region'); expect(regionColumn.width).toBe(gridColWidth); const cityColumn = grid.getColumnByName('City'); expect(cityColumn.width).toBe(gridColWidth); }); it('Width should be correct. Column group with three columns. Columns with width in px.', () => { const columnWidth = '200px'; componentInstance.columnWidth = columnWidth; fixture.detectChanges(); const locationColGroup = getColGroup(grid, 'Location'); const groupWidth = parseInt(columnWidth, 10) * 3; expect(locationColGroup.width).toBe(groupWidth + 'px'); const countryColumn = grid.getColumnByName('Country'); expect(countryColumn.width).toBe(columnWidth); const regionColumn = grid.getColumnByName('Region'); expect(regionColumn.width).toBe(columnWidth); const cityColumn = grid.getColumnByName('City'); expect(cityColumn.width).toBe(columnWidth); }); it('Width should be correct. Column group with three columns. Columns with width in percent.', () => { const columnWidth = '20%'; componentInstance.columnWidth = columnWidth; fixture.detectChanges(); const locationColGroup = getColGroup(grid, 'Location'); const expectedWidth = (Math.floor(grid.calcWidth * 0.2) * 3) + 'px'; expect(locationColGroup.width).toBe(expectedWidth); const countryColumn = grid.getColumnByName('Country'); expect(countryColumn.width).toBe(columnWidth); const regionColumn = grid.getColumnByName('Region'); expect(regionColumn.width).toBe(columnWidth); const cityColumn = grid.getColumnByName('City'); expect(cityColumn.width).toBe(columnWidth); }); }); describe('Column hiding: ', () => { beforeEach(fakeAsync(() => { fixture = TestBed.createComponent(ColumnGroupFourLevelTestComponent); fixture.detectChanges(); grid = fixture.componentInstance.grid; })); it('column hiding - verify grid after hiding the last column group', async () => { grid.navigateTo(0, 10); await wait(100); fixture.detectChanges(); await wait(250); fixture.detectChanges(); let headerDisplayContainer = fixture.debugElement.query(By.css('.igx-grid-thead__wrapper >* .igx-display-container')); let leftOffset = parseInt(headerDisplayContainer.styles.left, 10); expect(leftOffset).toBeLessThan(-600); const initialBodyHeight = parseInt(fixture.debugElement.query(By.css('.igx-grid__tbody-content')).styles.height, 10); const contactInfoGroup = grid.columns.find(c => c.header === 'Contact Information'); const groupWidth = contactInfoGroup.width; contactInfoGroup.hidden = true; fixture.detectChanges(); await wait(200); fixture.detectChanges(); headerDisplayContainer = fixture.debugElement.query(By.css('.igx-grid-thead__wrapper >* .igx-display-container')); const expectedOffset = leftOffset - parseInt(groupWidth, 10); leftOffset = parseInt(headerDisplayContainer.styles.left, 10); expect(parseInt(fixture.debugElement.query(By.css('.igx-grid__tbody-content')).styles.height, 10)).toEqual(initialBodyHeight); expect(leftOffset).toBeGreaterThanOrEqual(expectedOffset); }); it('column hiding - parent level', () => { const addressGroup = grid.columnList.filter(c => c.header === 'Address Information')[0]; addressGroup.hidden = true; fixture.detectChanges(); expect(GridFunctions.getColumnHeaders(fixture).length).toEqual(4); expect(GridFunctions.getColumnGroupHeaders(fixture).length).toEqual(2); }); it('column hiding - child level', () => { const addressGroup = fixture.componentInstance.addrInfoColGroup; addressGroup.children.first.hidden = true; fixture.detectChanges(); expect(GridFunctions.getColumnGroupHeaders(fixture).length).toEqual(5); expect(addressGroup.children.first.hidden).toBe(true); expect(addressGroup.children.first.children.toArray().every(c => c.hidden === true)).toEqual(true); }); it('column hiding - Verify column hiding of Individual column and Child column', () => { testGroupsAndColumns(7, 11, fixture); // Hide individual column grid.getColumnByName('ID').hidden = true; fixture.detectChanges(); testGroupsAndColumns(7, 10, fixture); // Hide column in goup grid.getColumnByName('CompanyName').hidden = true; fixture.detectChanges(); expect(GridFunctions.getColumnGroupHeaders(fixture).length).toEqual(7); expect(GridFunctions.getColumnHeaders(fixture).length).toEqual(9); grid.getColumnByName('Address').hidden = true; fixture.detectChanges(); testGroupsAndColumns(7, 8, fixture); }); it('column hiding - Verify when 2 of 2 child columns are hidden, the Grouped column would be hidden as well.', () => { testGroupsAndColumns(7, 11, fixture); // Hide 2 columns in the group grid.getColumnByName('ContactName').hidden = true; fixture.detectChanges(); grid.getColumnByName('ContactTitle').hidden = true; fixture.detectChanges(); testGroupsAndColumns(6, 9, fixture); expect(getColGroup(grid, 'Person Details').hidden).toEqual(true); // Show one of the columns grid.getColumnByName('ContactName').hidden = false; fixture.detectChanges(); testGroupsAndColumns(7, 10, fixture); expect(getColGroup(grid, 'Person Details').hidden).toEqual(false); }); it('column hiding - Verify when 1 child column and 1 group are hidden, the Grouped column would be hidden as well.', () => { testGroupsAndColumns(7, 11, fixture); // Hide 2 columns in the group grid.getColumnByName('CompanyName').hidden = true; fixture.detectChanges(); getColGroup(grid, 'Person Details').hidden = true; fixture.detectChanges(); testGroupsAndColumns(5, 8, fixture); expect(getColGroup(grid, 'General Information').hidden).toEqual(true); // Show the group getColGroup(grid, 'Person Details').hidden = false; fixture.detectChanges(); testGroupsAndColumns(7, 10, fixture); expect(getColGroup(grid, 'General Information').hidden).toEqual(false); }); }); describe('API methods tests ', () => { beforeEach(fakeAsync(() => { fixture = TestBed.createComponent(ColumnGroupFourLevelTestComponent); fixture.detectChanges(); grid = fixture.componentInstance.grid; })); it('API method level should return correct values', () => { grid.getColumnByName('Fax').hidden = true; fixture.detectChanges(); getColGroup(grid, 'Person Details').hidden = true; fixture.detectChanges(); expect(grid.columnList.filter(col => col.columnGroup).length).toEqual(7); // Get level of column expect(grid.getColumnByName('ID').level).toEqual(0); expect(grid.getColumnByName('CompanyName').level).toEqual(1); expect(grid.getColumnByName('Country').level).toEqual(2); expect(grid.getColumnByName('City').level).toEqual(3); expect(grid.getColumnByName('PostalCode').level).toEqual(2); // Get level of hidden column expect(grid.getColumnByName('Fax').level).toEqual(2); // Get level of column in hidden group expect(grid.getColumnByName('ContactTitle').level).toEqual(2); // Get level of grouped column expect(getColGroup(grid, 'General Information').level).toEqual(0); expect(getColGroup(grid, 'Location').level).toEqual(1); expect(getColGroup(grid, 'Location City').level).toEqual(2); expect(getColGroup(grid, 'Contact Information').level).toEqual(1); expect(getColGroup(grid, 'Postal Code').level).toEqual(1); // Get level of hidden group expect(getColGroup(grid, 'Person Details').level).toEqual(1); }); it('API method columnGroup should return correct values', () => { grid.getColumnByName('Fax').hidden = true; fixture.detectChanges(); getColGroup(grid, 'Person Details').hidden = true; fixture.detectChanges(); expect(grid.columnList.filter(col => col.columnGroup).length).toEqual(7); // Get columnGroup of column expect(grid.getColumnByName('ID').columnGroup).toEqual(false); expect(grid.getColumnByName('Fax').columnGroup).toEqual(false); expect(grid.getColumnByName('ContactTitle').columnGroup).toEqual(false); // Get columnGroup of grouped column expect(getColGroup(grid, 'General Information').columnGroup).toEqual(true); expect(getColGroup(grid, 'Location City').columnGroup).toEqual(true); expect(getColGroup(grid, 'Contact Information').columnGroup).toEqual(true); expect(getColGroup(grid, 'Postal Code').columnGroup).toEqual(true); expect(getColGroup(grid, 'Person Details').columnGroup).toEqual(true); }); it('API method allChildren should return correct values', () => { grid.getColumnByName('Fax').hidden = true; fixture.detectChanges(); getColGroup(grid, 'Person Details').hidden = true; fixture.detectChanges(); expect(grid.columnList.filter(col => col.columnGroup).length).toEqual(7); // Get allChildren of column expect(grid.getColumnByName('ID').allChildren.length).toEqual(0); expect(grid.getColumnByName('PostalCode').allChildren.length).toEqual(0); // Get allChildren of hidden column expect(grid.getColumnByName('Fax').allChildren.length).toEqual(0); // Get allChildren of group const genInfGroupedColumnAllChildren = getColGroup(grid, 'General Information').allChildren; expect(genInfGroupedColumnAllChildren.length).toEqual(4); expect(genInfGroupedColumnAllChildren.indexOf(getColGroup(grid, 'Person Details'))).toBeGreaterThanOrEqual(0); // Get allChildren of hidden group expect(getColGroup(grid, 'Person Details').allChildren.length).toEqual(2); // Get allChildren of group with one column const postCodeGroupedColumnAllChildren = getColGroup(grid, 'Postal Code').allChildren; expect(postCodeGroupedColumnAllChildren.length).toEqual(1); expect(postCodeGroupedColumnAllChildren.indexOf(grid.getColumnByName('PostalCode'))).toEqual(0); // Get allChildren of group with hidden columns and more levels const addressGroupedColumnAllChildren = getColGroup(grid, 'Address Information').allChildren; expect(addressGroupedColumnAllChildren.length).toEqual(11); expect(addressGroupedColumnAllChildren.indexOf(getColGroup(grid, 'Postal Code'))).toBeGreaterThanOrEqual(0); expect(addressGroupedColumnAllChildren.indexOf(grid.getColumnByName('PostalCode'))).toBeGreaterThanOrEqual(0); expect(addressGroupedColumnAllChildren.indexOf(grid.getColumnByName('Address'))).toBeGreaterThanOrEqual(0); expect(addressGroupedColumnAllChildren.indexOf(grid.getColumnByName('Country'))).toBeGreaterThanOrEqual(0); expect(addressGroupedColumnAllChildren.indexOf(grid.getColumnByName('Fax'))).toBeGreaterThanOrEqual(0); expect(addressGroupedColumnAllChildren.indexOf(getColGroup(grid, 'General Information'))).toEqual(-1); }); it('API method children should return correct values', () => { grid.getColumnByName('Fax').hidden = true; fixture.detectChanges(); getColGroup(grid, 'Person Details').hidden = true; fixture.detectChanges(); expect(grid.columnList.filter(col => col.columnGroup).length).toEqual(7); // Get children of grouped column expect(getColGroup(grid, 'General Information').children.length).toEqual(2); // Get children of hidden group expect(getColGroup(grid, 'Person Details').children.length).toEqual(2); // Get children of group with one column const postCodeGroupedColumnAllChildren = getColGroup(grid, 'Postal Code').children; expect(postCodeGroupedColumnAllChildren.length).toEqual(1); // Get children of group with more levels const addressGroupedColumnAllChildren = getColGroup(grid, 'Address Information').children; expect(addressGroupedColumnAllChildren.length).toEqual(3); }); it('API method topLevelParent should return correct values', () => { grid.getColumnByName('Fax').hidden = true; fixture.detectChanges(); getColGroup(grid, 'Person Details').hidden = true; fixture.detectChanges(); expect(grid.columnList.filter(col => col.columnGroup).length).toEqual(7); // Get topLevelParent of column with no group expect(grid.getColumnByName('ID').topLevelParent).toBeNull(); // Get topLevelParent of column const addressGroupedColumn = getColGroup(grid, 'Address Information'); expect(grid.getColumnByName('PostalCode').topLevelParent).toEqual(addressGroupedColumn); expect(grid.getColumnByName('Fax').topLevelParent).toEqual(addressGroupedColumn); expect(grid.getColumnByName('Country').topLevelParent).toEqual(addressGroupedColumn); const genInfGroupedColumn = getColGroup(grid, 'General Information'); expect(grid.getColumnByName('ContactName').topLevelParent).toEqual(genInfGroupedColumn); expect(grid.getColumnByName('CompanyName').topLevelParent).toEqual(genInfGroupedColumn); // Get topLevelParent of top group expect(genInfGroupedColumn.topLevelParent).toBeNull(); expect(addressGroupedColumn.topLevelParent).toBeNull(); // Get topLevelParent of group expect(getColGroup(grid, 'Person Details').topLevelParent).toEqual(genInfGroupedColumn); expect(getColGroup(grid, 'Postal Code').topLevelParent).toEqual(addressGroupedColumn); expect(getColGroup(grid, 'Location City').topLevelParent).toEqual(addressGroupedColumn); }); it('Should emit "columnInit" event when having multi-column headers.', () => { fixture = TestBed.createComponent(NestedColumnGroupsGridComponent); const ci = fixture.componentInstance; grid = ci.grid; spyOn(grid.columnInit, 'emit').and.callThrough(); fixture.detectChanges(); const colsCount = 4; const colGroupsCount = 3; expect(grid.columnInit.emit).toHaveBeenCalledTimes(colsCount + colGroupsCount); }); it('Should fire "columnInit" event when adding a multi-column header.', () => { fixture = TestBed.createComponent(DynamicGridComponent); componentInstance = fixture.componentInstance; grid = componentInstance.grid; fixture.detectChanges();