Files
claude-hook/test/events.test.js
T
2026-09-28 16:15:50 +02:00

93 lines
3.6 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');
});