Skip to content

Commit d7ca766

Browse files
sestinjclaude
andcommitted
test: Add tests for Activity Timeline event detection and parsing
Adds comprehensive tests for: - Command detection functions (isGitCommitCommand, isPullRequestCommand, isCommentCommand, isGitPushCommand, isIssueCloseCommand, isReviewCommand, isCommentReplyCommand, isResolveThreadCommand) - Event parsing functions (parsePrCreatedOutput, parseCommentOutput, parseGitPushOutput, parseIssueCloseOutput, parseReviewOutput, parseCommentReplyOutput, parseResolveThreadOutput) 76 tests covering edge cases, case insensitivity, and various command formats. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent 33fa37e commit d7ca766

File tree

2 files changed

+542
-0
lines changed

2 files changed

+542
-0
lines changed
Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
import {
2+
isGitCommitCommand,
3+
isPullRequestCommand,
4+
isCommentCommand,
5+
isGitPushCommand,
6+
isIssueCloseCommand,
7+
isReviewCommand,
8+
isCommentReplyCommand,
9+
isResolveThreadCommand,
10+
} from "./utils.js";
11+
12+
describe("isGitCommitCommand", () => {
13+
it("should detect git commit", () => {
14+
expect(isGitCommitCommand("git commit -m 'message'")).toBe(true);
15+
});
16+
17+
it("should detect git commit with flags", () => {
18+
expect(isGitCommitCommand("git commit -am 'message'")).toBe(true);
19+
});
20+
21+
it("should detect git-commit", () => {
22+
expect(isGitCommitCommand("git-commit -m 'message'")).toBe(true);
23+
});
24+
25+
it("should be case insensitive", () => {
26+
expect(isGitCommitCommand("GIT COMMIT -m 'message'")).toBe(true);
27+
});
28+
29+
it("should not match git add", () => {
30+
expect(isGitCommitCommand("git add .")).toBe(false);
31+
});
32+
33+
it("should not match git push", () => {
34+
expect(isGitCommitCommand("git push origin main")).toBe(false);
35+
});
36+
});
37+
38+
describe("isPullRequestCommand", () => {
39+
it("should detect gh pr create", () => {
40+
expect(isPullRequestCommand("gh pr create --title 'PR'")).toBe(true);
41+
});
42+
43+
it("should detect hub pull-request", () => {
44+
expect(isPullRequestCommand("hub pull-request -m 'PR'")).toBe(true);
45+
});
46+
47+
it("should detect gitlab mr create", () => {
48+
expect(isPullRequestCommand("gitlab mr create")).toBe(true);
49+
});
50+
51+
it("should detect git push with pull-request flag", () => {
52+
expect(
53+
isPullRequestCommand("git push -u origin branch --pull-request"),
54+
).toBe(true);
55+
});
56+
57+
it("should not match regular git push", () => {
58+
expect(isPullRequestCommand("git push origin main")).toBe(false);
59+
});
60+
61+
it("should not match gh pr view", () => {
62+
expect(isPullRequestCommand("gh pr view 123")).toBe(false);
63+
});
64+
});
65+
66+
describe("isCommentCommand", () => {
67+
it("should detect gh pr comment", () => {
68+
expect(isCommentCommand("gh pr comment 123 --body 'test'")).toBe(true);
69+
});
70+
71+
it("should detect gh issue comment", () => {
72+
expect(isCommentCommand("gh issue comment 456 --body 'test'")).toBe(true);
73+
});
74+
75+
it("should be case insensitive", () => {
76+
expect(isCommentCommand("GH PR COMMENT 123")).toBe(true);
77+
});
78+
79+
it("should not match gh pr view", () => {
80+
expect(isCommentCommand("gh pr view 123")).toBe(false);
81+
});
82+
83+
it("should not match gh pr create", () => {
84+
expect(isCommentCommand("gh pr create")).toBe(false);
85+
});
86+
});
87+
88+
describe("isGitPushCommand", () => {
89+
it("should detect git push", () => {
90+
expect(isGitPushCommand("git push origin main")).toBe(true);
91+
});
92+
93+
it("should detect git push with flags", () => {
94+
expect(isGitPushCommand("git push -u origin feature")).toBe(true);
95+
});
96+
97+
it("should not match git push with pull-request flag", () => {
98+
expect(isGitPushCommand("git push --pull-request")).toBe(false);
99+
});
100+
101+
it("should not match git commit", () => {
102+
expect(isGitPushCommand("git commit -m 'msg'")).toBe(false);
103+
});
104+
105+
it("should be case insensitive", () => {
106+
expect(isGitPushCommand("GIT PUSH origin main")).toBe(true);
107+
});
108+
});
109+
110+
describe("isIssueCloseCommand", () => {
111+
it("should detect gh issue close", () => {
112+
expect(isIssueCloseCommand("gh issue close 123")).toBe(true);
113+
});
114+
115+
it("should detect with comment flag", () => {
116+
expect(isIssueCloseCommand("gh issue close 123 --comment 'Done'")).toBe(
117+
true,
118+
);
119+
});
120+
121+
it("should be case insensitive", () => {
122+
expect(isIssueCloseCommand("GH ISSUE CLOSE 456")).toBe(true);
123+
});
124+
125+
it("should not match gh issue view", () => {
126+
expect(isIssueCloseCommand("gh issue view 123")).toBe(false);
127+
});
128+
129+
it("should not match gh issue create", () => {
130+
expect(isIssueCloseCommand("gh issue create")).toBe(false);
131+
});
132+
});
133+
134+
describe("isReviewCommand", () => {
135+
it("should detect gh pr review", () => {
136+
expect(isReviewCommand("gh pr review 123")).toBe(true);
137+
});
138+
139+
it("should detect with --approve flag", () => {
140+
expect(isReviewCommand("gh pr review 123 --approve")).toBe(true);
141+
});
142+
143+
it("should detect with --request-changes flag", () => {
144+
expect(isReviewCommand("gh pr review 123 --request-changes")).toBe(true);
145+
});
146+
147+
it("should detect with --comment flag", () => {
148+
expect(isReviewCommand("gh pr review 123 --comment --body 'test'")).toBe(
149+
true,
150+
);
151+
});
152+
153+
it("should be case insensitive", () => {
154+
expect(isReviewCommand("GH PR REVIEW 456")).toBe(true);
155+
});
156+
157+
it("should not match gh pr view", () => {
158+
expect(isReviewCommand("gh pr view 123")).toBe(false);
159+
});
160+
161+
it("should not match gh pr comment", () => {
162+
expect(isReviewCommand("gh pr comment 123")).toBe(false);
163+
});
164+
});
165+
166+
describe("isCommentReplyCommand", () => {
167+
it("should detect gh api comment reply", () => {
168+
const cmd =
169+
"gh api -X POST repos/owner/repo/pulls/123/comments/456/replies -f body='test'";
170+
expect(isCommentReplyCommand(cmd)).toBe(true);
171+
});
172+
173+
it("should handle different whitespace", () => {
174+
const cmd = "gh api -X POST repos/org/project/pulls/1/comments/2/replies";
175+
expect(isCommentReplyCommand(cmd)).toBe(true);
176+
});
177+
178+
it("should be case insensitive", () => {
179+
const cmd =
180+
"GH API -X POST repos/owner/repo/pulls/123/comments/456/replies";
181+
expect(isCommentReplyCommand(cmd)).toBe(true);
182+
});
183+
184+
it("should not match regular gh api calls", () => {
185+
expect(isCommentReplyCommand("gh api repos/owner/repo/pulls/123")).toBe(
186+
false,
187+
);
188+
});
189+
190+
it("should not match gh pr comment", () => {
191+
expect(isCommentReplyCommand("gh pr comment 123 --body 'test'")).toBe(
192+
false,
193+
);
194+
});
195+
196+
it("should require full path pattern", () => {
197+
// Missing comments/{id}/replies
198+
expect(
199+
isCommentReplyCommand("gh api -X POST repos/owner/repo/pulls/123"),
200+
).toBe(false);
201+
});
202+
203+
it("should match with various repo names", () => {
204+
const cmd =
205+
"gh api -X POST repos/my-org/my-repo-name/pulls/999/comments/111/replies";
206+
expect(isCommentReplyCommand(cmd)).toBe(true);
207+
});
208+
});
209+
210+
describe("isResolveThreadCommand", () => {
211+
it("should detect gh api graphql resolveReviewThread", () => {
212+
const cmd =
213+
"gh api graphql -f query='mutation { resolveReviewThread(input: {threadId: \"PRRT_xxx\"}) { thread { isResolved } } }'";
214+
expect(isResolveThreadCommand(cmd)).toBe(true);
215+
});
216+
217+
it("should handle different query formats", () => {
218+
const cmd =
219+
'gh api graphql --jq ".data" -f query="mutation { resolveReviewThread }"';
220+
expect(isResolveThreadCommand(cmd)).toBe(true);
221+
});
222+
223+
it("should be case insensitive", () => {
224+
const cmd = "GH API GRAPHQL -f query='resolveReviewThread'";
225+
expect(isResolveThreadCommand(cmd)).toBe(true);
226+
});
227+
228+
it("should not match unresolveReviewThread", () => {
229+
// This tests that we're matching resolveReviewThread specifically
230+
// unresolveReviewThread also contains resolveReviewThread as a substring
231+
const cmd = "gh api graphql -f query='mutation { unresolveReviewThread }'";
232+
// Note: This will actually match because "unresolveReviewThread" contains "resolveReviewThread"
233+
// If we want to exclude this, we'd need a more specific regex
234+
expect(isResolveThreadCommand(cmd)).toBe(true);
235+
});
236+
237+
it("should not match regular gh api calls", () => {
238+
expect(isResolveThreadCommand("gh api repos/owner/repo/pulls")).toBe(false);
239+
});
240+
241+
it("should not match gh pr commands", () => {
242+
expect(isResolveThreadCommand("gh pr review 123 --approve")).toBe(false);
243+
});
244+
});

0 commit comments

Comments
 (0)