Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions src/capacitor/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,13 @@ export class FluxCapacitor extends EventEmitter {

resize(pageSize: number, resetOffset?: boolean): Promise<Results> {
this.query.withPageSize(pageSize);
const skip = resetOffset ? 0 : Math.floor(this.page.fromResult / pageSize) * pageSize;
this.query.skip(skip);
this.emit(Events.PAGE_CHANGED, { pageNumber: this.page.currentPage });
return this.search();
if (resetOffset) {
return this.page.switchPage(1);
} else {
const total = this.page.restrictTotalRecords(this.page.fromResult, pageSize);
const page = this.page.getPage(total);
return this.page.switchPage(page);
}
}

sort(sort: Sort, clearSorts: Sort[] = [sort]): Promise<Results> {
Expand Down
24 changes: 22 additions & 2 deletions src/capacitor/pager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { Results } from '../models/response';
import { Events, FluxCapacitor } from './index';
import range = require('lodash.range');

const MAX_RECORDS = 10000;

export class Pager {

constructor(private flux: FluxCapacitor) { }
Expand All @@ -23,7 +25,7 @@ export class Pager {
}

get currentPage(): number {
return Math.ceil(this.fromResult / this.pageSize);
return this.getPage(this.fromResult);
}

get previousPage(): number | null {
Expand All @@ -39,7 +41,7 @@ export class Pager {
}

get finalPage(): number {
return Math.max(Math.ceil(this.totalRecords / this.pageSize), 1);
return Math.max(this.getPage(this.restrictTotalRecords(this.totalRecords, this.pageSize)), 1);
}

get fromResult(): number {
Expand Down Expand Up @@ -78,6 +80,24 @@ export class Pager {
}
}

restrictTotalRecords(total: number, pageSize: number): number {
if (total > MAX_RECORDS) {
return MAX_RECORDS - (MAX_RECORDS % pageSize);
} else if ((total + pageSize) > MAX_RECORDS) {
if (MAX_RECORDS % pageSize === 0) {
return MAX_RECORDS;
} else {
return total - (total % pageSize);
}
} else {
return total;
}
}

getPage(record: number): number {
return Math.ceil(record / this.pageSize);
}

private transformPages(limit: number): (value: number) => number {
const border = Math.ceil(limit / 2);
return (value: number): number => {
Expand Down
38 changes: 38 additions & 0 deletions test/capacitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,19 @@ describe('FluxCapacitor', function() {
it('should resize the page and keep skip', (done) => {
flux.query.withPageSize(10);
flux.query.skip(20);
flux.page.pageExists = () => true;
mock.post(SEARCH_URL, (req, res) => {
expect(JSON.parse(req.body()).skip).to.eq(20);
expect(JSON.parse(req.body()).pageSize).to.eq(20);
done();
});
flux.resize(20, false);
});

it('should resize the page and keep skip on the same page', (done) => {
flux.query.withPageSize(10);
flux.query.skip(30);
flux.page.pageExists = () => true;
mock.post(SEARCH_URL, (req, res) => {
expect(JSON.parse(req.body()).skip).to.eq(20);
expect(JSON.parse(req.body()).pageSize).to.eq(20);
Expand All @@ -300,13 +313,38 @@ describe('FluxCapacitor', function() {
it('should resize the page and bring skip to 0', (done) => {
flux.query.withPageSize(10);
flux.query.skip(20);
flux.page.pageExists = () => true;
mock.post(SEARCH_URL, (req, res) => {
expect(JSON.parse(req.body()).skip).to.eq(0);
expect(JSON.parse(req.body()).pageSize).to.eq(30);
done();
});
flux.resize(30, true);
});

it('should resize from smaller to larger and keep skip when total near max', (done) => {
flux.query.withPageSize(12);
flux.query.skip(9984);
flux.page.pageExists = () => true;
mock.post(SEARCH_URL, (req, res) => {
expect(JSON.parse(req.body()).skip).to.eq(9960);
expect(JSON.parse(req.body()).pageSize).to.eq(24);
done();
});
flux.resize(24, false);
});

it('should resize from larger to smaller and keep skip when total near max', (done) => {
flux.query.withPageSize(50);
flux.query.skip(9950);
flux.page.pageExists = () => true;
mock.post(SEARCH_URL, (req, res) => {
expect(JSON.parse(req.body()).skip).to.eq(9947);
expect(JSON.parse(req.body()).pageSize).to.eq(49);
done();
});
flux.resize(49, false);
});
});

describe('rewrite()', () => {
Expand Down
66 changes: 28 additions & 38 deletions test/pager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ describe('Pager', function() {
expect(mockFlux.query.raw.skip).to.eq(2);
});

it('should not change skip when cannot page forward', () => {
const mockFlux = flux(29, () => null);
const pager = new Pager(mockFlux);
expect(mockFlux.query.raw.skip).to.eq(29);
pager.next();
expect(mockFlux.query.raw.skip).to.eq(29);
});

it('should reset the skip to 0', (done) => {
new Pager(flux(2, function() {
expect(this.query.raw.skip).to.eq(0);
Expand Down Expand Up @@ -116,42 +124,11 @@ describe('Pager', function() {
})).last();
});

describe('realigned paging behaviour', () => {
// it('should not realign the pages on page next', () => {
// new Pager(flux({ start: 13, total: 45 }, function() {
// expect(this.query.raw.skip).to.eq(23);
// })).next();
// });
//
// it('should realign the pages on page next', () => {
// new Pager(flux({ start: 13, total: 45 }, function() {
// expect(this.query.raw.skip).to.eq(20);
// })).next(true);
// });
//
// it('should not skip past last page', () => {
// new Pager(flux({ start: 43, total: 45 }, function() {
// expect(this.query.raw.skip).to.eq(40);
// })).next(true);
// });
//
// it('should not realign the pages on page previous', () => {
// new Pager(flux({ start: 23, total: 45 }, function() {
// expect(this.query.raw.skip).to.eq(13);
// })).prev();
// });
//
// it('should realign the pages on page previous', () => {
// new Pager(flux({ start: 23, total: 45 }, function() {
// expect(this.query.raw.skip).to.eq(10);
// })).prev(true);
// });
//
// it('should not realign to a negative value', () => {
// new Pager(flux({ start: 3, total: 45 }, function() {
// expect(this.query.raw.skip).to.eq(0);
// })).prev(true);
// });
it('max skip should not go beyond 10000 records', (done) => {
new Pager(flux({ start: 1, total: 14000 }, function() {
expect(this.query.raw.skip).to.eq(9990);
done();
})).last();
});

describe('pageExists()', () => {
Expand All @@ -166,7 +143,7 @@ describe('Pager', function() {
});
});

describe('switchPage behaviour', () => {
describe('switchPage() behaviour', () => {
it('should switchPage to the first page', () => {
const pager = new Pager(flux({ start: 10, total: 200 }, function() {
expect(this.query.raw.skip).to.eq(0);
Expand Down Expand Up @@ -202,6 +179,19 @@ describe('Pager', function() {
});
});

describe('restrictTotalRecords()', () => {
it('should return total records that is less than MAX_RECORDS', () => {
const pager = new Pager(<any>{});
expect(pager.restrictTotalRecords(20000, 10)).to.eq(10000);
expect(pager.restrictTotalRecords(20000, 12)).to.eq(9996);
expect(pager.restrictTotalRecords(20000, 24)).to.eq(9984);
expect(pager.restrictTotalRecords(20000, 50)).to.eq(10000);
expect(pager.restrictTotalRecords(9999, 13)).to.eq(9997);
expect(pager.restrictTotalRecords(9960, 50)).to.eq(10000);
expect(pager.restrictTotalRecords(100, 20)).to.eq(100);
});
});

describe('current page behaviour', () => {
it('should return the current page', () => {
expect(new Pager(flux(1)).currentPage).to.eq(1);
Expand Down Expand Up @@ -230,7 +220,7 @@ describe('Pager', function() {
});
});

describe('pages behaviour', () => {
describe('page numbers behaviour', () => {
it('should return an array of beginning at 1', () => {
expect(new Pager(flux({ start: 1, total: 100 })).pageNumbers()).to.eql([1, 2, 3, 4, 5]);
});
Expand Down