Move disableForTesting to NavigationGuardProvider; add mockConfirm#60
Open
ypresto wants to merge 4 commits into
Open
Move disableForTesting to NavigationGuardProvider; add mockConfirm#60ypresto wants to merge 4 commits into
ypresto wants to merge 4 commits into
Conversation
Refactor: disableForTesting becomes a boolean prop on the provider; when set, the library installs none of its host-environment hooks (popstate, beforeunload, capture-phase click, history augmentation, App/Pages Router context overrides). useNavigationGuard keeps registering as usual, so enabled / confirm / active / accept / reject continue to work for component-level tests and storybook. Hook-side disableForTesting option is removed. Extract evaluateGuards util shared by router and popstate intercepts. Release prep: bump next devDep to ^14.2.35, redate 0.3.0 to 2026-04-28, add Fixed entries for #48 (null history.state) and #38 (import types), record v16.2 CI addition. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
disableForTesting now accepts boolean | { mockConfirm }. The router
context overrides stay on in both forms so navigation through Next.js
routers (incl. mock routers in tests) keeps evaluating guards. When
mockConfirm is provided, every registered guard's confirm is replaced
during evaluation; per-guard enabled predicates still run, so tests can
assert on navigation attempts without rendering the confirmation UI.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Match the wording the original useInterceptedAppRouter loop emitted so
DEBUG output stays byte-identical for that interceptor:
- Calling guard callback for ${type} to ${to}
- Guard callback returned: ${confirm}
- All guards passed, proceeding with navigation
Pages Router intercept now emits these (was silent before) and popstate
loses its per-guard "listener index N" line — both intentional drift
from centralizing the loop.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Popstate's old per-guard log included the listener index; centralizing the loop dropped it. Append "(listener index N)" to the per-guard log across all interceptors so popstate keeps that hint and App Router / Pages Router pick it up too. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Reshapes
disableForTesting(introduced but never released as 0.3.0) from a per-hookbooleanoption into aNavigationGuardProviderprop with a richer contract.disableForTestingis nowboolean | { mockConfirm }:true— library skips its host-environment hooks (nopopstate/beforeunload/ capture-phaseclicklisteners, nowindow.historyaugmentation, no Next.js 15.3+ link-click interceptor). The App Router / Pages Router context overrides remain in place, so navigation through Next.js routers (incl. mock routers in tests) still evaluates registered guards with the user's realconfirm.{ mockConfirm }— same as above, plus replaces every registered guard'sconfirmduring evaluation. Per-guardenabledpredicates still run. Useful for asserting on navigation attempts in tests without rendering the confirmation UI.The hook-side
disableForTestingoption (committed as part of the unshipped 0.3.0 ine65773a) is removed;useNavigationGuardonce again throws if there is no provider.Also extracts a shared
evaluateGuardsutil used byuseInterceptedAppRouter,useInterceptedPagesRouter, anduseInterceptPopState.Release prep folded in
Since 0.3.0 was bumped in
package.json/ CHANGELOG but never tagged or published to npm, this PR also tidies up the 0.3.0 release notes:nextdevDependency to^14.2.35(latest 14.2.x patch)[0.3.0]to todayhistory.stateincreateHandlePopState) and feat: added exports.types declaration to fix typescript module resolution error #38 (import types) which landed since v0.2.0 but were not in the changelogf24ecd2)Test plan
pnpm run build(tsc) — cleanpnpm run check:packaging— all four resolution modes 🟢pnpm e2eagainst the matrix — please run in CI (this branch does not yet add automated tests for themockConfirmshape; manual sanity check recommended in App Router and Pages Router examples)disableForTesting(boolean) renders without touchingwindow.historydisableForTesting={{ mockConfirm }}causes navigation through a mocked Next.js router to callmockConfirmwith the rightparams🤖 Generated with Claude Code