fix: use per-review comment fetching for Forgejo compatibility
Forgejo doesn't have the flat GET /pulls/{number}/comments endpoint
(returns 404). Replace pulls.listReviewComments() with a 2-phase
approach: fetch reviews first, then pulls.listCommentsForReview()
per-review in parallel. Updates tests to mock the new per-review API.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
efe30422e7
commit
b4a6c34853
2 files changed
+48
-25
No files matched your search
@@ -29,11 +29,25 @@ function createMockOctokits({
|
||||
filesData?: Record<string, unknown>[];
|
||||
commitsData?: Record<string, unknown>[];
|
||||
commentsData?: Record<string, unknown>[];
|
||||
reviewsData?: Record<string, unknown>[];
|
||||
reviewCommentsData?: Record<string, unknown>[];
|
||||
reviewsData?: (Record<string, unknown> & { id?: number })[];
|
||||
reviewCommentsData?: (Record<string, unknown> & {
|
||||
pull_request_review_id?: number | null;
|
||||
})[];
|
||||
issueData?: Record<string, unknown>;
|
||||
userData?: Record<string, unknown>;
|
||||
} = {}) {
|
||||
// Build per-review mock: listCommentsForReview returns comments matching
|
||||
// the requested review_id (Forgejo doesn't have a flat review-comments endpoint).
|
||||
const allReviewComments = reviewCommentsData ?? [];
|
||||
const listCommentsForReviewMock = jest
|
||||
.fn()
|
||||
.mockImplementation((params: { review_id: number }) => {
|
||||
const matching = allReviewComments.filter(
|
||||
(c) => c.pull_request_review_id === params.review_id,
|
||||
);
|
||||
return Promise.resolve({ data: matching });
|
||||
});
|
||||
|
||||
return {
|
||||
rest: {
|
||||
pulls: {
|
||||
@@ -41,9 +55,7 @@ function createMockOctokits({
|
||||
listFiles: jest.fn().mockResolvedValue({ data: filesData ?? [] }),
|
||||
listCommits: jest.fn().mockResolvedValue({ data: commitsData ?? [] }),
|
||||
listReviews: jest.fn().mockResolvedValue({ data: reviewsData ?? [] }),
|
||||
listReviewComments: jest
|
||||
.fn()
|
||||
.mockResolvedValue({ data: reviewCommentsData ?? [] }),
|
||||
listCommentsForReview: listCommentsForReviewMock,
|
||||
},
|
||||
issues: {
|
||||
get: jest.fn().mockResolvedValue({ data: issueData ?? {} }),
|
||||
@@ -114,7 +126,7 @@ const mockIssueRestResponse = {
|
||||
|
||||
describe("fetchForgejoData", () => {
|
||||
describe("PR data fetching", () => {
|
||||
it("should fetch PR details, files, commits, comments, reviews, and inline comments in parallel", async () => {
|
||||
it("should fetch PR details, files, commits, comments, and reviews in parallel then per-review comments", async () => {
|
||||
const mockOctokits = createMockOctokits({
|
||||
prData: mockPrRestResponse,
|
||||
filesData: mockFilesRestResponse,
|
||||
@@ -128,7 +140,7 @@ describe("fetchForgejoData", () => {
|
||||
isPR: true,
|
||||
});
|
||||
|
||||
// Verify all six REST calls were made
|
||||
// Verify phase 1 REST calls (parallel)
|
||||
expect(mockOctokits.rest.pulls.get).toHaveBeenCalledWith({
|
||||
owner: "test-owner",
|
||||
repo: "test-repo",
|
||||
@@ -158,12 +170,7 @@ describe("fetchForgejoData", () => {
|
||||
pull_number: 42,
|
||||
per_page: 100,
|
||||
});
|
||||
expect(mockOctokits.rest.pulls.listReviewComments).toHaveBeenCalledWith({
|
||||
owner: "test-owner",
|
||||
repo: "test-repo",
|
||||
pull_number: 42,
|
||||
per_page: 100,
|
||||
});
|
||||
// Phase 2: per-review comment fetching (no reviews in this test → no calls)
|
||||
});
|
||||
|
||||
it("should map PR fields to GitHubPullRequest type", async () => {
|
||||
@@ -412,7 +419,9 @@ describe("fetchForgejoData", () => {
|
||||
expect(mockOctokits.rest.pulls.listFiles).not.toHaveBeenCalled();
|
||||
expect(mockOctokits.rest.pulls.listCommits).not.toHaveBeenCalled();
|
||||
expect(mockOctokits.rest.pulls.listReviews).not.toHaveBeenCalled();
|
||||
expect(mockOctokits.rest.pulls.listReviewComments).not.toHaveBeenCalled();
|
||||
expect(
|
||||
mockOctokits.rest.pulls.listCommentsForReview,
|
||||
).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should map issue fields to GitHubIssue type", async () => {
|
||||
|
||||
Reference in new issue
Block a user