fix: correct membership back flow and add onboarding paywall
Staging Backend Quality Gate / validate (push) Has been cancelled
Staging Backend Quality Gate / publish (push) Has been cancelled

This commit is contained in:
Jesse_Chen
2026-08-10 11:14:31 +08:00
parent 8696eca022
commit a17ff258d8
7 changed files with 222 additions and 19 deletions
+18
View File
@@ -5,6 +5,8 @@ import test from "node:test";
const projectFile = (path: string) => new URL(`../${path}`, import.meta.url);
const readProjectFile = (path: string) => readFileSync(projectFile(path), "utf8");
const globalStyles = readProjectFile("src/app/globals.css");
const homePageSource = readProjectFile("src/app/page.tsx");
const onboardingPaywallSource = readProjectFile("src/components/onboarding-redeem-paywall.tsx");
const pageSource = readProjectFile("src/app/membership/page.tsx");
const ordersPageSource = readProjectFile("src/app/membership/orders/page.tsx");
const tabsSource = readProjectFile("src/components/ui/tabs.tsx");
@@ -216,6 +218,22 @@ test("independent orders page preserves loading, empty, error, refresh and list
assert.match(membershipLib, /paid: "已支付"/);
});
test("orders return replaces its history entry so membership back cannot reopen orders", () => {
assert.match(ordersPageSource, /<Link className="membership-back" href="\/membership" replace/);
});
test("finished starter questions open the redeem paywall only for accounts without access", () => {
assert.match(homePageSource, /!starterHomeVisible/);
assert.match(homePageSource, /account\.credits > 0/);
assert.match(homePageSource, /account\.activeSubscription\?\.status === "active"/);
assert.match(homePageSource, /setOnboardingPaywallOpen\(true\)/);
assert.match(homePageSource, /<OnboardingRedeemPaywall/);
assert.match(onboardingPaywallSource, /入门问题已经准备好/);
assert.match(onboardingPaywallSource, /fetch\("\/api\/redeem"/);
assert.match(onboardingPaywallSource, /兑换并继续/);
assert.match(onboardingPaywallSource, /membershipHref\("onboarding-paywall"\)/);
});
test("payment and plan copy points users to the separate orders page", () => {
assert.match(pageSource, /本页会自动检查支付状态并刷新余额。/);
assert.match(pageSource, /「订单记录」页面/);
+4 -3
View File
@@ -173,9 +173,10 @@ test("removes the user-facing admin entry and routes credit control to membershi
test("composes the chat page with the app sidebar shell", () => {
const page = readProjectFile("src/app/page.tsx");
assert.match(page, /<SidebarProvider escapeBlocked=\{accountMenuOpen \|\| activeAccountDialog !== null\}>/);
assert.match(page, /const modalOpen = activeAccountDialog !== null \|\| onboardingPaywallOpen/);
assert.match(page, /<SidebarProvider escapeBlocked=\{accountMenuOpen \|\| modalOpen\}>/);
assert.match(page, /<main className="chat-app">[\s\S]*<AppSidebar\b/);
assert.match(page, /<SidebarInset className="chat-panel" inert=\{activeAccountDialog !== null\}>/);
assert.match(page, /<SidebarInset className="chat-panel" inert=\{modalOpen\}>/);
assert.match(page, /<SidebarTrigger placement="inset" \/>/);
});
@@ -192,7 +193,7 @@ test("blocks the provider mobile Escape action behind layered account UI", () =>
const page = readProjectFile("src/app/page.tsx");
const sidebar = readProjectFile("src/components/ui/sidebar.tsx");
assert.match(page, /escapeBlocked=\{accountMenuOpen \|\| activeAccountDialog !== null\}/);
assert.match(page, /escapeBlocked=\{accountMenuOpen \|\| modalOpen\}/);
assert.match(sidebar, /event\.key === "Escape" && isMobile && openMobile && !escapeBlocked/);
});