Skip to content
This repository was archived by the owner on Jun 1, 2025. It is now read-only.

Commit f105efc

Browse files
Ghislain BeaulacGhislain Beaulac
authored andcommitted
feat(tests): start adding GridStateService unit tests
1 parent a6df5ec commit f105efc

File tree

6 files changed

+208
-609
lines changed

6 files changed

+208
-609
lines changed

src/app/modules/angular-slickgrid/services/collection.service.spec.ts renamed to src/app/modules/angular-slickgrid/services/__tests__/collection.service.spec.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,20 @@
11
import { TestBed } from '@angular/core/testing';
22
import { TranslateService, TranslateModule } from '@ngx-translate/core';
3-
import { CollectionService } from './collection.service';
3+
import { CollectionService } from '../collection.service';
44
import {
55
CollectionFilterBy,
66
CollectionSortBy,
77
FilterMultiplePassType,
88
OperatorType,
99
Column,
1010
FieldType,
11-
} from './../models/index';
11+
} from '../../models/index';
1212

1313
describe('CollectionService', () => {
1414
let collection = [];
1515
let translate: TranslateService;
1616
let service: CollectionService;
1717

18-
// stub some methods of the SlickGrid Grid instance
19-
const gridStub = {
20-
getOptions: jest.fn()
21-
};
22-
2318
beforeEach(() => {
2419
TestBed.configureTestingModule({
2520
providers: [CollectionService],
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
import { TestBed } from '@angular/core/testing';
2+
import { BackendServiceApi, BackendService, GridOption, CurrentPagination, CurrentSorter, CurrentFilter } from '../../models';
3+
import { FilterService } from '../filter.service';
4+
import { GridStateService } from '../gridState.service';
5+
import { ExtensionService } from '../extension.service';
6+
import { SortService } from '../sort.service';
7+
import { of } from 'rxjs';
8+
9+
const gridOptionMock = {
10+
enableAutoResize: true
11+
} as GridOption;
12+
13+
const backendServiceStub = {
14+
getCurrentFilters: () => { },
15+
getCurrentPagination: () => { },
16+
getCurrentSorters: () => { },
17+
} as BackendService;
18+
19+
const gridStub = {
20+
autosizeColumns: jest.fn(),
21+
getScrollbarDimensions: jest.fn(),
22+
getOptions: () => gridOptionMock
23+
};
24+
25+
const extensionServiceStub = {
26+
getExtensionByName: (name: string) => { }
27+
} as ExtensionService;
28+
29+
const filterServiceStub = {
30+
onFilterChanged: of([]),
31+
onFilterCleared: of(false)
32+
} as FilterService;
33+
34+
const sortServiceStub = {
35+
onSortChanged: of([]),
36+
onSortCleared: of(false)
37+
} as SortService;
38+
39+
describe('GridStateService', () => {
40+
let service: GridStateService;
41+
42+
beforeEach(() => {
43+
TestBed.configureTestingModule({
44+
providers: [GridStateService]
45+
});
46+
service = TestBed.get(GridStateService);
47+
service.init(gridStub, extensionServiceStub, filterServiceStub, sortServiceStub);
48+
});
49+
50+
afterEach(() => {
51+
service.dispose();
52+
});
53+
54+
it('should create the service', () => {
55+
expect(service).toBeTruthy();
56+
});
57+
58+
it('should have called the "subscribeToAllGridChanges" method while initializing', () => {
59+
const gridStateSpy = jest.spyOn(service, 'subscribeToAllGridChanges');
60+
const filterSpy = jest.spyOn(filterServiceStub.onFilterChanged, 'subscribe');
61+
const sortSpy = jest.spyOn(sortServiceStub.onSortChanged, 'subscribe');
62+
63+
service.init(gridStub, extensionServiceStub, filterServiceStub, sortServiceStub);
64+
65+
expect(gridStateSpy).toHaveBeenCalled();
66+
expect(filterSpy).toHaveBeenCalled();
67+
expect(sortSpy).toHaveBeenCalled();
68+
});
69+
70+
describe('getCurrentPagination method', () => {
71+
it('should call "getCurrentPagination" and return null when no BackendService is used', () => {
72+
const output = service.getCurrentPagination();
73+
expect(output).toBeNull();
74+
});
75+
76+
it('should call "getCurrentPagination" and return Pagination when a BackendService is used', () => {
77+
const gridOptionsMock = { backendServiceApi: { service: backendServiceStub } } as GridOption;
78+
const paginationMock = { pageNumber: 2, pageSize: 50 } as CurrentPagination;
79+
const gridSpy = jest.spyOn(gridStub, 'getOptions').mockReturnValue(gridOptionsMock);
80+
const backendSpy = jest.spyOn(backendServiceStub, 'getCurrentPagination').mockReturnValue(paginationMock);
81+
82+
const output = service.getCurrentPagination();
83+
84+
expect(gridSpy).toHaveBeenCalled();
85+
expect(backendSpy).toHaveBeenCalled();
86+
expect(output).toBe(paginationMock);
87+
});
88+
});
89+
90+
describe('getCurrentSorters method', () => {
91+
it('should return null when no BackendService is used and SortService is missing the "getCurrentLocalSorters" method', () => {
92+
const gridSpy = jest.spyOn(gridStub, 'getOptions').mockReturnValue({});
93+
94+
const output = service.getCurrentSorters();
95+
96+
expect(gridSpy).toHaveBeenCalled();
97+
expect(output).toBeNull();
98+
});
99+
100+
it('should return Sorters when a BackendService is used', () => {
101+
const gridOptionsMock = { backendServiceApi: { service: backendServiceStub } } as GridOption;
102+
const sorterMock = [{ columnId: 'field1', direction: 'ASC' }, { columnId: 'field2', direction: 'DESC' }] as CurrentSorter[];
103+
const gridSpy = jest.spyOn(gridStub, 'getOptions').mockReturnValue(gridOptionsMock);
104+
const backendSpy = jest.spyOn(backendServiceStub, 'getCurrentSorters').mockReturnValue(sorterMock);
105+
106+
const output = service.getCurrentSorters();
107+
108+
expect(gridSpy).toHaveBeenCalled();
109+
expect(backendSpy).toHaveBeenCalled();
110+
expect(output).toBe(sorterMock);
111+
});
112+
113+
it('should return Sorters when Local grid is set and no BackendService is used', () => {
114+
const sorterMock = [{ columnId: 'field1', direction: 'ASC' }, { columnId: 'field2', direction: 'DESC' }] as CurrentSorter[];
115+
sortServiceStub.getCurrentLocalSorters = () => sorterMock;
116+
const gridSpy = jest.spyOn(gridStub, 'getOptions').mockReturnValue({});
117+
const sortSpy = jest.spyOn(sortServiceStub, 'getCurrentLocalSorters').mockReturnValue(sorterMock);
118+
119+
const output = service.getCurrentSorters();
120+
121+
expect(gridSpy).toHaveBeenCalled();
122+
expect(sortSpy).toHaveBeenCalled();
123+
expect(output).toBe(sorterMock);
124+
});
125+
});
126+
127+
describe('getCurrentFilters method', () => {
128+
it('should return null when no BackendService is used and FilterService is missing the "getCurrentLocalFilters" method', () => {
129+
const gridSpy = jest.spyOn(gridStub, 'getOptions').mockReturnValue({});
130+
131+
const output = service.getCurrentFilters();
132+
133+
expect(gridSpy).toHaveBeenCalled();
134+
expect(output).toBeNull();
135+
});
136+
137+
it('should return Sorters when a BackendService is used', () => {
138+
const gridOptionsMock = { backendServiceApi: { service: backendServiceStub } } as GridOption;
139+
const filterMock = [{ columnId: 'field1', operator: 'EQ', searchTerms: [] }, { columnId: 'field2', operator: '>=', searchTerms: [2] }] as CurrentFilter[];
140+
const gridSpy = jest.spyOn(gridStub, 'getOptions').mockReturnValue(gridOptionsMock);
141+
const backendSpy = jest.spyOn(backendServiceStub, 'getCurrentFilters').mockReturnValue(filterMock);
142+
143+
const output = service.getCurrentFilters();
144+
145+
expect(gridSpy).toHaveBeenCalled();
146+
expect(backendSpy).toHaveBeenCalled();
147+
expect(output).toBe(filterMock);
148+
});
149+
150+
it('should return Sorters when Local grid is set and no BackendService is used', () => {
151+
const filterMock = [{ columnId: 'field1', operator: 'EQ', searchTerms: [] }, { columnId: 'field2', operator: '>=', searchTerms: [2] }] as CurrentFilter[];
152+
filterServiceStub.getCurrentLocalFilters = () => filterMock;
153+
const gridSpy = jest.spyOn(gridStub, 'getOptions').mockReturnValue({});
154+
const filterSpy = jest.spyOn(filterServiceStub, 'getCurrentLocalFilters').mockReturnValue(filterMock);
155+
156+
const output = service.getCurrentFilters();
157+
158+
expect(gridSpy).toHaveBeenCalled();
159+
expect(filterSpy).toHaveBeenCalled();
160+
expect(output).toBe(filterMock);
161+
});
162+
});
163+
});

src/app/modules/angular-slickgrid/services/resizer.service.spec.ts renamed to src/app/modules/angular-slickgrid/services/__tests__/resizer.service.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { GridOption } from './../models/gridOption.interface';
2-
import { ResizerService } from './resizer.service';
1+
import { GridOption } from '../../models/gridOption.interface';
2+
import { ResizerService } from '../resizer.service';
33

44
const DATAGRID_MIN_HEIGHT = 180;
55
const DATAGRID_MIN_WIDTH = 300;

src/app/modules/angular-slickgrid/services/extension.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ export class ExtensionService {
312312
}
313313
}
314314

315-
/** Translate the an array of items from an input key and assign to the output key */
315+
/** Translate an array of items from an input key and assign translated value to the output key */
316316
private translateItems(items: any[], inputKey: string, outputKey: string) {
317317
for (const item of items) {
318318
if (item[inputKey]) {

src/app/modules/angular-slickgrid/services/gridState.service.ts

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import { SortService } from './sort.service';
1616
import { Subject, Subscription } from 'rxjs';
1717

1818
// using external non-typed js libraries
19-
declare var $: any;
2019
declare var Slick: any;
2120

2221
export class GridStateService {
@@ -203,38 +202,6 @@ export class GridStateService {
203202
return null;
204203
}
205204

206-
/**
207-
* Hook a SlickGrid Extension Event to a Grid State change event
208-
* @param extension name
209-
* @param grid
210-
*/
211-
hookExtensionEventToGridStateChange(extensionName: ExtensionName, eventName: string) {
212-
const extension = this.extensionService && this.extensionService.getExtensionByName(extensionName);
213-
214-
if (extension && extension.class && extension.class[eventName] && extension.class[eventName].subscribe) {
215-
this._eventHandler.subscribe(extension.class[eventName], (e: Event, args: any) => {
216-
const columns: Column[] = args && args.columns;
217-
const currentColumns: CurrentColumn[] = this.getAssociatedCurrentColumns(columns);
218-
this.onGridStateChanged.next({ change: { newValues: currentColumns, type: GridStateType.columns }, gridState: this.getCurrentGridState() });
219-
});
220-
}
221-
}
222-
223-
/**
224-
* Hook a Grid Event to a Grid State change event
225-
* @param event name
226-
* @param grid
227-
*/
228-
hookSlickGridEventToGridStateChange(eventName: string, grid: any) {
229-
if (grid && grid[eventName] && grid[eventName].subscribe) {
230-
this._eventHandler.subscribe(grid[eventName], (e: Event, args: any) => {
231-
const columns: Column[] = grid.getColumns();
232-
const currentColumns: CurrentColumn[] = this.getAssociatedCurrentColumns(columns);
233-
this.onGridStateChanged.next({ change: { newValues: currentColumns, type: GridStateType.columns }, gridState: this.getCurrentGridState() });
234-
});
235-
}
236-
}
237-
238205
resetColumns(columnDefinitions?: Column[]) {
239206
const columns: Column[] = columnDefinitions || this._columns;
240207
const currentColumns: CurrentColumn[] = this.getAssociatedCurrentColumns(columns);
@@ -289,11 +256,47 @@ export class GridStateService {
289256
);
290257

291258
// Subscribe to ColumnPicker and/or GridMenu for show/hide Columns visibility changes
292-
this.hookExtensionEventToGridStateChange(ExtensionName.columnPicker, 'onColumnsChanged');
293-
this.hookExtensionEventToGridStateChange(ExtensionName.gridMenu, 'onColumnsChanged');
259+
this.bindExtensionEventToGridStateChange(ExtensionName.columnPicker, 'onColumnsChanged');
260+
this.bindExtensionEventToGridStateChange(ExtensionName.gridMenu, 'onColumnsChanged');
294261

295262
// subscribe to Column Resize & Reordering
296-
this.hookSlickGridEventToGridStateChange('onColumnsReordered', grid);
297-
this.hookSlickGridEventToGridStateChange('onColumnsResized', grid);
263+
this.bindSlickGridEventToGridStateChange('onColumnsReordered', grid);
264+
this.bindSlickGridEventToGridStateChange('onColumnsResized', grid);
265+
}
266+
267+
// --
268+
// private methods
269+
// ------------------
270+
271+
/**
272+
* Bind a SlickGrid Extension Event to a Grid State change event
273+
* @param extension name
274+
* @param grid
275+
*/
276+
private bindExtensionEventToGridStateChange(extensionName: ExtensionName, eventName: string) {
277+
const extension = this.extensionService && this.extensionService.getExtensionByName && this.extensionService.getExtensionByName(extensionName);
278+
279+
if (extension && extension.class && extension.class[eventName] && extension.class[eventName].subscribe) {
280+
this._eventHandler.subscribe(extension.class[eventName], (e: Event, args: any) => {
281+
const columns: Column[] = args && args.columns;
282+
const currentColumns: CurrentColumn[] = this.getAssociatedCurrentColumns(columns);
283+
this.onGridStateChanged.next({ change: { newValues: currentColumns, type: GridStateType.columns }, gridState: this.getCurrentGridState() });
284+
});
285+
}
286+
}
287+
288+
/**
289+
* Bind a Grid Event to a Grid State change event
290+
* @param event name
291+
* @param grid
292+
*/
293+
private bindSlickGridEventToGridStateChange(eventName: string, grid: any) {
294+
if (grid && grid[eventName] && grid[eventName].subscribe) {
295+
this._eventHandler.subscribe(grid[eventName], (e: Event, args: any) => {
296+
const columns: Column[] = grid.getColumns();
297+
const currentColumns: CurrentColumn[] = this.getAssociatedCurrentColumns(columns);
298+
this.onGridStateChanged.next({ change: { newValues: currentColumns, type: GridStateType.columns }, gridState: this.getCurrentGridState() });
299+
});
300+
}
298301
}
299302
}

0 commit comments

Comments
 (0)