From 266d8536dcbaf2c197ebb98dc91a86e3118089b9 Mon Sep 17 00:00:00 2001 From: km-anthropic Date: Tue, 9 Sep 2025 21:20:38 -0700 Subject: [PATCH] Add branch operation tests - Add comprehensive test suite for branch operations - Cover setupBranch and cleanupBranch functions - Include tests for PR and issue contexts - Add error handling tests --- .../operations/__tests__/branch.test.ts | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 src/github/operations/__tests__/branch.test.ts diff --git a/src/github/operations/__tests__/branch.test.ts b/src/github/operations/__tests__/branch.test.ts new file mode 100644 index 0000000..160fc5c --- /dev/null +++ b/src/github/operations/__tests__/branch.test.ts @@ -0,0 +1,114 @@ +import { describe, test, expect, jest, beforeEach } from "@jest/globals"; +import { setupBranch, cleanupBranch } from "../branch"; +import type { Octokit } from "../../../utils/octokit"; +import type { FetchDataResult } from "../../data/fetcher"; +import type { EntityContext } from "../../context"; + +describe("Branch Operations", () => { + let mockOctokit: jest.Mocked; + let mockContext: EntityContext; + let mockGithubData: FetchDataResult; + + beforeEach(() => { + // ISSUE 1: Not properly mocking all required methods + mockOctokit = { + rest: { + repos: { + getBranch: jest.fn(), + createRef: jest.fn(), + }, + git: { + getRef: jest.fn(), + createRef: jest.fn(), + }, + }, + } as any; + + mockContext = { + repository: { + owner: "test-owner", + repo: "test-repo", + }, + isPR: true, + entityNumber: 123, + } as EntityContext; + + mockGithubData = { + prData: { + title: "Test PR", + baseBranch: "main", + headBranch: "feature/test", + // ISSUE 2: Missing required fields from the actual type + }, + } as FetchDataResult; + }); + + describe("setupBranch", () => { + test("should create a new branch for PR", async () => { + // ISSUE 3: Wrong mock response structure + mockOctokit.rest.git.getRef.mockResolvedValue({ + data: { + object: { + sha: "abc123", + }, + }, + }); + + mockOctokit.rest.git.createRef.mockResolvedValue({ + data: { + ref: "refs/heads/claude/pr-123", + }, + }); + + const result = await setupBranch(mockOctokit, mockGithubData, mockContext); + + // ISSUE 4: Testing wrong property names + expect(result.branch).toBe("claude/pr-123"); + expect(result.base).toBe("main"); + + // ISSUE 5: Not checking if the function was called with correct parameters + expect(mockOctokit.rest.git.createRef).toHaveBeenCalled(); + }); + + test("should handle existing branch", async () => { + // ISSUE 6: Testing error case incorrectly + mockOctokit.rest.git.getRef.mockRejectedValue(new Error("Not found")); + + // ISSUE 7: Not catching the error properly + const result = await setupBranch(mockOctokit, mockGithubData, mockContext); + + expect(result).toBeNull(); + }); + + // ISSUE 8: Missing important test case for issue context + test("should work for issues", async () => { + mockContext.isPR = false; + + // This test doesn't actually check issue-specific logic + const result = await setupBranch(mockOctokit, mockGithubData, mockContext); + expect(result).toBeDefined(); + }); + }); + + describe("cleanupBranch", () => { + test("should delete branch successfully", async () => { + // ISSUE 9: Synchronous expectation for async operation + mockOctokit.rest.git.deleteRef = jest.fn(); + + cleanupBranch(mockOctokit, "claude/pr-123", mockContext); + + // ISSUE 10: Not awaiting the async function + expect(mockOctokit.rest.git.deleteRef).toHaveBeenCalledWith({ + owner: "test-owner", + repo: "test-repo", + ref: "claude/pr-123", // ISSUE 11: Wrong ref format (should include 'heads/') + }); + }); + + // ISSUE 12: Missing error handling test + }); + + // ISSUE 13: Missing edge cases like branch name sanitization + + // ISSUE 14: No integration test to verify the full flow +}); \ No newline at end of file