From bbe7ec3c99205fc4bb575c506108544f11c3c648 Mon Sep 17 00:00:00 2001 From: quality Date: Thu, 8 Oct 2026 16:46:12 -0400 Subject: [PATCH 1/2] test(bundle): drive meow.ts:28 (strict /meow re-check after the dispatcher's generic match) through dist/index.js handleIssueComment admits /meow with the generic, case-insensitive, argument-tolerant matcher; meow() then re-checks the line against its own strict pattern and returns at meow.ts:28 when only the first gate matched. The arm was reached only by the unit suite. The new file runs /meow cat, /MEOW and a multi-line /meow please through the bundle and asserts exit 0 with no GitHub and no cat api calls. Closes #396 Signed-off-by: quality --- __tests__/bundle/meowCommandShape.test.ts | 54 +++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 __tests__/bundle/meowCommandShape.test.ts diff --git a/__tests__/bundle/meowCommandShape.test.ts b/__tests__/bundle/meowCommandShape.test.ts new file mode 100644 index 00000000..2afed10c --- /dev/null +++ b/__tests__/bundle/meowCommandShape.test.ts @@ -0,0 +1,54 @@ +import type { FakeGithub } from './fakeGithub' +import path from 'node:path' +import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from 'vitest' + +import { start } from './fakeGithub' +import { comment, helpersFor, token } from './helpers' +import { runBundle } from './runBundle' + +vi.setConfig({ testTimeout: 30_000 }) + +// without CAT_API_URL the preload makes any cat api call throw, so a meow that got past the +// strict command check would post the unavailable note to the fake github and show up in calls() +const preload = path.resolve(__dirname, 'catApiPreload.cjs') + +// handleIssueComment admits /meow with the generic matcher (case-insensitive, arguments allowed); +// meow.ts then re-checks the line against its own stricter pattern (meow.ts:12) and returns at +// meow.ts:28 when only the generic one matched. These bodies pass the first gate and fail the second. +describe('dist/index.js issue_comment /meow strict command shape', () => { + let gh: FakeGithub + const { calls } = helpersFor(() => gh) + + beforeAll(async () => { + gh = await start() + }) + afterEach(() => { + gh.reset() + }) + afterAll(async () => { + await gh.close() + }) + + function meow(body: string) { + return runBundle({ + eventName: 'issue_comment', + payload: comment(body), + inputs: { ...token, 'prow-commands': '/meow' }, + apiUrl: gh.url, + env: { NODE_OPTIONS: `--require "${preload}"` }, + }) + } + + it.each([ + ['/meow with an argument', '/meow cat'], + ['/meow in upper case', '/MEOW'], + ['/meow with an argument among other lines', 'nice work\n/meow please\nthanks'], + ])('%s reaches the handler but posts nothing and succeeds', async (_name, body) => { + const result = await meow(body) + + expect(result.status, result.stdout).toBe(0) + expect(result.errors).toEqual([]) + expect(result.stdout).not.toMatch(/::warning::/) + expect(calls()).toEqual([]) + }) +}) From 9beaa55889c43b61fd8ab4edf56b63cf794121a3 Mon Sep 17 00:00:00 2001 From: quality Date: Thu, 8 Oct 2026 23:01:56 -0400 Subject: [PATCH 2/2] test(bundle): keep only the /meow cat shape case Signed-off-by: quality --- __tests__/bundle/meowCommandShape.test.ts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/__tests__/bundle/meowCommandShape.test.ts b/__tests__/bundle/meowCommandShape.test.ts index 2afed10c..212a67cc 100644 --- a/__tests__/bundle/meowCommandShape.test.ts +++ b/__tests__/bundle/meowCommandShape.test.ts @@ -14,7 +14,7 @@ const preload = path.resolve(__dirname, 'catApiPreload.cjs') // handleIssueComment admits /meow with the generic matcher (case-insensitive, arguments allowed); // meow.ts then re-checks the line against its own stricter pattern (meow.ts:12) and returns at -// meow.ts:28 when only the generic one matched. These bodies pass the first gate and fail the second. +// meow.ts:28 when only the generic one matched. This body passes the first gate and fails the second. describe('dist/index.js issue_comment /meow strict command shape', () => { let gh: FakeGithub const { calls } = helpersFor(() => gh) @@ -39,12 +39,8 @@ describe('dist/index.js issue_comment /meow strict command shape', () => { }) } - it.each([ - ['/meow with an argument', '/meow cat'], - ['/meow in upper case', '/MEOW'], - ['/meow with an argument among other lines', 'nice work\n/meow please\nthanks'], - ])('%s reaches the handler but posts nothing and succeeds', async (_name, body) => { - const result = await meow(body) + it('/meow with an argument reaches the handler but posts nothing and succeeds', async () => { + const result = await meow('/meow cat') expect(result.status, result.stdout).toBe(0) expect(result.errors).toEqual([])