Skip to content

Commit

Permalink
Added pagination 📑 for listReviews 👥 endpoint (#104)
Browse files Browse the repository at this point in the history
Implemented the pagination method when fetching reviews, as the default
endpoint has a hard limit of 30 results. By adding pagination we can go
over the limit of 30.

Fixes #102
  • Loading branch information
Bullrich authored Nov 29, 2023
1 parent a2f4704 commit f4e4c61
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 43 deletions.
2 changes: 1 addition & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ outputs:

runs:
using: 'docker'
image: 'docker://ghcr.io/paritytech/review-bot/action:2.2.0'
image: 'Dockerfile'
1 change: 0 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
testTimeout: 8_000,
testMatch: [__dirname + "/src/**/test/**/*.test.ts"],
};
8 changes: 5 additions & 3 deletions src/github/pullRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,10 @@ export class PullRequestApi {
/** List all the approved reviews in a PR */
async listApprovedReviewsAuthors(countAuthor: boolean): Promise<string[]> {
if (!this.usersThatApprovedThePr) {
const request = await this.api.rest.pulls.listReviews({ ...this.repoInfo, pull_number: this.number });
const reviews = request.data as PullRequestReview[];
const reviews = await this.api.paginate(this.api.rest.pulls.listReviews, {
...this.repoInfo,
pull_number: this.number,
});
this.logger.debug(`List of reviews: ${JSON.stringify(reviews)}`);

const latestReviewsMap = new Map<number, PullRequestReview>();
Expand All @@ -82,7 +84,7 @@ export class PullRequestApi {
prevReview.id < review.id
) {
// if the review is more modern (and not a comment) we replace the one in our map
latestReviewsMap.set(review.user.id, review);
latestReviewsMap.set(review.user.id, review as PullRequestReview);
}
}

Expand Down
78 changes: 48 additions & 30 deletions src/test/fellows.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { mock, mockClear, MockProxy } from "jest-mock-extended";
import { ActionLogger, TeamApi } from "../github/types";
import { PolkadotFellows } from "../polkadot/fellows";

const timeout = 15_000;

describe("CAPI test", () => {
let fellows: TeamApi;
let logger: MockProxy<ActionLogger>;
Expand All @@ -13,20 +15,28 @@ describe("CAPI test", () => {
fellows = new PolkadotFellows(logger);
});

test("Should fetch fellows", async () => {
const members = await fellows.getTeamMembers("2");
expect(members.length).toBeGreaterThan(0);
});
test(
"Should fetch fellows",
async () => {
const members = await fellows.getTeamMembers("2");
expect(members.length).toBeGreaterThan(0);
},
timeout,
);

test("Should cache fellows", async () => {
const members = await fellows.getTeamMembers("2");
expect(members.length).toBeGreaterThan(0);
expect(logger.debug).toHaveBeenCalledWith("Connecting to collective parachain");
mockClear(logger);
const members2 = await fellows.getTeamMembers("2");
expect(members2.length).toBeGreaterThan(0);
expect(logger.debug).not.toHaveBeenCalledWith("Connecting to collective parachain");
});
test(
"Should cache fellows",
async () => {
const members = await fellows.getTeamMembers("2");
expect(members.length).toBeGreaterThan(0);
expect(logger.debug).toHaveBeenCalledWith("Connecting to collective parachain");
mockClear(logger);
const members2 = await fellows.getTeamMembers("2");
expect(members2.length).toBeGreaterThan(0);
expect(logger.debug).not.toHaveBeenCalledWith("Connecting to collective parachain");
},
timeout,
);

describe("Fetch by rank", () => {
beforeEach(() => {
Expand All @@ -39,27 +49,35 @@ describe("CAPI test", () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(fellows as any).fellowsCache = fellowsMap;
});
test("should return fellows of a give rank", async () => {
const rank1 = await fellows.getTeamMembers("1");
expect(rank1).toEqual(["user-1", "user-2", "user-3", "user-4", "user-5"]);
test(
"should return fellows of a give rank",
async () => {
const rank1 = await fellows.getTeamMembers("1");
expect(rank1).toEqual(["user-1", "user-2", "user-3", "user-4", "user-5"]);

const rank2 = await fellows.getTeamMembers("2");
expect(rank2).toEqual(["user-2", "user-3", "user-4", "user-5"]);
const rank2 = await fellows.getTeamMembers("2");
expect(rank2).toEqual(["user-2", "user-3", "user-4", "user-5"]);

const rank3 = await fellows.getTeamMembers("3");
expect(rank3).toEqual(["user-3", "user-4", "user-5"]);
const rank3 = await fellows.getTeamMembers("3");
expect(rank3).toEqual(["user-3", "user-4", "user-5"]);

const rank4 = await fellows.getTeamMembers("4");
expect(rank4).toEqual(["user-4", "user-5"]);
const rank4 = await fellows.getTeamMembers("4");
expect(rank4).toEqual(["user-4", "user-5"]);

const rank5 = await fellows.getTeamMembers("5");
expect(rank5).toEqual(["user-5"]);
});
const rank5 = await fellows.getTeamMembers("5");
expect(rank5).toEqual(["user-5"]);
},
timeout,
);

test("should throw if there are no fellows available", async () => {
await expect(fellows.getTeamMembers("6")).rejects.toThrowError(
"Found no members of rank 6 or higher. Please see debug logs",
);
});
test(
"should throw if there are no fellows available",
async () => {
await expect(fellows.getTeamMembers("6")).rejects.toThrowError(
"Found no members of rank 6 or higher. Please see debug logs",
);
},
timeout,
);
});
});
8 changes: 3 additions & 5 deletions src/test/github.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { PullRequest, PullRequestReview } from "@octokit/webhooks-types";
import { DeepMockProxy, mock, mockDeep, MockProxy } from "jest-mock-extended";
import { any, DeepMockProxy, mock, mockDeep, MockProxy } from "jest-mock-extended";

import { PullRequestApi } from "../github/pullRequest";
import { ActionLogger, GitHubClient } from "../github/types";
Expand All @@ -25,9 +25,7 @@ describe("Pull Request API Tests", () => {
let reviews: PullRequestReview[];
beforeEach(() => {
reviews = [];
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore because the official type and the library type do not match
client.rest.pulls.listReviews.mockResolvedValue({ data: reviews as unknown });
client.paginate.calledWith(client.rest.pulls.listReviews, any()).mockResolvedValue(reviews as unknown);
});

test("Should return approval", async () => {
Expand All @@ -51,7 +49,7 @@ describe("Pull Request API Tests", () => {
expect(approvals).toEqual(["yes-user"]);
}

expect(client.rest.pulls.listReviews).toHaveBeenCalledTimes(1);
expect(client.paginate).toHaveBeenCalledTimes(1);
});

test("Should return approvals and ignore other reviews", async () => {
Expand Down
5 changes: 2 additions & 3 deletions src/test/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
import { PullRequest, PullRequestReview } from "@octokit/webhooks-types";
import { existsSync, openSync, readFileSync, unlinkSync } from "fs";
import { DeepMockProxy, mock, mockDeep, MockProxy } from "jest-mock-extended";
import { any, DeepMockProxy, mock, mockDeep, MockProxy } from "jest-mock-extended";
import { join } from "path";

import { GitHubChecksApi } from "../github/check";
Expand Down Expand Up @@ -67,8 +67,7 @@ describe("Integration testing", () => {
return { state, id, user: { login, id: getHash(login) } };
});

// @ts-ignore because the official type and the library type do not match
client.rest.pulls.listReviews.mockResolvedValue({ data });
client.paginate.calledWith(client.rest.pulls.listReviews, any()).mockResolvedValue(data);
};

const summaryTestFile = "./summary-test.html";
Expand Down

0 comments on commit f4e4c61

Please sign in to comment.