Skip to content

Commit 9858f04

Browse files
committed
test(grid): fix, tests for state persistence #5460
1 parent ded1908 commit 9858f04

File tree

2 files changed

+254
-3
lines changed

2 files changed

+254
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
import { TestBed, async } from '@angular/core/testing';
2+
import { IgxGridModule, IgxGridComponent } from './grid';
3+
import { Component, ViewChild } from '@angular/core';
4+
import { SampleTestData } from '../test-utils/sample-test-data.spec';
5+
import { IgxGridStateDirective, IGridState, IColumnState } from './state.directive';
6+
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
7+
import { ISortingExpression, SortingDirection } from '../data-operations/sorting-expression.interface';
8+
import { IGroupingExpression } from '../data-operations/grouping-expression.interface';
9+
import { FilteringExpressionsTree, IFilteringExpressionsTree } from '../data-operations/filtering-expressions-tree';
10+
import { IPagingState } from '../data-operations/paging-state.interface';
11+
import { GridSelectionRange } from './selection/selection.service';
12+
import { FilteringLogic, DefaultSortingStrategy } from 'igniteui-angular';
13+
import { IgxBooleanFilteringOperand } from '../data-operations/filtering-condition';
14+
import { IGroupingState } from '../data-operations/groupby-state.interface';
15+
import { IGroupByExpandState } from '../data-operations/groupby-expand-state.interface';
16+
17+
describe('IgxGridState - input properties', () => {
18+
beforeEach(async(() => {
19+
TestBed.configureTestingModule({
20+
declarations: [
21+
IgxGridStateComponent,
22+
IgxGridStateWithOptionsComponent
23+
],
24+
imports: [ NoopAnimationsModule, IgxGridModule ]
25+
}).compileComponents();
26+
}));
27+
28+
it('should initialize an IgxGridState with default options object', () => {
29+
const defaultOptions = {
30+
columns: true,
31+
filtering: true,
32+
advancedFiltering: true,
33+
sorting: true,
34+
groupBy: true,
35+
paging: true,
36+
cellSelection: true,
37+
rowSelection: true
38+
};
39+
40+
const fix = TestBed.createComponent(IgxGridStateComponent);
41+
fix.detectChanges();
42+
43+
const state = fix.componentInstance.state;
44+
45+
expect(state).toBeDefined('IgxGridState directive is initialized');
46+
expect(state.options).toEqual(jasmine.objectContaining(defaultOptions));
47+
});
48+
49+
it('should initialize an IgxGridState with correct options input', () => {
50+
const optionsInput = {
51+
columns: true,
52+
filtering: false,
53+
advancedFiltering: true,
54+
sorting: false,
55+
groupBy: true,
56+
paging: true,
57+
cellSelection: true,
58+
rowSelection: true
59+
};
60+
61+
const fix = TestBed.createComponent(IgxGridStateWithOptionsComponent);
62+
fix.detectChanges();
63+
64+
const state = fix.componentInstance.state;
65+
expect(state.options).toEqual(jasmine.objectContaining(optionsInput));
66+
});
67+
68+
it('getState should return corect JSON string', () => {
69+
// tslint:disable-next-line:max-line-length
70+
const initialGridState = '{"columns":[{"pinned":true,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"testCss","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":true,"hidden":false,"dataType":"number","hasSummary":false,"field":"ProductID","width":"150px","header":"Product ID","resizable":true,"searchable":false},{"pinned":false,"sortable":true,"filterable":true,"editable":false,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":true,"hidden":false,"dataType":"string","hasSummary":false,"field":"ProductName","width":"150px","header":"Prodyct Name","resizable":true,"searchable":true},{"pinned":false,"sortable":false,"filterable":true,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":false,"movable":false,"hidden":false,"dataType":"boolean","hasSummary":true,"field":"InStock","width":"140px","header":"In Stock","resizable":true,"searchable":true},{"pinned":false,"sortable":true,"filterable":false,"editable":true,"sortingIgnoreCase":true,"filteringIgnoreCase":true,"headerClasses":"","headerGroupClasses":"","maxWidth":"300px","groupable":true,"movable":false,"hidden":false,"dataType":"date","hasSummary":false,"field":"OrderDate","width":"110px","header":"Date ordered","resizable":false,"searchable":true}],"filtering":{"filteringOperands":[],"operator":0},"advancedFiltering":{"filteringOperands":[],"operator":0},"sorting":[],"groupBy":{"expressions":[],"expansion":[],"defaultExpanded":true},"paging":{"index":0,"recordsPerPage":15,"metadata":{"countPages":1,"countRecords":10,"error":0}},"cellSelection":[],"rowSelection":[]}';
71+
const fix = TestBed.createComponent(IgxGridStateComponent);
72+
fix.detectChanges();
73+
74+
const state = fix.componentInstance.state;
75+
76+
const gridState = state.getState();
77+
expect(gridState).toBe(initialGridState, 'JSON string representation of the initial grid state is not correct');
78+
});
79+
80+
it('getState should return corect IGridState object', () => {
81+
const fix = TestBed.createComponent(IgxGridStateComponent);
82+
fix.detectChanges();
83+
const grid = fix.componentInstance.grid;
84+
const state = fix.componentInstance.state;
85+
86+
const gridFilteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And);
87+
const productFilteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And, 'ProductName');
88+
const productExpression = {
89+
condition: IgxBooleanFilteringOperand.instance().condition('true'),
90+
fieldName: 'InStock',
91+
ignoreCase: true
92+
};
93+
productFilteringExpressionsTree.filteringOperands.push(productExpression);
94+
gridFilteringExpressionsTree.filteringOperands.push(productFilteringExpressionsTree);
95+
96+
const groupingExpressions = [
97+
{ dir: SortingDirection.Asc, fieldName: 'ProductID', ignoreCase: false,
98+
strategy: DefaultSortingStrategy.instance() },
99+
{ dir: SortingDirection.Asc, fieldName: 'OrderDate', ignoreCase: false,
100+
strategy: DefaultSortingStrategy.instance() }
101+
];
102+
103+
grid.filteringExpressionsTree = gridFilteringExpressionsTree;
104+
grid.groupingExpressions = groupingExpressions;
105+
fix.detectChanges();
106+
107+
const columns = fix.componentInstance.columns;
108+
const paging = grid.pagingState;
109+
const sorting = grid.sortingExpressions;
110+
const groupBy = grid.groupingExpressions;
111+
const groupByExpansion = grid.groupingExpansionState;
112+
const filtering = grid.filteringExpressionsTree;
113+
const advancedFiltering = grid.advancedFilteringExpressionsTree;
114+
115+
const gridState = state.getState(false) as IGridState;
116+
HelperFunctions.verifyColumns(columns, gridState);
117+
HelperFunctions.verifyPaging(paging, gridState);
118+
HelperFunctions.verifySortingExpressions(sorting, gridState);
119+
HelperFunctions.verifyGroupingExpressions(groupBy, gridState);
120+
HelperFunctions.verifyGroupingExpansion(groupByExpansion, gridState.groupBy);
121+
HelperFunctions.verifyFilteringExpressions(filtering, gridState);
122+
// HelperFunctions.verifyAdvancedFilteringExpressions(advancedFiltering, gridState);
123+
});
124+
});
125+
126+
class HelperFunctions {
127+
public static verifyColumns(columns: IColumnState[], gridState: IGridState) {
128+
columns.forEach((c, index) => {
129+
expect(gridState.columns[index]).toEqual(jasmine.objectContaining(c));
130+
});
131+
}
132+
133+
public static verifySortingExpressions(sortingExpressions: ISortingExpression[], gridState: IGridState) {
134+
sortingExpressions.forEach((expr, i) => {
135+
expect(expr).toEqual(jasmine.objectContaining(gridState.sorting[i]));
136+
});
137+
}
138+
139+
public static verifyGroupingExpressions(groupingExpressions: IGroupingExpression[], gridState: IGridState) {
140+
groupingExpressions.forEach((expr, i) => {
141+
expect(expr).toEqual(jasmine.objectContaining(gridState.groupBy.expressions[i]));
142+
});
143+
}
144+
145+
public static verifyGroupingExpansion(groupingExpansion: IGroupByExpandState[], groupBy: IGroupingState) {
146+
groupingExpansion.forEach((exp, i) => {
147+
expect(exp).toEqual(jasmine.objectContaining(groupBy.expansion[i]));
148+
});
149+
}
150+
151+
public static verifyFilteringExpressions(expressions: IFilteringExpressionsTree, gridState: IGridState) {
152+
expect(expressions.fieldName).toBe(gridState.filtering.fieldName, 'Filtering expression field name is not correct');
153+
expect(expressions.operator).toBe(gridState.filtering.operator, 'Filtering expression operator value is not correct');
154+
expressions.filteringOperands.forEach((expr, i) => {
155+
expect(expr).toEqual(jasmine.objectContaining(gridState.filtering.filteringOperands[i]));
156+
});
157+
}
158+
159+
public static verifyAdvancedFilteringExpressions(expressions: IFilteringExpressionsTree, gridState: IGridState) {
160+
expect(expressions.fieldName).toBe(gridState.filtering.fieldName, 'Filtering expression field name is not correct');
161+
expect(expressions.operator).toBe(gridState.filtering.operator, 'Filtering expression operator value is not correct');
162+
expressions.filteringOperands.forEach((expr, i) => {
163+
expect(expr).toEqual(jasmine.objectContaining(gridState.filtering.filteringOperands[i]));
164+
});
165+
}
166+
167+
public static verifyPaging(paging: IPagingState, gridState: IGridState) {
168+
expect(paging).toEqual(jasmine.objectContaining(gridState.paging));
169+
}
170+
171+
public static verifyRowSelection(selectedRows: any[], gridState: IGridState) {
172+
173+
}
174+
175+
public static verifyCellSelection(selectedCells: GridSelectionRange, gridState: IGridState) {
176+
177+
}
178+
}
179+
180+
@Component({
181+
template: `
182+
<igx-grid #grid [data]="data" [paging]="true" [autoGenerate]="false" igxGridState>
183+
<igx-column *ngFor="let c of columns"
184+
[width]="c.width"
185+
[sortable]="c.sortable"
186+
[movable]="c.movable"
187+
[editable]="c.editable"
188+
[sortingIgnoreCase]="c.sortingIgnoreCase"
189+
[filteringIgnoreCase]="c.sortingIgnoreCase"
190+
[maxWidth]="c.maxWidth"
191+
[hasSummary]="c.hasSummary"
192+
[filterable]="c.filterable"
193+
[searchable]="c.searchable"
194+
[resizable]="c.resizable"
195+
[headerClasses]="c.headerClasses"
196+
[headerGroupClasses]="c.headerGroupClasses"
197+
[groupable]="c.groupable"
198+
[field]="c.field"
199+
[header]="c.header"
200+
[dataType]="c.dataType"
201+
[pinned]="c.pinned"
202+
[hidden]="c.hidden">
203+
</igx-column>
204+
</igx-grid>
205+
`
206+
})
207+
export class IgxGridStateComponent {
208+
public data = SampleTestData.foodProductData();
209+
210+
public columns: any[] = [
211+
// tslint:disable:max-line-length
212+
{ field: 'ProductID', header: 'Product ID', width: '150px', dataType: 'number', pinned: true, movable: true, sortable: true, filterable: true, groupable: false, hasSummary: false, hidden: false, maxWidth: '300px', searchable: false, sortingIgnoreCase: true, filteringIgnoreCase: true, editable: false, headerClasses: 'testCss', headerGroupClasses: '', resizable: true },
213+
{ field: 'ProductName', header: 'Prodyct Name', width: '150px', dataType: 'string', pinned: false, movable: true, sortable: true, filterable: true, groupable: true, hasSummary: false, hidden: false, maxWidth: '300px', searchable: true, sortingIgnoreCase: true, filteringIgnoreCase: true, editable: false, headerClasses: '', headerGroupClasses: '', resizable: true },
214+
{ field: 'InStock', header: 'In Stock', width: '140px', dataType: 'boolean', pinned: false, movable: false, sortable: false, filterable: true, groupable: false, hasSummary: true, hidden: false, maxWidth: '300px', searchable: true, sortingIgnoreCase: true, filteringIgnoreCase: true, editable: true, headerClasses: '', headerGroupClasses: '', resizable: true },
215+
{ field: 'OrderDate', header: 'Date ordered', width: '110px', dataType: 'date', pinned: false, movable: false, sortable: true, filterable: false, groupable: true, hasSummary: false, hidden: false, maxWidth: '300px', searchable: true, sortingIgnoreCase: true, filteringIgnoreCase: true, editable: true, headerClasses: '', headerGroupClasses: '', resizable: false },
216+
// tslint:enable:max-line-length
217+
];
218+
219+
@ViewChild('grid', { read: IgxGridComponent, static: true })
220+
public grid: IgxGridComponent;
221+
222+
@ViewChild(IgxGridStateDirective, { static: true })
223+
public state: IgxGridStateDirective;
224+
}
225+
226+
@Component({
227+
template: `
228+
<igx-grid #grid [data]="data" [paging]="true" [autoGenerate]="true" [igxGridState]="options">
229+
</igx-grid>
230+
`
231+
})
232+
export class IgxGridStateWithOptionsComponent {
233+
public data = SampleTestData.foodProductData();
234+
public options = {
235+
filtering: false,
236+
advancedFiltering: true,
237+
sorting: false,
238+
groupBy: true
239+
};
240+
241+
@ViewChild('grid', { read: IgxGridComponent, static: true })
242+
public grid: IgxGridComponent;
243+
244+
@ViewChild(IgxGridStateDirective, { static: true })
245+
public state: IgxGridStateDirective;
246+
}

