# PRD #6: E2E Test All Untested Forgejo Trigger Scenarios **Issue**: [#6](https://git.wxs.ro/actions/claude-code-action/issues/6) **Priority**: High **Created**: 2026-02-25 --- ## Problem The Forgejo platform support (PRD #1) was validated for the two most common scenarios (agent mode via `workflow_dispatch` and tag mode via `issue_comment`). However, 5 trigger scenarios remain untested in a live environment: 1. PR review comment triggers (`pull_request_review_comment`) 2. PR review triggers (`pull_request_review`) 3. Label triggers (`issues` with `labeled` action) 4. Assignee triggers (`issues` with `assigned` action) 5. Branch creation + code changes from tag mode (the initial test only asked a question, no code was generated) These untested paths could have silent failures — the code may look correct but break on Forgejo's subtly different webhook payloads, API responses, or event structures. ## Solution Systematically exercise each untested scenario on the live Forgejo instance (git.wxs.ro), document results, fix any issues discovered, and update the E2E status table in `docs/forgejo.md`. ## Milestones - [x] **M1: Ensure workflow covers all trigger types** - Review `.forgejo/workflows/claude.yml` to confirm all 5 trigger types are listed - Add any missing triggers to the workflow file - Ensure the workflow has the correct permissions for each trigger type - **Validation**: Workflow YAML includes all required `on:` triggers - [ ] **M1.5: Fix image-downloader test failures blocking CI** _(pending CI verification)_ - **Problem**: All 18 `downloadCommentImages` tests failed on Forgejo CI (Linux Bun 1.2.21 in `harbor.wxs.ro/wxs/grunt-runner:v1.9.0`) while passing locally on macOS. This blocked all PRs. - **Root cause**: `mock.module("../src/github/utils/image-downloader")` in `test/forgejo-data-fetcher.test.ts` replaced the image-downloader module **globally** in Bun's module registry for the entire process. When Bun's non-deterministic test file ordering ran forgejo-data-fetcher.test.ts BEFORE image-downloader.test.ts, the latter imported the stubbed module instead of the real one, breaking all mock tracking. The failure was intermittent because file ordering changed when other files were added/removed. - **Fix (2 parts)**: 1. `c6ca8a7`: Added DI (`FsDeps` interface + optional `fsDeps` param) to `downloadCommentImages()` — removed `mock.module("fs/promises")` from the image-downloader test itself 2. `7c4191a`: Replaced `mock.module("image-downloader")` in forgejo-data-fetcher.test.ts with `spyOn(module, "fn")` — spyOn patches the live export per-test and is auto-restored, no cross-file pollution - **Key learning**: Never use `mock.module()` in Bun test files — it poisons the module registry for all files in the process. Always use `spyOn` on the module namespace import instead. - **Validation**: 797 tests pass locally, typecheck clean, critical file ordering (forgejo first → image-downloader second) verified passing - [ ] **M2: Test PR review comment trigger** - Create a test PR on the repo - Post a review comment with `@claude` mention - Verify: platform detection, context fetching (PR diff, review comment body), tracking comment, Claude response - Document any issues and fix them - **Validation**: Claude responds correctly to `@claude` in a PR review comment - [ ] **M3: Test PR review trigger** - Create a test PR on the repo - Submit a review with `@claude` mention in the review body - Verify: platform detection, context fetching, tracking comment, Claude response - Document any issues and fix them - **Validation**: Claude responds correctly to `@claude` in a PR review - [ ] **M4: Test label trigger** - Create a label (e.g., `claude`) that triggers the action when applied to an issue - Apply the label to a test issue - Verify: trigger detection, context fetching (issue body/title), Claude response - Document any issues and fix them - **Validation**: Claude responds when the configured label is applied to an issue - [ ] **M5: Test assignee trigger** - Assign a user to an issue to trigger the action - Verify: trigger detection, context fetching, Claude response - Document any issues and fix them - **Validation**: Claude responds when assigned to an issue - [ ] **M6: Test tag mode with code changes (branch creation)** - Create an issue requesting a code change (e.g., "add a comment to file X") - Trigger Claude via `@claude` mention - Verify: Claude creates a branch, pushes commits, links the branch in tracking comment - Verify the Forgejo-specific PR compare URL format is correct - **Validation**: Claude successfully creates a branch with code changes on Forgejo - [ ] **M7: Update documentation with E2E results** - Update `docs/forgejo.md` E2E status table with results for all 5 scenarios - Move tested items from "Not Yet E2E Tested" to the validated table - Document any Forgejo-specific quirks or limitations discovered - Add troubleshooting entries for any issues encountered - **Validation**: `docs/forgejo.md` accurately reflects the current E2E validation status ## Dependencies - PRD #5 (Dedicated Forgejo User) is recommended but not strictly required — tests can run with the current token setup - A test repository on git.wxs.ro with the action workflow configured ## Risks | Risk | Mitigation | | -------------------------------------------------------- | ----------------------------------------------------------- | | Forgejo webhook payloads differ from expected | Log raw payloads, compare with GitHub format, adapt parsing | | Trigger type not supported by Forgejo Actions | Document as known limitation, skip gracefully | | Action creates unwanted branches/comments during testing | Use a dedicated test repo or clean up after each test | | Bun mock.module breaks mock tracking on Linux | RESOLVED: use spyOn on module namespace, never mock.module | ## Success Criteria - All 5 previously untested scenarios have been exercised on a live Forgejo instance - Any bugs discovered are fixed and tested - `docs/forgejo.md` E2E status table is fully up-to-date - "Not Yet E2E Tested" section is empty (all items moved to validated or documented as unsupported)