igniteui-angular-sovn
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
345 lines (294 loc) • 15.8 kB
text/typescript
import { TestBed, fakeAsync, tick, waitForAsync } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { IgxTreeGridComponent } from './tree-grid.component';
import { DisplayDensity } from '../../core/density';
import { configureTestSuite } from '../../test-utils/configure-suite';
import { By } from '@angular/platform-browser';
import {
IgxTreeGridWrappedInContComponent,
IgxTreeGridDefaultLoadingComponent,
IgxTreeGridCellSelectionComponent,
IgxTreeGridSummariesTransactionsComponent,
IgxTreeGridNoDataComponent,
IgxTreeGridWithNoForeignKeyComponent
} from '../../test-utils/tree-grid-components.spec';
import { wait } from '../../test-utils/ui-interactions.spec';
import { GridSelectionMode } from '../common/enums';
import { IgxStringFilteringOperand } from '../../data-operations/filtering-condition';
import { SampleTestData } from '../../test-utils/sample-test-data.spec';
import { SAFE_DISPOSE_COMP_ID } from '../../test-utils/grid-functions.spec';
describe('IgxTreeGrid Component Tests #tGrid', () => {
configureTestSuite();
const TBODY_CLASS = '.igx-grid__tbody-content';
let fix;
let grid: IgxTreeGridComponent;
beforeAll(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [
NoopAnimationsModule,
IgxTreeGridWrappedInContComponent,
IgxTreeGridDefaultLoadingComponent,
IgxTreeGridCellSelectionComponent,
IgxTreeGridSummariesTransactionsComponent,
IgxTreeGridNoDataComponent,
IgxTreeGridWithNoForeignKeyComponent
]
}).compileComponents();
}));
describe('IgxTreeGrid - default rendering for rows and columns', () => {
beforeEach(waitForAsync(() => {
fix = TestBed.createComponent(IgxTreeGridWrappedInContComponent);
grid = fix.componentInstance.treeGrid;
fix.detectChanges();
}));
it('should render 10 records if height is unset and parent container\'s height is unset', () => {
fix.detectChanges();
const defaultHeight = fix.debugElement.query(By.css(TBODY_CLASS)).styles.height;
expect(defaultHeight).not.toBeNull();
expect(parseInt(defaultHeight, 10)).toBeGreaterThan(400);
expect(fix.componentInstance.isVerticalScrollbarVisible()).toBeTruthy();
expect(grid.rowList.length).toBeGreaterThanOrEqual(10);
});
it('should match width and height of parent container when width/height are set in %', () => {
fix.componentInstance.outerWidth = 800;
fix.componentInstance.outerHeight = 600;
grid.width = '50%';
grid.height = '50%';
fix.detectChanges();
// fakeAsync is not needed. Need a second change detection cycle for height changes to be applied.
fix.detectChanges();
expect(window.getComputedStyle(grid.nativeElement).height).toMatch('300px');
expect(window.getComputedStyle(grid.nativeElement).width).toMatch('400px');
expect(grid.rowList.length).toBeGreaterThan(0);
});
it('should render 10 records if height is 100% and parent container\'s height is unset', () => {
grid.height = '600px';
fix.detectChanges();
// fakeAsync is not needed. Need a second change detection cycle for height changes to be applied.
fix.detectChanges();
const defaultHeight = fix.debugElement.query(By.css(TBODY_CLASS)).styles.height;
expect(defaultHeight).not.toBeNull();
expect(parseInt(defaultHeight, 10)).toBeGreaterThan(400);
expect(fix.componentInstance.isVerticalScrollbarVisible()).toBeTruthy();
expect(grid.rowList.length).toBeGreaterThanOrEqual(10);
});
it(`should render all records exactly if height is 100% and parent container\'s height is unset and
there are fewer than 10 records in the data view`, () => {
grid.height = '100%';
fix.componentInstance.data = fix.componentInstance.data.slice(0, 1);
fix.detectChanges();
// fakeAsync is not needed. Need a second change detection cycle for height changes to be applied.
fix.detectChanges();
const defaultHeight = fix.debugElement.query(By.css(TBODY_CLASS)).styles.height;
expect(defaultHeight).toBeFalsy();
expect(fix.componentInstance.isVerticalScrollbarVisible()).toBeFalsy();
expect(grid.rowList.length).toEqual(6);
});
it(`should render 11 records if height is 100% and parent container\'s height is unset and display density is changed`, () => {
grid.height = '100%';
fix.componentInstance.density = DisplayDensity.compact;
fix.detectChanges();
// fakeAsync is not needed. Need a second change detection cycle for height changes to be applied.
fix.detectChanges();
const defaultHeight = fix.debugElement.query(By.css(TBODY_CLASS)).styles.height;
const defaultHeightNum = parseInt(defaultHeight, 10);
expect(defaultHeight).not.toBeFalsy();
expect(defaultHeightNum).toBeGreaterThan(300);
expect(defaultHeightNum).toBeLessThanOrEqual(330);
expect(fix.componentInstance.isVerticalScrollbarVisible()).toBeTruthy();
expect(grid.rowList.length).toEqual(11);
});
it('should display horizontal scroll bar when column width is set in %', () => {
fix.detectChanges();
grid.columnList.get(0).width = '50%';
fix.detectChanges();
const horizontalScroll = fix.nativeElement.querySelector('igx-horizontal-virtual-helper');
expect(horizontalScroll.offsetWidth).toBeGreaterThanOrEqual(783);
expect(horizontalScroll.offsetWidth).toBeLessThanOrEqual(786);
expect(horizontalScroll.children[0].offsetWidth).toBeGreaterThanOrEqual(799);
expect(horizontalScroll.children[0].offsetWidth).toBeLessThanOrEqual(801);
});
it('checks if attributes are correctly assigned when grid has or does not have data', fakeAsync(() => {
// Checks if igx-grid__tbody-content attribute is null when there is data in the grid
const container = fix.nativeElement.querySelectorAll('.igx-grid__tbody-content')[0];
expect(container.getAttribute('role')).toBe(null);
//Filter grid so no results are available and grid is empty
grid.filter('Name', '111', IgxStringFilteringOperand.instance().condition('contains'), true);
fix.detectChanges();
fix.detectChanges();
expect(container.getAttribute('role')).toMatch('row');
// clear grid data and check if attribute is now 'row'
grid.clearFilter();
fix.componentInstance.clearData();
fix.detectChanges();
tick();
expect(container.getAttribute('role')).toMatch('row');
}));
it('should display flat data even if no foreignKey is set', () => {
fix = TestBed.createComponent(IgxTreeGridWithNoForeignKeyComponent);
grid = fix.componentInstance.treeGrid;
fix.detectChanges();
expect(grid.dataView.length).toBeGreaterThan(0);
});
});
describe('Auto-generated columns', () => {
beforeEach(waitForAsync(() => {
fix = TestBed.createComponent(IgxTreeGridComponent);
grid = fix.componentInstance;
grid.autoGenerate = true;
// When doing pure unit tests, the grid doesn't get removed after the test, because it overrides
// the element ID and the testbed cannot find it to remove it.
// The testbed is looking up components by [id^=root], so working around this by forcing root id
grid.id = SAFE_DISPOSE_COMP_ID;
}));
// afterEach(() => {
// // When doing pure unit tests, the grid doesn't get removed after the test, because it overrides
// // the element ID and the testbed cannot find it to remove it.
// // this is needed when we don't force a root id
// grid.ngOnDestroy();
// element.remove();
// });
it('should auto-generate all columns', () => {
grid.data = SampleTestData.employeePrimaryForeignKeyTreeData();
grid.primaryKey = 'ID';
grid.foreignKey = 'ParentID';
fix.detectChanges();
const expectedColumns = [...Object.keys(grid.data[0])];
expect(grid.columns.map(c => c.field)).toEqual(expectedColumns);
// Verify that records are also rendered by checking the first record cell
expect(grid.getCellByColumn(0, 'ID').value).toEqual(1);
});
it('should auto-generate columns without childDataKey', () => {
grid.data = SampleTestData.employeeAllTypesTreeData();
grid.childDataKey ='Employees';
fix.detectChanges();
const expectedColumns = [...Object.keys(grid.data[0])].filter(col => col !== grid.childDataKey);
// Employees shouldn't be in the columns
expect(grid.columns.map(c => c.field)).toEqual(expectedColumns);
// Verify that records are also rendered by checking the first record cell
expect(grid.getCellByColumn(0, 'ID').value).toEqual(147);
});
});
describe('Loading Template', () => {
beforeEach(waitForAsync(() => {
fix = TestBed.createComponent(IgxTreeGridDefaultLoadingComponent);
grid = fix.componentInstance.treeGrid;
}));
it('should auto-generate columns', async () => {
fix.detectChanges();
const gridElement = fix.debugElement.query(By.css('.igx-grid'));
let loadingIndicator = gridElement.query(By.css('.igx-grid__loading'));
expect(loadingIndicator).not.toBeNull();
expect(grid.dataRowList.length).toBe(0);
await wait(1000);
fix.detectChanges();
loadingIndicator = gridElement.query(By.css('.igx-grid__loading'));
expect(loadingIndicator).toBeNull();
expect(grid.dataRowList.length).toBeGreaterThan(0);
});
});
describe('Hide All', () => {
beforeEach(waitForAsync(() => {
fix = TestBed.createComponent(IgxTreeGridCellSelectionComponent);
grid = fix.componentInstance.treeGrid;
fix.detectChanges();
}));
it('should not render rows and headers group when all cols are hidden', fakeAsync(() => {
grid.rowSelection = GridSelectionMode.multiple;
grid.rowDraggable = true;
tick();
fix.detectChanges();
let fixEl = fix.nativeElement; let gridEl = grid.nativeElement;
let tHeadItems = fixEl.querySelector('igx-grid-header-group');
let gridRows = fixEl.querySelector('igx-tree-grid-row');
let paging = fixEl.querySelector('.igx-paginator');
let rowSelectors = gridEl.querySelector('.igx-checkbox');
let dragIndicators = gridEl.querySelector('.igx-grid__drag-indicator');
let verticalScrollBar = gridEl.querySelector('.igx-grid__tbody-scrollbar[hidden]');
expect(tHeadItems).not.toBeNull();
expect(gridRows).not.toBeNull();
expect(paging).not.toBeNull();
expect(rowSelectors).not.toBeNull();
expect(dragIndicators).not.toBeNull();
expect(verticalScrollBar).toBeNull();
grid.columnList.forEach((col) => col.hidden = true);
tick();
fix.detectChanges();
fixEl = fix.nativeElement;
gridEl = grid.nativeElement;
tHeadItems = fixEl.querySelector('igx-grid-header-group');
gridRows = fixEl.querySelector('igx-tree-grid-row');
paging = fixEl.querySelector('.igx-paginator');
rowSelectors = gridEl.querySelector('.igx-checkbox');
dragIndicators = gridEl.querySelector('.igx-grid__drag-indicator');
verticalScrollBar = gridEl.querySelector('.igx-grid__tbody-scrollbar[hidden]');
expect(tHeadItems).toBeNull();
expect(gridRows).toBeNull();
expect(paging).not.toBeNull();
expect(rowSelectors).toBeNull();
expect(dragIndicators).toBeNull();
expect(verticalScrollBar).not.toBeNull();
}));
});
describe('Setting null data', () => {
it('should not throw error when data is null', () => {
fix = TestBed.createComponent(IgxTreeGridNoDataComponent);
fix.componentInstance.treeGrid.batchEditing = true;
expect(() => fix.detectChanges()).not.toThrow();
});
it('should not throw error when data is set to null', () => {
fix = TestBed.createComponent(IgxTreeGridCellSelectionComponent);
fix.componentInstance.data = null;
expect(() => fix.detectChanges()).not.toThrow();
});
it('should not throw error when data is set to null and transactions are enabled', () => {
fix = TestBed.createComponent(IgxTreeGridSummariesTransactionsComponent);
fix.componentInstance.data = null;
expect(() => fix.detectChanges()).not.toThrow();
});
it('should not throw error when data is null and row is pinned', () => {
fix = TestBed.createComponent(IgxTreeGridNoDataComponent);
grid = fix.componentInstance.treeGrid;
grid.pinRow(4);
expect(() => fix.detectChanges()).not.toThrow();
});
});
describe('Displaying empty grid message', () => {
beforeEach(waitForAsync(() => {
fix = TestBed.createComponent(IgxTreeGridWrappedInContComponent);
grid = fix.componentInstance.treeGrid;
fix.detectChanges();
}));
it('should display empty grid message when there is no data', () => {
const data: any[] = grid.data;
grid.data = [];
fix.detectChanges();
let emptyGridMessage = fix.debugElement.query(By.css('.igx-grid__tbody-message'));
expect(emptyGridMessage).toBeTruthy();
expect(emptyGridMessage.nativeElement.innerText).toBe('Grid has no data.');
grid.data = data;
fix.detectChanges();
emptyGridMessage = fix.debugElement.query(By.css('.igx-grid__tbody-message'));
expect(emptyGridMessage).toBeFalsy();
});
it('should display empty grid message when last row is deleted', () => {
grid.data = [];
grid.addRow({
ID: 0,
Name: 'John Winchester',
HireDate: new Date(2008, 3, 20),
Age: 55,
OnPTO: false,
Employees: []
});
fix.detectChanges();
let emptyGridMessage = fix.debugElement.query(By.css('.igx-grid__tbody-message'));
expect(emptyGridMessage).toBeFalsy();
grid.deleteRowById(0);
fix.detectChanges();
emptyGridMessage = fix.debugElement.query(By.css('.igx-grid__tbody-message'));
expect(emptyGridMessage).toBeTruthy();
expect(emptyGridMessage.nativeElement.innerText).toBe('Grid has no data.');
});
});
});