projects/igniteui-angular/src/lib/grids/state.directive.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ export class IgxGridStateDirective {
163163
}
164164
this.state = state as IGridState;
165165
this.restoreGridState();
166+
this.grid.cdr.detectChanges();
166167
}
167168

168169
/**
@@ -336,8 +337,9 @@ export class IgxGridStateDirective {
336337
delete expr.strategy;
337338
});
338339
const expansionState = this.grid.groupingExpansionState;
340+
const groupsExpanded = this.grid.groupsExpanded;
339341

340-
return { groupBy: { expressions: groupingExpressions, expansion: expansionState, defaultExpanded: true} };
342+
return { groupBy: { expressions: groupingExpressions, expansion: expansionState, defaultExpanded: groupsExpanded} };
341343
}
342344

343345
private getRowSelection(): IGridState {
@@ -402,7 +404,11 @@ export class IgxGridStateDirective {
402404
*/
403405
private restoreGroupBy(state: IGroupingState) {
404406
(this.grid as IgxGridComponent).groupingExpressions = state.expressions as IGroupingExpression[];
405-
(this.grid as IgxGridComponent).groupingExpansionState = state.expansion as IGroupByExpandState[];
407+
if ((this.grid as IgxGridComponent).groupsExpanded !== state.defaultExpanded) {
408+
this.grid.toggleAllGroupRows();
409+
} else {
410+
(this.grid as IgxGridComponent).groupingExpansionState = state.expansion as IGroupByExpandState[];
411+
}
406412
}
407413

408414
/**
@@ -414,7 +420,6 @@ export class IgxGridStateDirective {
414420
this.grid.cdr.detectChanges();
415421
}
416422
this.grid.page = state.index;
417-
this.grid.cdr.detectChanges();
418423
}
419424

420425
private restoreRowSelection(state: any[]) {

0 commit comments

Comments
 (0)