Files
2026-09-28 15:09:16 +00:00

195 lines
7.4 KiB
JavaScript

import { test } from 'node:test';
import assert from 'node:assert/strict';
import { classifyEvent } from '../src/events.js';
const opts = { ownerLogin: 'selimaj-dev', triggerPhrase: '@claude' };
function issueCommentPayload(overrides = {}) {
return {
action: 'created',
comment: { user: { login: 'selimaj-dev' }, body: '@claude please fix this' },
issue: { number: 42, title: 'Bug', body: 'It is broken', pull_request: undefined },
repository: { full_name: 'selimaj-dev/repo', default_branch: 'main' },
...overrides,
};
}
test('triggers on an issue comment from the owner mentioning the phrase', () => {
const { trigger, reason } = classifyEvent('issue_comment', issueCommentPayload(), opts);
assert.equal(reason, null);
assert.deepEqual(trigger, {
repo: 'selimaj-dev/repo',
issueNumber: 42,
issueTitle: 'Bug',
issueBody: 'It is broken',
isPullRequest: false,
defaultBranch: 'main',
requestText: '@claude please fix this',
author: 'selimaj-dev',
});
});
test('marks isPullRequest true when issue.pull_request is present', () => {
const payload = issueCommentPayload({ issue: { number: 7, title: 'PR', body: '', pull_request: { url: 'x' } } });
const { trigger } = classifyEvent('issue_comment', payload, opts);
assert.equal(trigger.isPullRequest, true);
});
test('ignores comments not from the configured owner', () => {
const payload = issueCommentPayload({ comment: { user: { login: 'someone-else' }, body: '@claude do it' } });
const { trigger, reason } = classifyEvent('issue_comment', payload, opts);
assert.equal(trigger, null);
assert.match(reason, /is not the configured owner/);
});
test('ignores comments without the trigger phrase', () => {
const payload = issueCommentPayload({ comment: { user: { login: 'selimaj-dev' }, body: 'just a note' } });
const { trigger, reason } = classifyEvent('issue_comment', payload, opts);
assert.equal(trigger, null);
assert.match(reason, /trigger phrase/);
});
test('ignores non-created issue_comment actions', () => {
const payload = issueCommentPayload({ action: 'deleted' });
const { trigger, reason } = classifyEvent('issue_comment', payload, opts);
assert.equal(trigger, null);
assert.match(reason, /not handled/);
});
test('triggers on a new issue whose body mentions the phrase', () => {
const payload = {
action: 'opened',
issue: { number: 1, title: 'New issue', body: 'please @claude help', user: { login: 'selimaj-dev' } },
repository: { full_name: 'selimaj-dev/repo', default_branch: 'main' },
};
const { trigger } = classifyEvent('issues', payload, opts);
assert.ok(trigger);
assert.equal(trigger.requestText, 'please @claude help');
});
test('ignores unrelated event names', () => {
const { trigger, reason } = classifyEvent('push', {}, opts);
assert.equal(trigger, null);
assert.match(reason, /not handled/);
});
test('ignores null/undefined payload without throwing', () => {
assert.doesNotThrow(() => classifyEvent('issue_comment', null, opts));
assert.doesNotThrow(() => classifyEvent('issue_comment', undefined, opts));
});
test('ignores payload missing repository/issue info', () => {
const payload = issueCommentPayload({ repository: { full_name: undefined } });
const { trigger, reason } = classifyEvent('issue_comment', payload, opts);
assert.equal(trigger, null);
assert.match(reason, /missing repository or issue/);
});
test('defaults default_branch to main when absent', () => {
const payload = issueCommentPayload({ repository: { full_name: 'a/b', default_branch: undefined } });
const { trigger } = classifyEvent('issue_comment', payload, opts);
assert.equal(trigger.defaultBranch, 'main');
});
function pullRequestPayload(overrides = {}) {
return {
action: 'opened',
pull_request: { number: 5, title: 'Add feature', body: 'please @claude review', user: { login: 'selimaj-dev' } },
repository: { full_name: 'selimaj-dev/repo', default_branch: 'main' },
...overrides,
};
}
test('triggers on a new pull request whose body mentions the phrase', () => {
const { trigger, reason } = classifyEvent('pull_request', pullRequestPayload(), opts);
assert.equal(reason, null);
assert.deepEqual(trigger, {
repo: 'selimaj-dev/repo',
issueNumber: 5,
issueTitle: 'Add feature',
issueBody: 'please @claude review',
isPullRequest: true,
defaultBranch: 'main',
requestText: 'please @claude review',
author: 'selimaj-dev',
});
});
test('triggers on an edited pull request body', () => {
const { trigger } = classifyEvent('pull_request', pullRequestPayload({ action: 'edited' }), opts);
assert.ok(trigger);
});
test('ignores pull_request actions other than opened/edited', () => {
const { trigger, reason } = classifyEvent('pull_request', pullRequestPayload({ action: 'closed' }), opts);
assert.equal(trigger, null);
assert.match(reason, /not handled/);
});
test('ignores pull requests not from the configured owner', () => {
const payload = pullRequestPayload({ pull_request: { number: 5, title: 'x', body: '@claude help', user: { login: 'someone-else' } } });
const { trigger, reason } = classifyEvent('pull_request', payload, opts);
assert.equal(trigger, null);
assert.match(reason, /is not the configured owner/);
});
function pullRequestReviewCommentPayload(overrides = {}) {
return {
action: 'created',
comment: { user: { login: 'selimaj-dev' }, body: '@claude fix this line' },
pull_request: { number: 9, title: 'PR title', body: 'pr description' },
repository: { full_name: 'selimaj-dev/repo', default_branch: 'main' },
...overrides,
};
}
test('triggers on a pull request review (inline) comment mentioning the phrase', () => {
const { trigger, reason } = classifyEvent('pull_request_review_comment', pullRequestReviewCommentPayload(), opts);
assert.equal(reason, null);
assert.deepEqual(trigger, {
repo: 'selimaj-dev/repo',
issueNumber: 9,
issueTitle: 'PR title',
issueBody: 'pr description',
isPullRequest: true,
defaultBranch: 'main',
requestText: '@claude fix this line',
author: 'selimaj-dev',
});
});
test('ignores non-created pull_request_review_comment actions', () => {
const { trigger, reason } = classifyEvent(
'pull_request_review_comment',
pullRequestReviewCommentPayload({ action: 'deleted' }),
opts,
);
assert.equal(trigger, null);
assert.match(reason, /not handled/);
});
function pullRequestReviewPayload(overrides = {}) {
return {
action: 'submitted',
review: { user: { login: 'selimaj-dev' }, body: '@claude address these comments' },
pull_request: { number: 11, title: 'PR title', body: 'pr description' },
repository: { full_name: 'selimaj-dev/repo', default_branch: 'main' },
...overrides,
};
}
test('triggers on a submitted pull request review mentioning the phrase', () => {
const { trigger, reason } = classifyEvent('pull_request_review', pullRequestReviewPayload(), opts);
assert.equal(reason, null);
assert.equal(trigger.requestText, '@claude address these comments');
assert.equal(trigger.isPullRequest, true);
assert.equal(trigger.issueNumber, 11);
});
test('ignores pull_request_review without the trigger phrase', () => {
const payload = pullRequestReviewPayload({ review: { user: { login: 'selimaj-dev' }, body: 'looks good' } });
const { trigger, reason } = classifyEvent('pull_request_review', payload, opts);
assert.equal(trigger, null);
assert.match(reason, /trigger phrase/);
});