Fix Forgejo CI terminal test mock alias
The remaining Forgejo-only failure was a Next.js module-shape mismatch in the terminal test. I taught the test harness to mock both the bare next/navigation specifier and the resolved next/navigation.js path so Forgejo can import the same named exports the local suite already accepts.
New Changes as of 2026-05-30 01:53 EDT
This update builds on the earlier Bun PATH and redirect-mock fixes. Forgejo was still resolving the Next.js navigation module through the explicit .js path, so the test harness now mocks both the specifier and the resolved path before the terminal module loads.
Summary of changes
- Wrapped the Next.js navigation stubs in a shared mock object in
apps/web/app/terminal.test.ts. - Added explicit mocks for both
import.meta.resolve("next/navigation")andimport.meta.resolve("next/navigation.js"). - Kept the
redirectshim andusePathnamestub identical across every module entry point Forgejo might choose.
Why this change was made
The previous mock covered the string specifier, but Forgejo's Bun runtime still resolved the explicit .js entry point in the test job. Without the resolved-path aliases, Bun reported a missing named export and aborted the file before the assertions could run.
Code diff
const nextNavigationMock = {
default: {
redirect,
usePathname: () => "/options"
},
redirect,
usePathname: () => "/options"
};
const nextNavigationResolved = import.meta.resolve("next/navigation");
const nextNavigationJsResolved = import.meta.resolve("next/navigation.js");
mock.module(nextNavigationResolved, () => ({
...nextNavigationMock
}));
mock.module(nextNavigationJsResolved, () => ({
...nextNavigationMock
}));
Related issues or PRs
islandflow-3l6
Summary
The remaining Forgejo failure was inside the web test suite, not the install or typecheck stages. The terminal test needed to mock the Next.js navigation module under both import paths, so the final change keeps the CI runner from tripping over a named export mismatch.
Changes Made
- Updated
apps/web/app/terminal.test.tsto mocknext/navigation.jsin addition tonext/navigation. - Kept the redirect shim and pathname stub aligned between both module shapes.
- Left the earlier Bun PATH and redirect-mock fixes intact, since they were already solving the other CI failure modes.
Context
The repository already had the Bun executable path fix and the routes mock alias fix in place. The last failure surfaced only in the full CI-shaped test run, where Bun resolved the terminal module through next/navigation.js rather than the shorter specifier used in the local test path.
Important Implementation Details
- The alias returns the same mock object for both module entry points, so the terminal module sees a consistent redirect helper and pathname stub regardless of the import path Bun chooses.
- This stays narrowly scoped to the test file and does not change production routing code.
- The fix addresses the exact CI import shape instead of widening the test harness in a way that could hide future regressions.
Relevant Diff Snippets
Rendered with @pierre/diffs/ssr from the current working tree. It shows the shared Next.js navigation mock plus the explicit resolved-path aliases that keep Forgejo aligned with the local Bun runtime.
4 unmodified lines567891011121314151617181920214 unmodified linesthrow new Error(`NEXT_REDIRECT:${path}`);});mock.module("next/navigation", () => ({redirect,usePathname: () => "/options"}));mock.module("next/navigation.js", () => ({default: {redirect,usePathname: () => "/options"},redirect,usePathname: () => "/options"}));const {4 unmodified lines567891011121314151617181920212223242526272829303132334 unmodified linesthrow new Error(`NEXT_REDIRECT:${path}`);});const nextNavigationMock = {default: {redirect,usePathname: () => "/options"},redirect,usePathname: () => "/options"};const nextNavigationResolved = import.meta.resolve("next/navigation");const nextNavigationJsResolved = import.meta.resolve("next/navigation.js");mock.module("next/navigation", () => ({...nextNavigationMock}));mock.module("next/navigation.js", () => ({...nextNavigationMock}));mock.module(nextNavigationResolved, () => ({...nextNavigationMock}));mock.module(nextNavigationJsResolved, () => ({...nextNavigationMock}));const {
Expected Impact for End-Users
Forgejo should stop failing on the terminal test's CI-only module resolution mismatch, which reduces false negative pipeline runs and makes it easier to trust the branch when the suite passes.
Validation
env PATH="$HOME/.bun/bin:/usr/bin:/bin" bun test apps/web/app/terminal.test.tspassed: 74 tests, 0 failures.env PATH="$HOME/.bun/bin:/usr/bin:/bin" bun testpassed: 250 tests, 0 failures.
Issues, Limitations, and Mitigations
This fix is intentionally narrow. If another CI-only Next.js import path shows up later, the same pattern should be applied to the affected test file instead of broadening the mock surface globally. That keeps the failure signal honest and the test harness easy to reason about.
Follow-up Work
- Watch the next Forgejo run on this branch to confirm the updated terminal alias clears the last failure.
- If another module-shape mismatch appears, fold the shared mock setup into a tiny helper rather than repeating the alias logic by hand.