feat: add support for pull request reviewer triggers (#12)

Co-authored-by: Oleg Zaimkin <oleg.zaimkin@developertools.com>
This commit is contained in:
Oleg
2025-10-17 09:54:56 +02:00
committed by GitHub
parent 225a4e6f3a
commit 92631f4d12
3 changed files with 465 additions and 2 deletions

View File

@@ -365,6 +365,343 @@ describe("checkContainsTrigger", () => {
});
});
describe("pull request reviewer trigger", () => {
it("should return true when PR has trigger user as requested reviewer (same as text mention)", () => {
const context = createMockContext({
eventName: "pull_request",
eventAction: "opened",
isPR: true,
payload: {
action: "opened",
pull_request: {
number: 123,
title: "Test PR",
body: "This PR fixes a bug",
created_at: "2023-01-01T00:00:00Z",
user: { login: "testuser" },
requested_reviewers: [
{ login: "claude", id: 1, type: "User" },
{ login: "other-reviewer", id: 2, type: "User" },
],
},
} as unknown as PullRequestEvent,
inputs: {
mode: "tag",
triggerPhrase: "@claude",
assigneeTrigger: "",
labelTrigger: "",
directPrompt: "",
overridePrompt: "",
allowedTools: [],
disallowedTools: [],
customInstructions: "",
branchPrefix: "claude/",
useStickyComment: false,
additionalPermissions: new Map(),
useCommitSigning: false,
},
});
expect(checkContainsTrigger(context)).toBe(true);
});
it("should return true for synchronized PR with trigger user as reviewer", () => {
const context = createMockContext({
eventName: "pull_request",
eventAction: "synchronized",
isPR: true,
payload: {
action: "synchronized",
pull_request: {
number: 123,
title: "Test PR",
body: "This PR fixes a bug",
created_at: "2023-01-01T00:00:00Z",
user: { login: "testuser" },
requested_reviewers: [
{ login: "claude", id: 1, type: "User" },
],
},
} as unknown as PullRequestEvent,
inputs: {
mode: "tag",
triggerPhrase: "@claude",
assigneeTrigger: "",
labelTrigger: "",
directPrompt: "",
overridePrompt: "",
allowedTools: [],
disallowedTools: [],
customInstructions: "",
branchPrefix: "claude/",
useStickyComment: false,
additionalPermissions: new Map(),
useCommitSigning: false,
},
});
expect(checkContainsTrigger(context)).toBe(true);
});
it("should return false when PR has no matching requested reviewers", () => {
const context = createMockContext({
eventName: "pull_request",
eventAction: "opened",
isPR: true,
payload: {
action: "opened",
pull_request: {
number: 123,
title: "Test PR",
body: "This PR fixes a bug",
created_at: "2023-01-01T00:00:00Z",
user: { login: "testuser" },
requested_reviewers: [
{ login: "other-reviewer", id: 2, type: "User" },
],
},
} as unknown as PullRequestEvent,
inputs: {
mode: "tag",
triggerPhrase: "@claude",
assigneeTrigger: "",
labelTrigger: "",
directPrompt: "",
overridePrompt: "",
allowedTools: [],
disallowedTools: [],
customInstructions: "",
branchPrefix: "claude/",
useStickyComment: false,
additionalPermissions: new Map(),
useCommitSigning: false,
},
});
expect(checkContainsTrigger(context)).toBe(false);
});
it("should handle trigger phrase without @ symbol", () => {
const context = createMockContext({
eventName: "pull_request",
eventAction: "opened",
isPR: true,
payload: {
action: "opened",
pull_request: {
number: 123,
title: "Test PR",
body: "This PR fixes a bug",
created_at: "2023-01-01T00:00:00Z",
user: { login: "testuser" },
requested_reviewers: [
{ login: "claude", id: 1, type: "User" },
],
},
} as unknown as PullRequestEvent,
inputs: {
mode: "tag",
triggerPhrase: "claude", // No @ symbol
assigneeTrigger: "",
labelTrigger: "",
directPrompt: "",
overridePrompt: "",
allowedTools: [],
disallowedTools: [],
customInstructions: "",
branchPrefix: "claude/",
useStickyComment: false,
additionalPermissions: new Map(),
useCommitSigning: false,
},
});
expect(checkContainsTrigger(context)).toBe(true);
});
});
it("should return true when PR has trigger user as requested reviewer for synchronized event", () => {
const context = createMockContext({
eventName: "pull_request",
eventAction: "synchronized",
isPR: true,
payload: {
action: "synchronized",
pull_request: {
number: 123,
title: "Test PR",
body: "This PR fixes a bug",
created_at: "2023-01-01T00:00:00Z",
user: { login: "testuser" },
requested_reviewers: [
{ login: "claude", id: 1, type: "User" },
],
requested_teams: [],
},
} as unknown as PullRequestEvent,
inputs: {
mode: "tag",
triggerPhrase: "@claude",
assigneeTrigger: "",
labelTrigger: "",
directPrompt: "",
overridePrompt: "",
allowedTools: [],
disallowedTools: [],
customInstructions: "",
branchPrefix: "claude/",
useStickyComment: false,
additionalPermissions: new Map(),
useCommitSigning: false,
},
});
expect(checkContainsTrigger(context)).toBe(true);
});
it("should return false when PR has no matching requested reviewers", () => {
const context = createMockContext({
eventName: "pull_request",
eventAction: "opened",
isPR: true,
payload: {
action: "opened",
pull_request: {
number: 123,
title: "Test PR",
body: "This PR fixes a bug",
created_at: "2023-01-01T00:00:00Z",
user: { login: "testuser" },
requested_reviewers: [
{ login: "other-reviewer", id: 2, type: "User" },
],
requested_teams: [],
},
} as unknown as PullRequestEvent,
inputs: {
mode: "tag",
triggerPhrase: "@claude",
assigneeTrigger: "",
labelTrigger: "",
directPrompt: "",
overridePrompt: "",
allowedTools: [],
disallowedTools: [],
customInstructions: "",
branchPrefix: "claude/",
useStickyComment: false,
additionalPermissions: new Map(),
useCommitSigning: false,
},
});
expect(checkContainsTrigger(context)).toBe(false);
});
it("should handle trigger phrase without @ symbol", () => {
const context = createMockContext({
eventName: "pull_request",
eventAction: "opened",
isPR: true,
payload: {
action: "opened",
pull_request: {
number: 123,
title: "Test PR",
body: "This PR fixes a bug",
created_at: "2023-01-01T00:00:00Z",
user: { login: "testuser" },
requested_reviewers: [
{ login: "claude", id: 1, type: "User" },
],
requested_teams: [],
},
} as unknown as PullRequestEvent,
inputs: {
mode: "tag",
triggerPhrase: "claude", // No @ symbol
assigneeTrigger: "",
labelTrigger: "",
directPrompt: "",
overridePrompt: "",
allowedTools: [],
disallowedTools: [],
customInstructions: "",
branchPrefix: "claude/",
useStickyComment: false,
additionalPermissions: new Map(),
useCommitSigning: false,
},
});
expect(checkContainsTrigger(context)).toBe(true);
});
it("should handle empty requested_reviewers and requested_teams arrays", () => {
const context = createMockContext({
eventName: "pull_request",
eventAction: "opened",
isPR: true,
payload: {
action: "opened",
pull_request: {
number: 123,
title: "Test PR",
body: "This PR fixes a bug",
created_at: "2023-01-01T00:00:00Z",
user: { login: "testuser" },
requested_reviewers: [],
requested_teams: [],
},
} as unknown as PullRequestEvent,
inputs: {
mode: "tag",
triggerPhrase: "@claude",
assigneeTrigger: "",
labelTrigger: "",
directPrompt: "",
overridePrompt: "",
allowedTools: [],
disallowedTools: [],
customInstructions: "",
branchPrefix: "claude/",
useStickyComment: false,
additionalPermissions: new Map(),
useCommitSigning: false,
},
});
expect(checkContainsTrigger(context)).toBe(false);
});
it("should handle missing requested_reviewers and requested_teams fields", () => {
const context = createMockContext({
eventName: "pull_request",
eventAction: "opened",
isPR: true,
payload: {
action: "opened",
pull_request: {
number: 123,
title: "Test PR",
body: "This PR fixes a bug",
created_at: "2023-01-01T00:00:00Z",
user: { login: "testuser" },
// requested_reviewers and requested_teams are undefined
},
} as unknown as PullRequestEvent,
inputs: {
mode: "tag",
triggerPhrase: "@claude",
assigneeTrigger: "",
labelTrigger: "",
directPrompt: "",
overridePrompt: "",
allowedTools: [],
disallowedTools: [],
customInstructions: "",
branchPrefix: "claude/",
useStickyComment: false,
additionalPermissions: new Map(),
useCommitSigning: false,
},
});
expect(checkContainsTrigger(context)).toBe(false);
});
});
describe("comment trigger", () => {
it("should return true for issue_comment with trigger phrase", () => {
const context = mockIssueCommentContext;
@@ -475,6 +812,119 @@ describe("checkContainsTrigger", () => {
});
});
describe("pull request review_requested action", () => {
it("should return true when trigger user is requested as reviewer", () => {
const context = createMockContext({
eventName: "pull_request",
eventAction: "review_requested",
isPR: true,
payload: {
action: "review_requested",
pull_request: {
number: 123,
title: "Test PR",
body: "This PR fixes a bug",
created_at: "2023-01-01T00:00:00Z",
user: { login: "testuser" },
requested_reviewers: [{ login: "claude", id: 1, type: "User" }],
requested_teams: [],
},
requested_reviewer: { login: "claude", id: 1, type: "User" },
} as unknown as PullRequestEvent,
inputs: {
mode: "tag",
triggerPhrase: "@claude",
assigneeTrigger: "",
labelTrigger: "",
directPrompt: "",
overridePrompt: "",
allowedTools: [],
disallowedTools: [],
customInstructions: "",
branchPrefix: "claude/",
useStickyComment: false,
additionalPermissions: new Map(),
useCommitSigning: false,
},
});
expect(checkContainsTrigger(context)).toBe(true);
});
it("should return false when different user is requested as reviewer", () => {
const context = createMockContext({
eventName: "pull_request",
eventAction: "review_requested",
isPR: true,
payload: {
action: "review_requested",
pull_request: {
number: 123,
title: "Test PR",
body: "This PR fixes a bug",
created_at: "2023-01-01T00:00:00Z",
user: { login: "testuser" },
requested_reviewers: [{ login: "john", id: 2, type: "User" }],
requested_teams: [],
},
requested_reviewer: { login: "john", id: 2, type: "User" },
} as unknown as PullRequestEvent,
inputs: {
mode: "tag",
triggerPhrase: "@claude",
assigneeTrigger: "",
labelTrigger: "",
directPrompt: "",
overridePrompt: "",
allowedTools: [],
disallowedTools: [],
customInstructions: "",
branchPrefix: "claude/",
useStickyComment: false,
additionalPermissions: new Map(),
useCommitSigning: false,
},
});
expect(checkContainsTrigger(context)).toBe(false);
});
it("should handle trigger phrase without @ symbol", () => {
const context = createMockContext({
eventName: "pull_request",
eventAction: "review_requested",
isPR: true,
payload: {
action: "review_requested",
pull_request: {
number: 123,
title: "Test PR",
body: "This PR fixes a bug",
created_at: "2023-01-01T00:00:00Z",
user: { login: "testuser" },
requested_reviewers: [{ login: "claude", id: 1, type: "User" }],
requested_teams: [],
},
requested_reviewer: { login: "claude", id: 1, type: "User" },
} as unknown as PullRequestEvent,
inputs: {
mode: "tag",
triggerPhrase: "claude", // no @ symbol
assigneeTrigger: "",
labelTrigger: "",
directPrompt: "",
overridePrompt: "",
allowedTools: [],
disallowedTools: [],
customInstructions: "",
branchPrefix: "claude/",
useStickyComment: false,
additionalPermissions: new Map(),
useCommitSigning: false,
},
});
expect(checkContainsTrigger(context)).toBe(true);
});
});
describe("non-matching events", () => {
it("should return false for non-matching event type", () => {
const context = createMockContext({
@@ -485,7 +935,6 @@ describe("checkContainsTrigger", () => {
expect(checkContainsTrigger(context)).toBe(false);
});
});
});
describe("escapeRegExp", () => {
it("should escape special regex characters", () => {