igniteui-angular-sovn
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
1,174 lines (918 loc) • 60.8 kB
text/typescript
import { TestBed, waitForAsync } from '@angular/core/testing';
import { IgxGridComponent } from '../../grids/grid/grid.component';
import { IColumnExportingEventArgs, IRowExportingEventArgs } from '../exporter-common/base-export-service';
import { ExportUtilities } from '../exporter-common/export-utilities';
import { TestMethods } from '../exporter-common/test-methods.spec';
import { IgxExcelExporterService } from './excel-exporter';
import { IgxExcelExporterOptions } from './excel-exporter-options';
import { ZipWrapper } from './zip-verification-wrapper.spec';
import { FileContentData } from './test-data.service.spec';
import {
ReorderedColumnsComponent,
GridIDNameJobTitleComponent,
ProductsComponent,
GridIDNameJobTitleHireDataPerformanceComponent,
GridHireDateComponent,
GridExportGroupedDataComponent,
MultiColumnHeadersExportComponent,
GridWithEmptyColumnsComponent,
ColumnsAddedOnInitComponent,
GridWithThreeLevelsOfMultiColumnHeadersAndTwoRowsExportComponent,
GroupedGridWithSummariesComponent,
GridCurrencySummariesComponent,
GridUserMeetingDataComponent
} from '../../test-utils/grid-samples.spec';
import { SampleTestData } from '../../test-utils/sample-test-data.spec';
import { first } from 'rxjs/operators';
import { DefaultSortingStrategy, SortingDirection } from '../../data-operations/sorting-strategy';
import { IgxStringFilteringOperand } from '../../data-operations/filtering-condition';
import { configureTestSuite } from '../../test-utils/configure-suite';
import { IgxTreeGridPrimaryForeignKeyComponent, IgxTreeGridSummariesKeyComponent } from '../../test-utils/tree-grid-components.spec';
import { IgxTreeGridComponent } from '../../grids/tree-grid/public_api';
import { IgxNumberFilteringOperand } from '../../data-operations/filtering-condition';
import { UIInteractions, wait } from '../../test-utils/ui-interactions.spec';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { FilteringExpressionsTree } from '../../data-operations/filtering-expressions-tree';
import { FilteringLogic } from '../../data-operations/filtering-expression.interface';
import { IgxHierarchicalGridExportComponent,
IgxHierarchicalGridMultiColumnHeaderIslandsExportComponent,
IgxHierarchicalGridMultiColumnHeadersExportComponent,
IgxHierarchicalGridSummariesExportComponent
} from '../../test-utils/hierarchical-grid-components.spec';
import { IgxHierarchicalGridComponent } from '../../grids/hierarchical-grid/public_api';
import { IgxHierarchicalRowComponent } from '../../grids/hierarchical-grid/hierarchical-row.component';
import { GridFunctions } from '../../test-utils/grid-functions.spec';
import { IgxPivotGridMultipleRowComponent, IgxPivotGridTestComplexHierarchyComponent } from '../../test-utils/pivot-grid-samples.spec';
import { IgxPivotGridComponent } from '../../grids/pivot-grid/public_api';
describe('Excel Exporter', () => {
configureTestSuite();
let exporter: IgxExcelExporterService;
let actualData: FileContentData;
let options: IgxExcelExporterOptions;
beforeAll(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [
NoopAnimationsModule,
ReorderedColumnsComponent,
GridIDNameJobTitleComponent,
IgxTreeGridPrimaryForeignKeyComponent,
ProductsComponent,
GridWithEmptyColumnsComponent,
GridIDNameJobTitleHireDataPerformanceComponent,
GridHireDateComponent,
GridExportGroupedDataComponent,
IgxHierarchicalGridExportComponent,
MultiColumnHeadersExportComponent,
IgxHierarchicalGridMultiColumnHeadersExportComponent,
ColumnsAddedOnInitComponent,
IgxHierarchicalGridMultiColumnHeaderIslandsExportComponent,
GridWithThreeLevelsOfMultiColumnHeadersAndTwoRowsExportComponent,
IgxPivotGridMultipleRowComponent,
IgxPivotGridTestComplexHierarchyComponent,
IgxTreeGridSummariesKeyComponent,
IgxHierarchicalGridSummariesExportComponent,
GroupedGridWithSummariesComponent,
GridCurrencySummariesComponent,
GridUserMeetingDataComponent
]
}).compileComponents();
}));
beforeEach(waitForAsync(() => {
exporter = new IgxExcelExporterService();
actualData = new FileContentData();
// Spy the saveBlobToFile method so the files are not really created
spyOn(ExportUtilities as any, 'saveBlobToFile');
}));
afterEach(waitForAsync(() => {
exporter.columnExporting.unsubscribe();
exporter.rowExporting.unsubscribe();
}));
describe('', () => {
beforeEach(waitForAsync(() => {
options = createExportOptions('GridExcelExport', 50);
}));
it('should export grid as displayed.', async () => {
const currentGrid: IgxGridComponent = null;
await TestMethods.testRawData(currentGrid, async (grid) => {
await exportAndVerify(grid, options, actualData.simpleGridData);
});
});
it('should honor \'ignoreFiltering\' option.', async () => {
const result = await TestMethods.createGridAndFilter();
const fix = result.fixture;
const grid = result.grid;
expect(grid.rowList.length).toEqual(1);
options.ignoreFiltering = false;
fix.detectChanges();
let wrapper = await getExportedData(grid, options);
await wrapper.verifyDataFilesContent(actualData.simpleGridDataRecord5, 'One row only should have been exported!');
options.ignoreFiltering = true;
fix.detectChanges();
wrapper = await getExportedData(grid, options);
await wrapper.verifyDataFilesContent(actualData.simpleGridData, 'All 10 rows should have been exported!');
});
it('should honor filter criteria changes.', async () => {
const result = await TestMethods.createGridAndFilter();
const fix = result.fixture;
const grid = result.grid;
expect(grid.rowList.length).toEqual(1);
options.ignoreFiltering = false;
let wrapper = await getExportedData(grid, options);
await wrapper.verifyDataFilesContent(actualData.simpleGridDataRecord5, 'One row should have been exported!');
grid.filter('JobTitle', 'Director', IgxStringFilteringOperand.instance().condition('equals'), true);
fix.detectChanges();
expect(grid.rowList.length).toEqual(2, 'Invalid number of rows after filtering!');
wrapper = await getExportedData(grid, options);
await wrapper.verifyDataFilesContent(actualData.simpleGridDataDirectors, 'Two rows should have been exported!');
});
it('should honor \'ignoreColumnsVisibility\' option.', async () => {
const fix = TestBed.createComponent(GridIDNameJobTitleComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
grid.columnList.get(0).hidden = true;
options.ignoreColumnsVisibility = false;
fix.detectChanges();
expect(grid.visibleColumns.length).toEqual(2, 'Invalid number of visible columns!');
let wrapper = await getExportedData(grid, options);
await wrapper.verifyDataFilesContent(actualData.simpleGridNameJobTitle, 'Two columns should have been exported!');
options.ignoreColumnsVisibility = true;
fix.detectChanges();
wrapper = await getExportedData(grid, options);
await wrapper.verifyDataFilesContent(actualData.simpleGridData, 'All three columns should have been exported!');
});
it('should honor columns visibility changes.', async () => {
const fix = TestBed.createComponent(GridIDNameJobTitleComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
options.ignoreColumnsVisibility = false;
expect(grid.visibleColumns.length).toEqual(3, 'Invalid number of visible columns!');
let wrapper = await getExportedData(grid, options);
await wrapper.verifyDataFilesContent(actualData.simpleGridData, 'All columns should have been exported!');
grid.columnList.get(0).hidden = true;
fix.detectChanges();
expect(grid.visibleColumns.length).toEqual(2, 'Invalid number of visible columns!');
wrapper = await getExportedData(grid, options);
await wrapper.verifyDataFilesContent(actualData.simpleGridNameJobTitle, 'Two columns should have been exported!');
grid.columnList.get(0).hidden = false;
fix.detectChanges();
expect(grid.visibleColumns.length).toEqual(3, 'Invalid number of visible columns!');
wrapper = await getExportedData(grid, options);
await wrapper.verifyDataFilesContent(actualData.simpleGridData, 'All columns should have been exported!');
grid.columnList.get(0).hidden = undefined;
fix.detectChanges();
expect(grid.visibleColumns.length).toEqual(3, 'Invalid number of visible columns!');
wrapper = await getExportedData(grid, options);
await wrapper.verifyDataFilesContent(actualData.simpleGridData, 'All columns should have been exported!');
});
it('should honor columns declaration order.', async () => {
const fix = TestBed.createComponent(ReorderedColumnsComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
const wrapper = await getExportedData(grid, options);
await wrapper.verifyDataFilesContent(actualData.simpleGridNameJobTitleID);
});
it('should honor \'ignorePinning\' option.', async () => {
const result = await TestMethods.createGridAndPinColumn([1]);
const fix = result.fixture;
const grid = result.grid;
options.ignorePinning = false;
fix.detectChanges();
let wrapper = await getExportedData(grid, options);
wrapper.verifyStructure();
// await wrapper.verifyTemplateFilesContent();
await wrapper.verifyDataFilesContent(actualData.gridNameFrozen, 'One frozen column should have been exported!');
options.ignorePinning = true;
fix.detectChanges();
wrapper = await getExportedData(grid, options);
await wrapper.verifyDataFilesContent(actualData.gridNameIDJobTitle, 'No frozen columns should have been exported!');
});
it('should honor pinned state changes.', async () => {
const result = await TestMethods.createGridAndPinColumn([1]);
const fix = result.fixture;
const grid = result.grid;
let wrapper = await getExportedData(grid, options);
await wrapper.verifyDataFilesContent(actualData.gridNameFrozen, 'One frozen column should have been exported!');
grid.columnList.get(1).pinned = false;
fix.detectChanges();
wrapper = await getExportedData(grid, options);
await wrapper.verifyDataFilesContent(actualData.simpleGridData, 'No frozen columns should have been exported!');
});
it('should honor all pinned columns.', async () => {
const result = await TestMethods.createGridAndPinColumn(2, 0);
const grid = result.grid;
const wrapper = await getExportedData(grid, options);
wrapper.verifyStructure();
await wrapper.verifyDataFilesContent(actualData.gridJobTitleIdFrozen, 'Not all pinned columns are frozen in the export!');
});
it('should honor \'freezeHeaders\' option.', async () => {
const result = await TestMethods.createGridAndPinColumn([1]);
const fix = result.fixture;
const grid = result.grid;
options.ignorePinning = false;
options.freezeHeaders = true;
fix.detectChanges();
let wrapper = await getExportedData(grid, options);
wrapper.verifyStructure();
await wrapper.verifyDataFilesContent(actualData.gridNameFrozenHeaders,
'One frozen column and frozen headers should have been exported!');
options.ignorePinning = true;
fix.detectChanges();
wrapper = await getExportedData(grid, options);
await wrapper.verifyDataFilesContent(actualData.gridFrozenHeaders,
'No frozen columns and frozen headers should have been exported!');
options.freezeHeaders = false;
fix.detectChanges();
wrapper = await getExportedData(grid, options);
await wrapper.verifyDataFilesContent(actualData.gridNameIDJobTitle,
'No frozen columns and no frozen headers should have been exported!');
});
it('should honor applied sorting.', async () => {
const fix = TestBed.createComponent(GridIDNameJobTitleComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
grid.sort({fieldName: 'Name', dir: SortingDirection.Asc, ignoreCase: true, strategy: DefaultSortingStrategy.instance()});
fix.detectChanges();
const wrapper = await getExportedData(grid, options);
await wrapper.verifyDataFilesContent(actualData.simpleGridSortByName);
// XXX : ???? What's the point of this?
// grid.clearSort();
// fix.detectChanges();
});
it('should honor changes in applied sorting.', async () => {
const fix = TestBed.createComponent(GridIDNameJobTitleComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
grid.sort({fieldName: 'Name', dir: SortingDirection.Asc, ignoreCase: true, strategy: DefaultSortingStrategy.instance()});
fix.detectChanges();
let wrapper = await getExportedData(grid, options);
await wrapper.verifyDataFilesContent(actualData.simpleGridSortByName, 'Ascending sorted data should have been exported.');
grid.sort({fieldName: 'Name', dir: SortingDirection.Desc, ignoreCase: true, strategy: DefaultSortingStrategy.instance()});
fix.detectChanges();
wrapper = await getExportedData(grid, options);
await wrapper.verifyDataFilesContent(
actualData.simpleGridSortByNameDesc(), 'Descending sorted data should have been exported.');
grid.clearSort();
grid.sort({fieldName: 'ID', dir: SortingDirection.Asc, ignoreCase: true, strategy: DefaultSortingStrategy.instance()});
fix.detectChanges();
// wrapper = await getExportedData(grid, options);
// await wrapper.verifyDataFilesContent(actualData.simpleGridSortByNameDesc(false), 'Unsorted data should have been exported.');
});
it('should export all columns with the width specified in options.', async () => {
const fix = TestBed.createComponent(GridIDNameJobTitleComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
grid.columnList.get(1).hidden = true;
grid.columnList.get(2).hidden = true;
const columnWidths = [100, 200, 0, null];
fix.detectChanges();
await setColWidthAndExport(grid, options, fix, columnWidths[0]);
await setColWidthAndExport(grid, options, fix, columnWidths[1]);
await setColWidthAndExport(grid, options, fix, columnWidths[2]);
await setColWidthAndExport(grid, options, fix, columnWidths[3]);
});
it('should export all rows with the height specified in options.', async () => {
const fix = TestBed.createComponent(GridIDNameJobTitleComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
const rowHeights = [20, 40, 0, undefined, null];
await setRowHeightAndExport(grid, options, fix, rowHeights[0]);
await setRowHeightAndExport(grid, options, fix, rowHeights[1]);
await setRowHeightAndExport(grid, options, fix, rowHeights[2]);
await setRowHeightAndExport(grid, options, fix, rowHeights[3]);
await setRowHeightAndExport(grid, options, fix, rowHeights[4]);
});
it('should fire \'columnExporting\' for each grid column.', async () => {
const fix = TestBed.createComponent(GridIDNameJobTitleComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
const cols = [];
exporter.columnExporting.subscribe((value) => {
cols.push({ header: value.header, index: value.columnIndex });
});
await getExportedData(grid, options);
expect(cols.length).toBe(3);
expect(cols[0].header).toBe('ID');
expect(cols[0].index).toBe(0);
expect(cols[1].header).toBe('Name');
expect(cols[1].index).toBe(1);
expect(cols[2].header).toBe('JobTitle');
expect(cols[2].index).toBe(2);
});
it('should fire \'columnExporting\' for each visible grid column.', async () => {
const fix = TestBed.createComponent(GridIDNameJobTitleComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
const cols = [];
exporter.columnExporting.subscribe((value) => {
cols.push({ header: value.header, index: value.columnIndex });
});
grid.columnList.get(0).hidden = true;
options.ignoreColumnsVisibility = false;
fix.detectChanges();
const wrapper = await getExportedData(grid, options);
expect(cols.length).toBe(2);
expect(cols[0].header).toBe('Name');
expect(cols[0].index).toBe(0);
expect(cols[1].header).toBe('JobTitle');
expect(cols[1].index).toBe(1);
await wrapper.verifyDataFilesContent(actualData.simpleGridNameJobTitle);
});
it('should not export columns when \'columnExporting\' is canceled.', async () => {
const fix = TestBed.createComponent(GridIDNameJobTitleComponent);
options.alwaysExportHeaders = false;
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
exporter.columnExporting.subscribe((value: IColumnExportingEventArgs) => {
value.cancel = true;
});
const wrapper = await getExportedData(grid, options);
expect(wrapper.hasValues).toBe(false);
wrapper.verifyStructure();
await wrapper.verifyTemplateFilesContent();
});
it('should export the column at the specified index when \'columnIndex\' is set during \'columnExporting\' event.', async () => {
const fix = TestBed.createComponent(GridIDNameJobTitleComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
exporter.columnExporting.subscribe((value: IColumnExportingEventArgs) => {
if (value.columnIndex === 0) {
value.columnIndex = 2;
}
});
await exportAndVerify(grid, options, actualData.simpleGridNameJobTitleID);
});
it('should export the column at the specified index when \'columnIndex\' is set during \'columnExporting\' (2).', async () => {
const fix = TestBed.createComponent(GridIDNameJobTitleComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
exporter.columnExporting.subscribe((value: IColumnExportingEventArgs) => {
if (value.columnIndex === 2) {
value.columnIndex = 0;
}
});
await exportAndVerify(grid, options, actualData.simpleGridJobTitleIDName);
});
it('should handle gracefully setting \'columnIndex\' to an invalid value.', async () => {
const fix = TestBed.createComponent(GridIDNameJobTitleComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
exporter.columnExporting.subscribe((value: IColumnExportingEventArgs) => {
if (value.columnIndex === 0) {
value.columnIndex = 4;
} else if (value.columnIndex === 2) {
value.columnIndex = -1;
}
});
await exportAndVerify(grid, options, actualData.simpleGridNameJobTitleID);
});
it('should fire \'rowExporting\' for each grid row.', async () => {
const fix = TestBed.createComponent(GridIDNameJobTitleComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
const data = SampleTestData.personJobData();
const rows = [];
exporter.rowExporting.subscribe((value: IRowExportingEventArgs) => {
rows.push({ data: value.rowData, index: value.rowIndex });
});
await getExportedData(grid, options);
expect(rows.length).toBe(10);
for (let i = 0; i < rows.length; i++) {
expect(rows[i].index).toBe(i);
expect(JSON.stringify(rows[i].data)).toBe(JSON.stringify(data[i]));
}
});
it('should not export rows when \'rowExporting\' is canceled.', async () => {
const fix = TestBed.createComponent(GridIDNameJobTitleComponent);
options.alwaysExportHeaders = false;
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
exporter.rowExporting.subscribe((value: IRowExportingEventArgs) => {
value.cancel = true;
});
const wrapper = await getExportedData(grid, options);
expect(wrapper.hasValues).toBe(false);
wrapper.verifyStructure();
await wrapper.verifyTemplateFilesContent();
});
it('shouldn\'t affect grid sort expressions', async () => {
const fix = TestBed.createComponent(GridIDNameJobTitleComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
grid.columnList.get(1).header = 'My header';
grid.columnList.get(1).sortable = true;
grid.sort({fieldName: 'Name', dir: SortingDirection.Desc, ignoreCase: false});
const sortField = grid.sortingExpressions[0].fieldName;
fix.detectChanges();
await getExportedData(grid, options);
fix.detectChanges();
await getExportedData(grid, options);
const sortFieldAfterExport = grid.sortingExpressions[0].fieldName;
expect(sortField).toBe(sortFieldAfterExport);
});
it('should skip the column formatter when \'columnExporting\' skipFormatter is true', async () => {
const fix = TestBed.createComponent(GridIDNameJobTitleComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
// Set column formatters
grid.columnList.get(0).formatter = ((val: number) => {
const numbers = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine' , 'ten'];
return numbers[val - 1];
});
grid.cdr.detectChanges();
fix.detectChanges();
// Verify the exported data is formatted by default
await exportAndVerify(grid, options, actualData.simpleGridNameJobTitleWithFormatting);
exporter.columnExporting.subscribe((val: IColumnExportingEventArgs) => {
val.skipFormatter = true;
});
fix.detectChanges();
grid.cdr.detectChanges();
// Verify the data without formatting
await exportAndVerify(grid, options, actualData.simpleGridData);
exporter.columnExporting.subscribe((val: IColumnExportingEventArgs) => {
val.skipFormatter = false;
});
grid.cdr.detectChanges();
fix.detectChanges();
// Verify the exported data with formatting
await exportAndVerify(grid, options, actualData.simpleGridNameJobTitleWithFormatting);
});
it('should export columns without header', async () => {
const fix = TestBed.createComponent(GridWithEmptyColumnsComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
// Verify the data without formatting
await exportAndVerify(grid, options, actualData.gridWithEmptyColums);
exporter.columnExporting.subscribe((value: IColumnExportingEventArgs) => {
if (value.columnIndex === 0 || value.columnIndex === 2) {
value.cancel = true;
}
});
await exportAndVerify(grid, options, actualData.simpleGridData);
});
it('Should honor Advanced filters when exporting', async () => {
const fix = TestBed.createComponent(GridIDNameJobTitleComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
const tree = new FilteringExpressionsTree(FilteringLogic.And);
tree.filteringOperands.push({
fieldName: 'Name',
searchVal: 'a',
condition: IgxStringFilteringOperand.instance().condition('contains'),
ignoreCase: true
});
tree.filteringOperands.push({
fieldName: 'Name',
searchVal: 'r',
condition: IgxStringFilteringOperand.instance().condition('contains'),
ignoreCase: true
});
tree.filteringOperands.push({
fieldName: 'ID',
searchVal: 5,
condition: IgxNumberFilteringOperand.instance().condition('greaterThan'),
});
grid.advancedFilteringExpressionsTree = tree;
fix.detectChanges();
grid.cdr.detectChanges();
await wait();
expect(grid.filteredData.length).toBe(4);
// Export and verify
await exportAndVerify(grid, options, actualData.gridWithAdvancedFilters);
});
it('Should set worksheet name', async () => {
const fix = TestBed.createComponent(GridIDNameJobTitleComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
const worksheetName = 'NewWorksheetName';
await setWorksheetNameAndExport(grid, options, fix, worksheetName);
});
it('Should export arrays as strings.', async () => {
const fix = TestBed.createComponent(GridIDNameJobTitleHireDataPerformanceComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
await exportAndVerify(grid, options, actualData.personJobHoursDataPerformance);
});
it('Should export dates correctly.', async () => {
const fix = TestBed.createComponent(GridHireDateComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
await exportAndVerify(grid, options, actualData.hireDate);
});
it('Should export grouped grid', async () => {
const fix = TestBed.createComponent(GridExportGroupedDataComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
grid.groupBy({ fieldName: 'Brand', dir: SortingDirection.Asc, ignoreCase: false });
grid.groupBy({ fieldName: 'Price', dir: SortingDirection.Desc, ignoreCase: false });
fix.detectChanges();
await exportAndVerify(grid, options, actualData.exportGroupedData);
});
it('Should export grouped grid with collapsed rows', async () => {
const fix = TestBed.createComponent(GridExportGroupedDataComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
grid.groupBy({ fieldName: 'Brand', dir: SortingDirection.Asc, ignoreCase: false });
grid.groupBy({ fieldName: 'Price', dir: SortingDirection.Desc, ignoreCase: false });
fix.detectChanges();
const groupRows = grid.groupsRecords;
grid.toggleGroup(groupRows[0].groups[1]);
grid.toggleGroup(groupRows[1]);
grid.toggleGroup(groupRows[1].groups[2]);
fix.detectChanges();
await exportAndVerify(grid, options, actualData.exportGroupedDataWithCollapsedRows);
});
it('Should export grouped grid with ignored sorting', async () => {
const fix = TestBed.createComponent(GridExportGroupedDataComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
grid.groupBy({ fieldName: 'Brand', dir: SortingDirection.Asc, ignoreCase: false });
grid.sort({fieldName: 'Price', dir: SortingDirection.Desc});
options.ignoreSorting = true;
fix.detectChanges();
await exportAndVerify(grid, options, actualData.exportGroupedDataWithIgnoreSorting);
});
it('Should export grouped grid with ignored filtering', async () => {
const fix = TestBed.createComponent(GridExportGroupedDataComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
grid.groupBy({ fieldName: 'Brand', dir: SortingDirection.Asc, ignoreCase: false });
grid.filter('Model', 'Model', IgxStringFilteringOperand.instance().condition('contains'), true);
fix.detectChanges();
options.ignoreFiltering = true;
fix.detectChanges();
await exportAndVerify(grid, options, actualData.exportGroupedDataWithIgnoreFiltering);
});
it('Should export grouped grid with ignored grouping', async () => {
const fix = TestBed.createComponent(GridExportGroupedDataComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
grid.groupBy({ fieldName: 'Brand', dir: SortingDirection.Asc, ignoreCase: false });
options.ignoreGrouping = true;
fix.detectChanges();
await exportAndVerify(grid, options, actualData.exportGroupedDataWithIgnoreGrouping);
});
it('should map dynamically added data & columns properly (#9872).', async () => {
const fix = TestBed.createComponent(ColumnsAddedOnInitComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
await exportAndVerify(grid, options, actualData.columnsAddedOnInit);
});
it('Should escape special chars in headers', async () => {
const fix = TestBed.createComponent(GridIDNameJobTitleHireDataPerformanceComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
grid.columnList.get(1).header = '&';
grid.columnList.get(2).header = '<>';
grid.columnList.get(3).header = '"';
grid.columnList.get(4).header = '\'';
await exportAndVerify(grid, options, actualData.exportGridDataWithSpecialCharsInHeaders);
});
it('Should export date, dateTime, time and percent columns correctly', async () => {
const fix = TestBed.createComponent(GridUserMeetingDataComponent);
fix.detectChanges();
await wait();
const grid = fix.componentInstance.grid;
await exportAndVerify(grid, options, actualData.exportGriWithDateData);
});
});
describe('', () => {
let fix;
let hGrid;
beforeEach(waitForAsync(() => {
options = createExportOptions('HierarchicalGridExcelExport');
fix = TestBed.createComponent(IgxHierarchicalGridExportComponent);
fix.detectChanges();
hGrid = fix.componentInstance.hGrid;
}));
it('should export hierarchical grid', async () => {
await exportAndVerify(hGrid, options, actualData.exportHierarchicalData);
});
it('should export hierarchical grid respecting options width.', async () => {
options = createExportOptions('HierarchicalGridExcelExport', 50);
await exportAndVerify(hGrid, options, actualData.exportHierarchicalDataWithColumnWidth);
});
it('should export sorted hierarchical grid data', async () => {
hGrid.sort({fieldName: 'GrammyNominations', dir: SortingDirection.Desc});
fix.detectChanges();
await exportAndVerify(hGrid, options, actualData.exportSortedHierarchicalData);
});
it('should export hierarchical grid data with ignored sorting', async () => {
hGrid.sort({fieldName: 'GrammyNominations', dir: SortingDirection.Desc});
options.ignoreSorting = true;
fix.detectChanges();
await exportAndVerify(hGrid, options, actualData.exportHierarchicalData);
});
it('should export filtered hierarchical grid data', async () => {
hGrid.filter('Debut', '2009', IgxStringFilteringOperand.instance().condition('contains'), true);
fix.detectChanges();
await exportAndVerify(hGrid, options, actualData.exportFilteredHierarchicalData);
});
it('should export hierarchical grid data with ignored filtering', async () => {
hGrid.filter('Debut', '2009', IgxStringFilteringOperand.instance().condition('contains'), true);
fix.detectChanges();
options.ignoreFiltering = true;
await exportAndVerify(hGrid, options, actualData.exportHierarchicalData);
});
it('should export hierarchical grid with expanded rows.', async () => {
const firstRow = hGrid.gridAPI.get_row_by_index(0) as IgxHierarchicalRowComponent;
const secondRow = hGrid.gridAPI.get_row_by_index(1) as IgxHierarchicalRowComponent;
UIInteractions.simulateClickAndSelectEvent(firstRow.expander);
fix.detectChanges();
expect(firstRow.expanded).toBe(true);
let childGrids = hGrid.gridAPI.getChildGrids(false);
const firstChildGrid = childGrids[0];
const firstChildRow = firstChildGrid.gridAPI.get_row_by_index(2) as IgxHierarchicalRowComponent;
UIInteractions.simulateClickAndSelectEvent(firstChildRow.expander);
fix.detectChanges();
expect(firstChildRow.expanded).toBe(true);
const secondChildGrid = childGrids[1];
const secondChildRow = secondChildGrid.gridAPI.get_row_by_index(0) as IgxHierarchicalRowComponent;
UIInteractions.simulateClickAndSelectEvent(secondChildRow.expander);
fix.detectChanges();
expect(secondChildRow.expanded).toBe(true);
UIInteractions.simulateClickAndSelectEvent(secondRow.expander);
fix.detectChanges();
expect(secondRow.expanded).toBe(true);
childGrids = hGrid.gridAPI.getChildGrids(false);
const thirdChildGrid = childGrids[3];
const thirdChildRow = thirdChildGrid.gridAPI.get_row_by_index(0) as IgxHierarchicalRowComponent;
UIInteractions.simulateClickAndSelectEvent(thirdChildRow.expander);
fix.detectChanges();
expect(thirdChildRow.expanded).toBe(true);
await exportAndVerify(hGrid, options, actualData.exportHierarchicalDataWithExpandedRows);
});
it('should export hierarchical grid data with frozen headers', async () => {
options.freezeHeaders = true;
fix.detectChanges();
await exportAndVerify(hGrid, options, actualData.exportHierarchicalDataWithFrozenHeaders);
});
it('should export hierarchical grid with skipped columns', async () => {
exporter.columnExporting.subscribe((args: IColumnExportingEventArgs) => {
if (args.header === 'Debut' ||
args.header === 'Billboard Review' ||
args.header === 'Album' ||
args.header === 'Tickets Sold' ||
args.header === 'Released') {
args.cancel = true;
}
});
fix.detectChanges();
await exportAndVerify(hGrid, options, actualData.exportHierarchicalDataWithSkippedColumns);
});
});
describe('', () => {
it('should export hierarchical grid with multi column headers', async () => {
const fix = TestBed.createComponent(IgxHierarchicalGridMultiColumnHeadersExportComponent);
fix.detectChanges();
const hGrid = fix.componentInstance.hGrid;
options = createExportOptions('HierarchicalGridMCHExcelExport');
await exportAndVerify(hGrid, options, actualData.exportHierarchicalDataWithMultiColumnHeaders);
});
it('should export hierarchical grid with multi column headers only in the row island', async () => {
const fix = TestBed.createComponent(IgxHierarchicalGridMultiColumnHeaderIslandsExportComponent);
fix.detectChanges();
const hGrid = fix.componentInstance.hGrid;
options = createExportOptions('HierarchicalGridMCHExcelExport');
await exportAndVerify(hGrid, options, actualData.exportHierarchicalDataWithMultiColumnHeadersOnlyInIsland);
});
it('should export hierarchical grid with multi column headers and skipped column', async () => {
const fix = TestBed.createComponent(IgxHierarchicalGridMultiColumnHeadersExportComponent);
fix.detectChanges();
const hGrid = fix.componentInstance.hGrid;
options = createExportOptions('HierarchicalGridMCHExcelExport');
exporter.columnExporting.subscribe((args: IColumnExportingEventArgs) => {
if (args.field === 'ContactTitle') {
args.cancel = true;
}
});
fix.detectChanges();
await exportAndVerify(hGrid, options, actualData.exportMultiColumnHeadersDataWithSkippedColumn);
});
it('should export hierarchical grid with multi column headers and skipped parent multi column header', async () => {
const fix = TestBed.createComponent(IgxHierarchicalGridMultiColumnHeadersExportComponent);
fix.detectChanges();
const hGrid = fix.componentInstance.hGrid;
options = createExportOptions('HierarchicalGridMCHExcelExport');
exporter.columnExporting.subscribe((args: IColumnExportingEventArgs) => {
if (args.header === 'Address Information') {
args.cancel = true;
}
});
fix.detectChanges();
await exportAndVerify(hGrid, options, actualData.exportMultiColumnHeadersDataWithSkippedParentMCH);
});
it('should export empty file when all parent multi column headers are skipped and alwaysExportHeaders is false', async () => {
const fix = TestBed.createComponent(IgxHierarchicalGridMultiColumnHeadersExportComponent);
fix.detectChanges();
const hGrid = fix.componentInstance.hGrid;
options = createExportOptions('HierarchicalGridMCHExcelExport');
options.alwaysExportHeaders = false;
exporter.columnExporting.subscribe((args: IColumnExportingEventArgs) => {
if (args.header === 'General Information' || args.header === 'Address Information' || args.field === 'CustomerID') {
args.cancel = true;
}
});
fix.detectChanges();
await exportAndVerify(hGrid, options, actualData.exportMultiColumnHeadersDataWithAllParentsSkipped);
});
it('should export headers when exporting empty hierarchical grid with multi column headers', async () => {
const fix = TestBed.createComponent(IgxHierarchicalGridMultiColumnHeadersExportComponent);
fix.detectChanges();
const hGrid = fix.componentInstance.hGrid;
fix.componentInstance.data = [];
options = createExportOptions('HierarchicalGridMCHExcelExport');
fix.detectChanges();
await exportAndVerify(hGrid, options, actualData.exportEmptyMultiColumnHeadersDataWithExportedHeaders);
});
});
describe('', () => {
let fix;
let treeGrid: IgxTreeGridComponent;
beforeEach(waitForAsync(() => {
options = createExportOptions('TreeGridExcelExport', 50);
fix = TestBed.createComponent(IgxTreeGridPrimaryForeignKeyComponent);
fix.detectChanges();
treeGrid = fix.componentInstance.treeGrid;
}));
it('should export tree grid as displayed with all groups expanded.', async () => {
await exportAndVerify(treeGrid, options, actualData.treeGridData);
});
it('should export sorted tree grid properly.', async () => {
treeGrid.sort({fieldName: 'ID', dir: SortingDirection.Desc});
options.ignoreSorting = true;
fix.detectChanges();
await exportAndVerify(treeGrid, options, actualData.treeGridData);
options.ignoreSorting = false;
await exportAndVerify(treeGrid, options, actualData.treeGridDataSorted);
treeGrid.clearSort();
fix.detectChanges();
await exportAndVerify(treeGrid, options, actualData.treeGridData);
});
it('should export filtered tree grid properly.', async () => {
treeGrid.filter('ID', 3, IgxNumberFilteringOperand.instance().condition('greaterThan'));
options.ignoreFiltering = true;
fix.detectChanges();
await exportAndVerify(treeGrid, options, actualData.treeGridData);
options.ignoreFiltering = false;
await exportAndVerify(treeGrid, options, actualData.treeGridDataFiltered);
treeGrid.clearFilter();
fix.detectChanges();
await exportAndVerify(treeGrid, options, actualData.treeGridData);
});
it('should export filtered and sorted tree grid properly.', async () => {
treeGrid.filter('ID', 3, IgxNumberFilteringOperand.instance().condition('greaterThan'));
fix.detectChanges();
treeGrid.sort({fieldName: 'Name', dir: SortingDirection.Desc});
fix.detectChanges();
await exportAndVerify(treeGrid, options, actualData.treeGridDataFilteredSorted);
});
it('should export tree grid with only first level expanded.', async () => {
treeGrid.expansionDepth = 1;
fix.detectChanges();
await exportAndVerify(treeGrid, options, actualData.treeGridDataExpDepth(1));
});
it('should export tree grid with collapsed first level.', async () => {
treeGrid.collapseAll();
fix.detectChanges();
await exportAndVerify(treeGrid, options, actualData.treeGridDataExpDepth(0));
});
it('should export tree grid with ignore filtering properly.', async () => {
treeGrid.filter('Age', 52, IgxNumberFilteringOperand.instance().condition('greaterThan'));
options.ignoreFiltering = true;
fix.detectChanges();
await exportAndVerify(treeGrid, options, actualData.treeGridDataIgnoreFiltering);
});
it('should export tree grid with ignore sorting properly.', async () => {
treeGrid.sort({fieldName: 'Age', dir: SortingDirection.Desc});
options.ignoreSorting = true;
fix.detectChanges();
await exportAndVerify(treeGrid, options, actualData.treeGridData);
});
it('should throw an exception when nesting level is greater than 8.', async () => {
const nestedData = SampleTestData.employeePrimaryForeignKeyTreeData();
for (let i = 1; i < 9; i++) {
nestedData[i - 1].ID = i;
nestedData[i - 1].ParentID = i - 1;
}
nestedData.push({ ID: 9, ParentID: 8, Name: 'Test', JobTitle: '', Age: 49 });
treeGrid.data = nestedData;
fix.detectChanges();
await wait(16);
let error = '';
try {
exporter.export(treeGrid, options);
await wait();
} catch (ex) {
error = ex.message;
}
expect(error).toMatch('Can create an outline of up to eight levels!');
treeGrid.deleteRowById(9);
fix.detectChanges();
await wait(16);
error = '';
try {
exporter.export(treeGrid, options);
await wait();
} catch (ex) {
error = ex.message;
}
expect(error).toEqual('');
treeGrid.addRow({ ID: 9, ParentID: 8, Name: 'Test', JobTitle: '', Age: 49 });
fix.detectChanges();
await wait(16);
error = '';
try {
exporter.export(treeGrid, options);
await wait();
} catch (ex) {
error = ex.message;
}
expect(error).toMatch('Can create an outline of up to eight levels!');
});
it('should skip the formatter when columnExporting skipFormatter is true', async () => {
treeGrid.columnList.get(4).formatter = ((val: number) => {
const t = Math.floor(val / 10);
const o = val % 10;
return val + parseFloat(((t + o) / 12).toFixed(2));
});
treeGrid.cdr.detectChanges();
await exportAndVerify(treeGrid, options, actualData.treeGridDataFormatted);
exporter.columnExporting.subscribe((args: IColumnExportingEventArgs) => {
args.skipFormatter = true;
});
treeGrid.cdr.detectChanges();
await exportAndVerify(treeGrid, options, actualData.treeGridData);
exporter.columnExporting.subscribe((args: IColumnExportingEventArgs) => {
args.skipFormatter = false;
});
treeGrid.cdr.detectChanges();
await exportAndVerify(treeGrid, options, actualData.treeGridDataFormatted);
});
it('Should honor Advanced filters when exporting', async () => {
const tree = new FilteringExpressionsTree(FilteringLogic.And);
tree.filteringOperands.push({
fieldName: 'Age',
searchVal: 40,
condition: IgxNumberFilteringOperand.instance().condition('lessThan'),
ignoreCase: true
});
tree.filteringOperands.push({
fieldName: 'Name',
searchVal: 'a',
condition: IgxStringFilteringOperand.instance().condition('contains'),
ignoreCase: true
});
treeGrid.advancedFilteringExpressionsTree = tree;
fix.detectChanges();
treeGrid.cdr.detectChanges();
await wait();
expect(treeGrid.filteredData.length).toBe(5);
await exportAndVerify(treeGrid, options, actualData.treeGridWithAdvancedFilters);
});
it('should export headers when exporting empty tree grid.', async () => {
fix.componentInstance.data = [];
fix.detectChanges();
await exportAndVerify(treeGrid, options, actualData.emptyTreeGridWithExportedHeaders);
});
});
describe('', () => {
let fix;
let grid: IgxGridComponent;
beforeEach(waitForAsync(() => {
options = createExportOptions('MultiColumnHeaderGridExcelExport');
fix = TestBed.createComponent(MultiColumnHeadersExportComponent);
fix.detectChanges();
grid = fix.componentInstance.grid;
}));
it('should export grid with multi column headers', async () => {
await exportAndVerify(grid, options, a