Skip to content

Commit

Permalink
- Remove bad guard clause on pagination handling (#419)
Browse files Browse the repository at this point in the history
- Add unit test to verify pagination workflow retrieves all valid pages
  • Loading branch information
nwithan8 committed Nov 2, 2023
1 parent 891e4a5 commit 4f75889
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/services/base_service.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ export default (easypostClient) =>
};

const response = await this._all(url, params);
if (response == undefined || response[url].length == 0 || !response.has_more) {
if (response == undefined || response[url].length == 0) {
throw new EndOfPaginationError();
}

Expand Down
119 changes: 119 additions & 0 deletions test/services/base_service.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/* eslint-disable func-names */
import { expect } from 'chai';

import EasyPostClient from '../../src/easypost';
import EndOfPaginationError from '../../src/errors/general/end_of_pagination_error';
import * as setupPolly from '../helpers/setup_polly';
import {
MockMiddleware,
MockRequest,
MockRequestMatchRule,
MockRequestResponseInfo,
} from '../helpers/mocking';

describe('Base Service', function () {
setupPolly.startPolly();

beforeEach(function () {
const { server } = this.polly;
setupPolly.setupCassette(server);
});

it('getNextPage collects all pages', async function () {
const pageSize = 1; // Doesn't matter what this is, we're mocking the response

let allResults = [];
let previousPage = null;

// Using scanforms as an example, but this should work for any service since it's a base class method
// Mock the initial "get all scanforms" call
let firstPageResponse = {
scan_forms: [
{
id: 'sf_123',
},
],
has_more: true,
};
let middleware = (request) => {
return new MockMiddleware(request, [
new MockRequest(
new MockRequestMatchRule('GET', 'v2\\/scan_forms'),
new MockRequestResponseInfo(200, firstPageResponse),
),
]);
};
this.client = new EasyPostClient(process.env.EASYPOST_TEST_API_KEY, {
requestMiddleware: middleware,
});

let firstPage = await this.client.ScanForm.all({ page_size: pageSize });
allResults = allResults.concat(firstPage.scan_forms);
previousPage = firstPage;

// Mock the first "get next page" call with more to collect after
// (current page "has_more" = True, next page "has_more" = True)
let secondPageResponse = {
scan_forms: [
{
id: 'sf_456',
},
],
has_more: true,
};
middleware = (request) => {
return new MockMiddleware(request, [
new MockRequest(
new MockRequestMatchRule('GET', 'v2\\/scan_forms'),
new MockRequestResponseInfo(200, secondPageResponse),
),
]);
};
this.client = new EasyPostClient(process.env.EASYPOST_TEST_API_KEY, {
requestMiddleware: middleware,
});

let secondPage = await this.client.ScanForm.getNextPage(previousPage, pageSize);
allResults = allResults.concat(secondPage.scan_forms);
previousPage = secondPage;

// Mock the second "get next page" call with no more to collect after
// (current page "has_more" = True, next page "has_more" = False)
let thirdPageResponse = {
scan_forms: [
{
id: 'sf_789',
},
],
has_more: false,
};
middleware = (request) => {
return new MockMiddleware(request, [
new MockRequest(
new MockRequestMatchRule('GET', 'v2\\/scan_forms'),
new MockRequestResponseInfo(200, thirdPageResponse),
),
]);
};
this.client = new EasyPostClient(process.env.EASYPOST_TEST_API_KEY, {
requestMiddleware: middleware,
});

let thirdPage = await this.client.ScanForm.getNextPage(previousPage, pageSize);
allResults = allResults.concat(thirdPage.scan_forms);
previousPage = thirdPage;

// Verify we have all scanforms (from the initial "get all scanforms" and two subsequent "get next page" calls)
// Ensures no guard clauses inside the "get next page" method are preventing us from collecting all scanforms
expect(allResults.length).to.equal(3);

// Now that the previous page has "has_more" = False, it should throw an error before even making the API call
try {
await this.client.ScanForm.getNextPage(previousPage, pageSize);
// if the above line doesn't throw an error, the test should fail
expect.fail();
} catch (error) {
expect(error).instanceOf(EndOfPaginationError);
}
});
});

0 comments on commit 4f75889

Please sign in to comment.