import { describe, expect, it } from "vitest"; import { isAuthenticatedUser, resolveAuthenticatedNavigation, resolveRouteGuardRedirect, } from "../navigation-resolver"; import { ROUTE_BUILDERS, ROUTES } from "../routes"; describe("navigation resolver", () => { it("treats only real login providers as authenticated users", () => { expect(isAuthenticatedUser("notLoggedIn")).toBe(false); expect(isAuthenticatedUser("guest")).toBe(false); expect(isAuthenticatedUser("email")).toBe(true); expect(isAuthenticatedUser("facebook")).toBe(true); }); it("wraps protected navigation with auth redirect for guests", () => { expect( resolveAuthenticatedNavigation({ loginStatus: "guest", targetUrl: "/subscription?type=vip", }), ).toBe(ROUTE_BUILDERS.authWithRedirect("/subscription?type=vip")); }); it("keeps protected navigation targets for authenticated users", () => { expect( resolveAuthenticatedNavigation({ loginStatus: "google", targetUrl: "/subscription?type=topup", }), ).toBe("/subscription?type=topup"); }); it("preserves payment analytics context through auth redirects", () => { const subscriptionUrl = ROUTE_BUILDERS.subscription("topup", { payChannel: "stripe", returnTo: "chat", analytics: { entryPoint: "chat_unlock", triggerReason: "ad_landing", }, }); expect(subscriptionUrl).toBe( "/subscription?type=topup&payChannel=stripe&returnTo=chat&analytics_entry=chat_unlock&analytics_reason=ad_landing", ); expect( resolveAuthenticatedNavigation({ loginStatus: "guest", targetUrl: subscriptionUrl, }), ).toBe(ROUTE_BUILDERS.authWithRedirect(subscriptionUrl)); }); it("builds private zone subscription return urls", () => { expect( ROUTE_BUILDERS.subscription("topup", { payChannel: "stripe", returnTo: "private-zone", sourceCharacterSlug: "maya", }), ).toBe( "/subscription?type=topup&payChannel=stripe&returnTo=private-zone&character=maya", ); }); it("keeps the user-bound offer and server-selected plan in the subscription URL", () => { expect( ROUTE_BUILDERS.subscription("vip", { returnTo: "chat", sourceCharacterSlug: "elio", planId: "vip_annual", commercialOfferId: "offer-1", }), ).toBe( "/subscription?type=vip&returnTo=chat&character=elio&planId=vip_annual&commercialOfferId=offer-1", ); }); it("allows not logged in users to enter chat for guest bootstrap", () => { expect( resolveRouteGuardRedirect({ loginStatus: "notLoggedIn", pathname: ROUTES.chat, }), ).toBeNull(); }); it.each(["notLoggedIn", "guest"] as const)( "redirects %s users from profile to auth with the return context", (loginStatus) => { expect( resolveRouteGuardRedirect({ loginStatus, pathname: ROUTES.profile, searchParams: "returnTo=%2Fcharacters%2Fmaya%2Fchat", }), ).toBe( ROUTE_BUILDERS.authWithRedirect( "/profile?returnTo=%2Fcharacters%2Fmaya%2Fchat", ), ); }, ); it("redirects non-real users on subscription routes to auth", () => { expect( resolveRouteGuardRedirect({ loginStatus: "guest", pathname: ROUTES.subscription, searchParams: "type=vip&returnTo=chat", }), ).toBe( ROUTE_BUILDERS.authWithRedirect( "/subscription?type=vip&returnTo=chat", ), ); }); it("allows public and authorized routes", () => { expect( resolveRouteGuardRedirect({ loginStatus: "guest", pathname: ROUTES.coinsRules, }), ).toBeNull(); expect( resolveRouteGuardRedirect({ loginStatus: "email", pathname: ROUTES.subscription, searchParams: "type=vip", }), ).toBeNull(); }); });