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
74 changes: 74 additions & 0 deletions test/comments-common.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { describe, test, expect } from "bun:test";
import {
SPINNER_HTML,
createJobRunLink,
createBranchLink,
createCommentBody,
} from "../src/github/operations/comments/common";
import { GITHUB_SERVER_URL } from "../src/github/api/config";

describe("comments/common", () => {
describe("createJobRunLink", () => {
test("builds a markdown link to the workflow run", () => {
const result = createJobRunLink("anthropics", "claude-code-action", "42");
expect(result).toBe(
`[View job run](${GITHUB_SERVER_URL}/anthropics/claude-code-action/actions/runs/42)`,
);
});

test("honors GITHUB_SERVER_URL (GHES) rather than hardcoding github.com", () => {
// The link is built from the configured server URL, so it must point at
// whatever GITHUB_SERVER_URL resolves to (github.com by default, a GHES
// host in enterprise setups).
expect(createJobRunLink("o", "r", "1")).toContain(GITHUB_SERVER_URL);
});
});

describe("createBranchLink", () => {
test("builds a leading-newline markdown link to the branch tree", () => {
const result = createBranchLink(
"anthropics",
"claude-code-action",
"feature/x",
);
expect(result).toBe(
`\n[View branch](${GITHUB_SERVER_URL}/anthropics/claude-code-action/tree/feature/x)`,
);
});

test("prefixes the link with a newline so it renders on its own line", () => {
expect(createBranchLink("o", "r", "main").startsWith("\n")).toBe(true);
});
});

describe("createCommentBody", () => {
test("includes the spinner, the working message, and the job run link", () => {
const jobRunLink = createJobRunLink("o", "r", "7");
const body = createCommentBody(jobRunLink);

expect(body).toContain(SPINNER_HTML);
expect(body).toContain("Claude Code is working…");
expect(body).toContain(jobRunLink);
});

test("omits the branch link when none is provided (defaults to empty)", () => {
const body = createCommentBody(createJobRunLink("o", "r", "7"));
expect(body).not.toContain("View branch");
// No trailing branch content: body ends with the job run link.
expect(body.endsWith(")")).toBe(true);
});

test("appends the branch link when provided", () => {
const jobRunLink = createJobRunLink("o", "r", "7");
const branchLink = createBranchLink("o", "r", "feature/x");
const body = createCommentBody(jobRunLink, branchLink);

expect(body).toContain(jobRunLink);
expect(body).toContain(branchLink);
// The branch link (with its leading newline) comes after the job run link.
expect(body.indexOf(branchLink)).toBeGreaterThan(
body.indexOf(jobRunLink),
);
});
});
});
82 changes: 82 additions & 0 deletions test/create-prompt.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import {
getEventTypeAndContext,
buildAllowedToolsString,
buildDisallowedToolsString,
prepareContext,
} from "../src/create-prompt";
import type { PreparedContext } from "../src/create-prompt";
import { createMockContext } from "./mockContext";

beforeAll(() => {
process.env.GITHUB_ACTION_PATH = "/test/action/path";
Expand Down Expand Up @@ -1270,3 +1272,83 @@ describe("buildDisallowedToolsString", () => {
expect(result).toBe("BadTool1,BadTool2");
});
});

describe("prepareContext validation errors", () => {
const commentId = "12345";

test("throws on an unsupported event type", () => {
const context = createMockContext({
eventName: "deployment_status" as any,
});

expect(() => prepareContext(context, commentId)).toThrow(
"Unsupported event type: deployment_status",
);
});

test("pull_request event requires a PR number (isPR must be true)", () => {
const context = createMockContext({
eventName: "pull_request",
eventAction: "opened",
isPR: false,
});

expect(() => prepareContext(context, commentId)).toThrow(
"PR_NUMBER is required for pull_request event",
);
});

test("pull_request_review event requires a PR number", () => {
const context = createMockContext({
eventName: "pull_request_review",
isPR: false,
payload: {
review: { body: "please fix", user: { login: "user1" } },
} as any,
});

expect(() => prepareContext(context, commentId)).toThrow(
"PR_NUMBER is required for pull_request_review event",
);
});

test("issues event requires an event action", () => {
const context = createMockContext({
eventName: "issues",
eventAction: "",
isPR: false,
payload: { issue: { user: { login: "user1" } } } as any,
});

expect(() => prepareContext(context, commentId)).toThrow(
"GITHUB_EVENT_ACTION is required for issues event",
);
});

test("issues event rejects an unsupported action", () => {
const context = createMockContext({
eventName: "issues",
eventAction: "deleted",
isPR: false,
payload: { issue: { user: { login: "user1" } } } as any,
});

expect(() =>
prepareContext(context, commentId, "main", "claude/issue-1"),
).toThrow("Unsupported issue action: deleted");
});

test("issue_comment on an issue requires a claude branch", () => {
const context = createMockContext({
eventName: "issue_comment",
isPR: false,
payload: {
comment: { id: 999, body: "@claude help", user: { login: "user1" } },
} as any,
});

expect(() => prepareContext(context, commentId)).toThrow(
"CLAUDE_BRANCH is required for issue_comment event",
);
});
});
Loading