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