Skip to content

Commit b7b1a73

Browse files
committed
feat(tests): add Cypress E2E for Local Pagination and fix new bugs found
1 parent 9441a86 commit b7b1a73

File tree

8 files changed

+375
-52
lines changed

8 files changed

+375
-52
lines changed

src/app/examples/grid-state.component.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ function randomBetween(min, max) {
1717
}
1818
const LOCAL_STORAGE_KEY = 'gridState';
1919
const NB_ITEMS = 500;
20+
const DEFAULT_PAGE_SIZE = 25;
2021

2122
@Component({
2223
templateUrl: './grid-state.component.html'
@@ -66,6 +67,7 @@ export class GridStateComponent implements OnInit {
6667
clearGridStateFromLocalStorage() {
6768
localStorage[LOCAL_STORAGE_KEY] = null;
6869
this.angularGrid.gridService.resetGrid(this.columnDefinitions);
70+
this.angularGrid.paginationService.changeItemPerPage(DEFAULT_PAGE_SIZE);
6971
}
7072

7173
/* Define grid Options and Columns */
@@ -153,7 +155,7 @@ export class GridStateComponent implements OnInit {
153155
enablePagination: true,
154156
pagination: {
155157
pageSizes: [5, 10, 15, 20, 25, 30, 40, 50, 75, 100],
156-
pageSize: 25
158+
pageSize: DEFAULT_PAGE_SIZE
157159
},
158160
};
159161

src/app/modules/angular-slickgrid/components/__tests__/angular-slickgrid-constructor.spec.ts

+30
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ const mockDataView = {
154154
getItem: jest.fn(),
155155
getItems: jest.fn(),
156156
getItemMetadata: jest.fn(),
157+
getPagingInfo: jest.fn(),
157158
onRowsChanged: jest.fn(),
158159
onRowCountChanged: jest.fn(),
159160
onSetItemsCalled: jest.fn(),
@@ -586,12 +587,39 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () =
586587
});
587588

588589
it('should refresh a local grid and change pagination options pagination when a preset for it is defined in grid options', (done) => {
590+
const expectedPageNumber = 2;
591+
const expectedTotalItems = 2;
592+
const refreshSpy = jest.spyOn(component, 'refreshGridData');
593+
594+
const mockData = [{ firstName: 'John', lastName: 'Doe' }, { firstName: 'Jane', lastName: 'Smith' }];
595+
component.gridOptions = {
596+
enablePagination: true,
597+
presets: { pagination: { pageSize: 2, pageNumber: expectedPageNumber } }
598+
};
599+
component.paginationOptions = { pageSize: 2, pageNumber: 2, pageSizes: [2, 10, 25, 50], totalItems: 100 };
600+
601+
component.dataset = mockData;
602+
component.ngAfterViewInit();
603+
604+
setTimeout(() => {
605+
expect(component.paginationOptions.pageSize).toBe(2);
606+
expect(component.paginationOptions.pageNumber).toBe(expectedPageNumber);
607+
expect(component.paginationOptions.totalItems).toBe(expectedTotalItems);
608+
expect(refreshSpy).toHaveBeenCalledWith(mockData);
609+
done();
610+
});
611+
});
612+
613+
it('should refresh a local grid defined and change pagination options pagination when a preset is defined in grid options and total rows is different when Filters are applied', (done) => {
589614
const expectedPageNumber = 3;
615+
const expectedTotalItems = 15;
590616
const refreshSpy = jest.spyOn(component, 'refreshGridData');
617+
const getPagingSpy = jest.spyOn(mockDataView, 'getPagingInfo').mockReturnValue({ pageNum: 1, totalRows: expectedTotalItems });
591618

592619
const mockData = [{ firstName: 'John', lastName: 'Doe' }, { firstName: 'Jane', lastName: 'Smith' }];
593620
component.gridOptions = {
594621
enablePagination: true,
622+
enableFiltering: true,
595623
presets: { pagination: { pageSize: 10, pageNumber: expectedPageNumber } }
596624
};
597625
component.paginationOptions = { pageSize: 10, pageNumber: 2, pageSizes: [10, 25, 50], totalItems: 100 };
@@ -600,8 +628,10 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () =
600628
component.dataset = mockData;
601629

602630
setTimeout(() => {
631+
expect(getPagingSpy).toHaveBeenCalled();
603632
expect(component.paginationOptions.pageSize).toBe(10);
604633
expect(component.paginationOptions.pageNumber).toBe(expectedPageNumber);
634+
expect(component.paginationOptions.totalItems).toBe(expectedTotalItems);
605635
expect(refreshSpy).toHaveBeenCalledWith(mockData);
606636
done();
607637
});

src/app/modules/angular-slickgrid/components/angular-slickgrid.component.ts

+30-11
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
119119
private _fixedHeight: number | null;
120120
private _fixedWidth: number | null;
121121
private _hideHeaderRowAfterPageLoad = false;
122+
private _isGridInitialized = false;
123+
private _isPaginationInitialized = false;
122124
dataView: any;
123125
grid: any;
124126
gridHeightString: string;
@@ -133,7 +135,6 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
133135
showCustomFooter = false;
134136
showPagination = false;
135137
totalItems = 0;
136-
isGridInitialized = false;
137138
subscriptions: Subscription[] = [];
138139

139140
@Output() onAngularGridCreated = new EventEmitter<AngularGridInstance>();
@@ -164,7 +165,7 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
164165
@Input()
165166
set columnDefinitions(columnDefinitions: Column[]) {
166167
this._columnDefinitions = columnDefinitions;
167-
if (this.isGridInitialized) {
168+
if (this._isGridInitialized) {
168169
this.updateColumnDefinitionsList(columnDefinitions);
169170
}
170171
}
@@ -206,7 +207,7 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
206207

207208
ngAfterViewInit() {
208209
this.initialization();
209-
this.isGridInitialized = true;
210+
this._isGridInitialized = true;
210211

211212
// user must provide a "gridHeight" or use "autoResize: true" in the grid options
212213
if (!this._fixedHeight && !this.gridOptions.enableAutoResize) {
@@ -344,11 +345,9 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
344345
}
345346

346347
// initialize the Pagination Service with new pagination options (which might have presets)
347-
// with a delay so that presets are properly reflected in the grid
348-
setTimeout(() => this.initializePaginationService(paginationOptions));
349-
} else {
350-
// without backend service, we'll assume the total of items is the dataset size
351-
this.totalItems = dataset.length;
348+
if (!this._isPaginationInitialized) {
349+
this.initializePaginationService(paginationOptions);
350+
}
352351
}
353352

354353
// resize the grid inside a slight timeout, in case other DOM element changed prior to the resize (like a filter/pagination changed)
@@ -636,6 +635,7 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
636635

637636
private initializePaginationService(paginationOptions: Pagination) {
638637
this.paginationService.init(this.grid, this.dataView, paginationOptions, this.backendServiceApi);
638+
this._isPaginationInitialized = true;
639639
this.cd.detectChanges();
640640
}
641641

@@ -751,11 +751,10 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
751751

752752
// local grid, check if we need to show the Pagination
753753
// if so then also check if there's any presets and finally initialize the PaginationService
754+
// a local grid with Pagination presets will potentially have a different total of items, we'll need to get it from the DataView and update our total
754755
if (this.gridOptions && this.gridOptions.enablePagination && !this.gridOptions.backendServiceApi) {
755-
this.totalItems = this.dataset.length;
756756
this.showPagination = true;
757-
const paginationOptions = this.setPaginationOptionsWhenPresetDefined(this.gridOptions, this.paginationOptions);
758-
this.initializePaginationService(paginationOptions);
757+
this.loadLocalGridPagination();
759758
}
760759

761760
this.onAngularGridCreated.emit({
@@ -798,6 +797,26 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
798797
}
799798
}
800799

800+
/**
801+
* local grid, check if we need to show the Pagination
802+
* if so then also check if there's any presets and finally initialize the PaginationService
803+
* a local grid with Pagination presets will potentially have a different total of items, we'll need to get it from the DataView and update our total
804+
*/
805+
private loadLocalGridPagination() {
806+
if (this.gridOptions) {
807+
this.totalItems = this.dataset.length;
808+
if (this.paginationOptions && this.dataView && this.dataView.getPagingInfo) {
809+
const slickPagingInfo = this.dataView.getPagingInfo() || {};
810+
if (slickPagingInfo.hasOwnProperty('totalRows') && this.paginationOptions.totalItems !== slickPagingInfo.totalRows) {
811+
this.totalItems = slickPagingInfo.totalRows;
812+
}
813+
}
814+
this.paginationOptions.totalItems = this.totalItems;
815+
const paginationOptions = this.setPaginationOptionsWhenPresetDefined(this.gridOptions, this.paginationOptions);
816+
this.initializePaginationService(paginationOptions);
817+
}
818+
}
819+
801820
private mergeGridOptions(gridOptions): GridOption {
802821
gridOptions.gridId = this.gridId;
803822
gridOptions.gridContainerId = `slickGridContainer-${this.gridId}`;

src/app/modules/angular-slickgrid/services/__tests__/pagination.service.spec.ts

+24-26
Original file line numberDiff line numberDiff line change
@@ -97,16 +97,12 @@ describe('PaginationService', () => {
9797

9898
it('should initialize the service and call "refreshPagination" and trigger "onPaginationChanged" event', () => {
9999
const refreshSpy = jest.spyOn(service, 'refreshPagination');
100-
const paginationSpy = jest.spyOn(service.onPaginationChanged, 'next');
101100
service.init(gridStub, dataviewStub, mockGridOption.pagination, mockGridOption.backendServiceApi);
102101

103102
expect(service.paginationOptions).toEqual(mockGridOption.pagination);
104103
expect(service.pager).toBeTruthy();
105104
expect(refreshSpy).toHaveBeenCalled();
106105
expect(service.getCurrentPageNumber()).toBe(2);
107-
expect(paginationSpy).toHaveBeenCalledWith({
108-
from: 26, to: 50, itemsPerPage: 25, pageCount: 4, pageNumber: 2, totalItems: 85, availablePageSizes: mockGridOption.pagination.pageSizes
109-
});
110106
});
111107

112108
it('should initialize the service and be able to change the grid options by the SETTER and expect the GETTER to have updated options', () => {
@@ -126,7 +122,7 @@ describe('PaginationService', () => {
126122
expect(service.totalItems).toEqual(125);
127123
expect(service.pager).toBeTruthy();
128124
expect(service.getCurrentPageNumber()).toBe(2);
129-
expect(spy).toHaveBeenCalledTimes(1); // called 1x time inside the init() only
125+
expect(spy).toHaveBeenCalledWith(false, false);
130126
});
131127

132128
it('should be able to change the totalItems by the SETTER after the initialization and expect the "refreshPagination" method to be called', () => {
@@ -494,31 +490,43 @@ describe('PaginationService', () => {
494490
});
495491

496492
it('should call refreshPagination when "onFilterCleared" is triggered', () => {
497-
const spy = jest.spyOn(service, 'refreshPagination');
493+
const resetSpy = jest.spyOn(service, 'resetPagination');
494+
const refreshSpy = jest.spyOn(service, 'refreshPagination');
498495

499496
service.init(gridStub, dataviewStub, mockGridOption.pagination, mockGridOption.backendServiceApi);
500497
filterServiceStub.onFilterCleared.next(true);
501498

502-
expect(spy).toHaveBeenCalledWith(true);
499+
expect(resetSpy).toHaveBeenCalled();
500+
expect(refreshSpy).toHaveBeenCalledWith(true, true);
503501
});
504502

505503
it('should call refreshPagination when "onFilterChanged" is triggered', () => {
504+
const resetSpy = jest.spyOn(service, 'resetPagination');
506505
const spy = jest.spyOn(service, 'refreshPagination');
507506

508507
service.init(gridStub, dataviewStub, mockGridOption.pagination, mockGridOption.backendServiceApi);
509508
filterServiceStub.onFilterChanged.next([{ columnId: 'field1', operator: '=', searchTerms: [] }]);
510509

511-
expect(spy).toHaveBeenCalledWith(true);
510+
expect(resetSpy).toHaveBeenCalled();
511+
expect(spy).toHaveBeenCalledWith(true, true);
512512
});
513513
});
514514

515515
describe('resetPagination method', () => {
516-
it('should call "refreshPagination" with argument True when calling the method', () => {
516+
it('should call "refreshPagination" with 2 arguments True when calling the method', () => {
517517
const spy = jest.spyOn(service, 'refreshPagination');
518518
service.init(gridStub, dataviewStub, mockGridOption.pagination, mockGridOption.backendServiceApi);
519519
service.resetPagination();
520520

521-
expect(spy).toHaveBeenCalledWith(true);
521+
expect(spy).toHaveBeenCalledWith(true, true);
522+
});
523+
524+
it('should call "refreshPagination" with True and False arguments when calling the method with False being passed as input argument', () => {
525+
const spy = jest.spyOn(service, 'refreshPagination');
526+
service.init(gridStub, dataviewStub, mockGridOption.pagination, mockGridOption.backendServiceApi);
527+
service.resetPagination(false);
528+
529+
expect(spy).toHaveBeenCalledWith(true, false);
522530
});
523531
});
524532

@@ -540,8 +548,7 @@ describe('PaginationService', () => {
540548
gridServiceStub.onItemAdded.next(mockItems);
541549

542550
setTimeout(() => {
543-
// called 2x times by init() then by processOnItemAddedOrRemoved()
544-
expect(paginationSpy).toHaveBeenCalledTimes(2);
551+
expect(paginationSpy).toHaveBeenCalledTimes(1);
545552
expect(recalculateSpy).toHaveBeenCalledTimes(2);
546553
expect(service.pager.from).toBe(26);
547554
expect(service.pager.to).toBe(50 + 1);
@@ -558,8 +565,7 @@ describe('PaginationService', () => {
558565
gridServiceStub.onItemAdded.next(mockItems);
559566

560567
setTimeout(() => {
561-
// called 2x times by init() then by processOnItemAddedOrRemoved()
562-
expect(paginationSpy).toHaveBeenCalledTimes(2);
568+
expect(paginationSpy).toHaveBeenCalledTimes(1);
563569
expect(recalculateSpy).toHaveBeenCalledTimes(2);
564570
expect(service.pager.from).toBe(26);
565571
expect(service.pager.to).toBe(50 + mockItems.length);
@@ -575,8 +581,7 @@ describe('PaginationService', () => {
575581
gridServiceStub.onItemAdded.next(null);
576582

577583
setTimeout(() => {
578-
// called 1x time by init() only
579-
expect(paginationSpy).toHaveBeenCalledTimes(1);
584+
expect(paginationSpy).not.toHaveBeenCalled();
580585
expect(recalculateSpy).toHaveBeenCalledTimes(1);
581586
expect(service.pager.from).toBe(26);
582587
expect(service.pager.to).toBe(50);
@@ -593,8 +598,7 @@ describe('PaginationService', () => {
593598
gridServiceStub.onItemDeleted.next(mockItems);
594599

595600
setTimeout(() => {
596-
// called 2x times by init() then by processOnItemAddedOrRemoved()
597-
expect(paginationSpy).toHaveBeenCalledTimes(2);
601+
expect(paginationSpy).toHaveBeenCalledTimes(1);
598602
expect(recalculateSpy).toHaveBeenCalledTimes(2);
599603
expect(service.pager.from).toBe(26);
600604
expect(service.pager.to).toBe(50 - 1);
@@ -611,8 +615,7 @@ describe('PaginationService', () => {
611615
gridServiceStub.onItemDeleted.next(mockItems);
612616

613617
setTimeout(() => {
614-
// called 2x times by init() then by processOnItemAddedOrRemoved()
615-
expect(paginationSpy).toHaveBeenCalledTimes(2);
618+
expect(paginationSpy).toHaveBeenCalledTimes(1);
616619
expect(recalculateSpy).toHaveBeenCalledTimes(2);
617620
expect(service.pager.from).toBe(26);
618621
expect(service.pager.to).toBe(50 - mockItems.length);
@@ -629,8 +632,7 @@ describe('PaginationService', () => {
629632
gridServiceStub.onItemDeleted.next(null);
630633

631634
setTimeout(() => {
632-
// called 1x time by init() only
633-
expect(paginationSpy).toHaveBeenCalledTimes(1);
635+
expect(paginationSpy).not.toHaveBeenCalled();
634636
expect(recalculateSpy).toHaveBeenCalledTimes(1);
635637
expect(service.pager.from).toBe(26);
636638
expect(service.pager.to).toBe(50);
@@ -662,7 +664,6 @@ describe('PaginationService', () => {
662664

663665
it('should initialize the service and call "refreshPagination" with some DataView calls', () => {
664666
const refreshSpy = jest.spyOn(service, 'refreshPagination');
665-
const paginationSpy = jest.spyOn(service.onPaginationChanged, 'next');
666667
const onPagingSpy = jest.spyOn(dataviewStub.onPagingInfoChanged, 'subscribe');
667668
const setRefreshSpy = jest.spyOn(dataviewStub, 'setRefreshHints');
668669
const setPagingSpy = jest.spyOn(dataviewStub, 'setPagingOptions');
@@ -675,9 +676,6 @@ describe('PaginationService', () => {
675676
expect(setRefreshSpy).toHaveBeenCalled();
676677
expect(setPagingSpy).toHaveBeenCalledWith({ pageSize: 25, pageNum: 0 });
677678
expect(service.getCurrentPageNumber()).toBe(2);
678-
expect(paginationSpy).toHaveBeenCalledWith({
679-
from: 26, to: 50, itemsPerPage: 25, pageCount: 4, pageNumber: 2, totalItems: 85, availablePageSizes: mockGridOption.pagination.pageSizes
680-
});
681679
});
682680

683681
it('should change the totalItems when "onPagingInfoChanged" from the DataView is triggered with a different total', () => {

0 commit comments

Comments
 (0)