fix(payment): #159 route payment navigations through the base path#177
Merged
Conversation
Raw `window.location.href` and raw `<a href>` do NOT get the basePath prepended (only next/link and the next/navigation router do). On a GitHub Pages project-site fork (basePath=/RepoName) these escape the app to the domain root mid-payment. Fix all five same-class sites (the two named in #159 plus three raw anchors found alongside them), mirroring the #154 pattern. Hard navigations -> getInternalUrl (query URL, no trailing slash added): - src/app/payment-result/page.tsx:257 (onRetrySuccess) - PaymentStatusDisplay.tsx:436 (SwitchProviderPanel onSwitchSuccess) Raw <a href> -> next/link <Link> (auto-prefixes at runtime): - PaymentStatusDisplay.tsx: two /contact support links - PaymentConsentModal.tsx: the /privacy policy link Tests (mirror the #154 use-auth vitest pattern): - PaymentStatusDisplay.test.tsx: the SwitchProviderPanel stub now exposes a button to fire onSwitchSuccess, so the parent's navigation is exercised. Asserts the prefixed href with NEXT_PUBLIC_BASE_PATH=/ScriptHammer and the unprefixed href without it, plus that the support control is a next/link. - PaymentConsentModal.test.tsx: asserts the privacy link is a next/link anchor. Note on coverage: getInternalUrl reads process.env at runtime so the two window.location tests pin the prefix directly; next/link reads the runtime __NEXT_ROUTER_BASEPATH which jsdom doesn't populate, so the Link prefix is pinned end-to-end by the basePath E2E project (#157). page.tsx site 1 uses the byte-identical expression to the pinned site 2 (mounting the whole auth+payment tree to re-assert one shared line adds fragility, not coverage). Closes #159 Co-Authored-By: Claude Opus 4.8 (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.
What
Fixes the basePath-escape bug class in payment navigation (#159). Routes all five same-class sites through the basePath-aware helpers introduced in #154 — the two
window.location.hrefsites the issue named, plus three raw<a href>anchors found alongside them.Why
Raw
window.location.hrefand raw<a href>do not get the basePath prepended — onlynext/linkand thenext/navigationrouter do. On a GitHub Pages project-site fork (basePath=/RepoName), these escape the app to the domain root mid-payment. The template itself is immune (custom domain, basePath''), but a fork silently breaks. Same defect class as #154.Changes
Hard navigations →
getInternalUrl(query URL — no trailing slash added):src/app/payment-result/page.tsx:257(onRetrySuccess)PaymentStatusDisplay.tsx:436(SwitchProviderPanelonSwitchSuccess)Raw
<a href>→next/link<Link>(auto-prefixes at runtime):PaymentStatusDisplay.tsx— two/contactsupport linksPaymentConsentModal.tsx— the/privacypolicy linkTests (mirror the #154 use-auth vitest pattern):
PaymentStatusDisplay.test.tsx— theSwitchProviderPanelstub now exposes a button to fireonSwitchSuccess, so the parent's navigation is actually exercised. Asserts the prefixed href underNEXT_PUBLIC_BASE_PATH=/ScriptHammerand the unprefixed href without it, plus that the support control renders as anext/link.PaymentConsentModal.test.tsx— asserts the privacy link is anext/linkanchor.Coverage note (honest scoping)
getInternalUrlreadsprocess.envat runtime, so the twowindow.locationtests pin the prefix directly.next/link, however, reads the runtime__NEXT_ROUTER_BASEPATHwhich jsdom doesn't populate — so the<Link>prefix is pinned end-to-end by the basePath E2E project (#157), not the unit layer.page.tsxsite 1 uses the byte-identical expression to the pinned site 2; mounting the whole auth+payment tree to re-assert one shared line would add fragility, not coverage.Verification
PaymentStatusDisplay.test.tsx+PaymentConsentModal.test.tsx→ 47 pass (incl. the pre-existing "contact support" link assertion, still green after the<Link>conversion).pnpm type-checkclean. eslint on all 5 files clean.Closes #159
🤖 Generated with Claude Code