refactor(routes): move shared pages to global scope
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
buildGlobalPageUrl,
|
||||
resolveGlobalRouteContext,
|
||||
resolveGlobalRouteContextValue,
|
||||
} from "../global-route-context";
|
||||
import { ROUTES } from "../routes";
|
||||
|
||||
describe("global route context", () => {
|
||||
it("preserves a known character chat as the return target", () => {
|
||||
const context = resolveGlobalRouteContext("/characters/maya/chat");
|
||||
|
||||
expect(context).toMatchObject({
|
||||
characterSlug: "maya",
|
||||
chatUrl: "/characters/maya/chat",
|
||||
splashUrl: "/characters/maya/splash",
|
||||
});
|
||||
expect(context.sidebarUrl).toBe(
|
||||
"/sidebar?returnTo=%2Fcharacters%2Fmaya%2Fchat",
|
||||
);
|
||||
expect(context.feedbackUrl).toBe(
|
||||
"/feedback?returnTo=%2Fcharacters%2Fmaya%2Fchat",
|
||||
);
|
||||
expect(context.coinsRulesUrl).toBe(
|
||||
"/coins-rules?returnTo=%2Fcharacters%2Fmaya%2Fchat",
|
||||
);
|
||||
});
|
||||
|
||||
it("uses only the first repeated return target", () => {
|
||||
expect(
|
||||
resolveGlobalRouteContextValue([
|
||||
"/characters/nayeli/chat",
|
||||
"/characters/maya/chat",
|
||||
]),
|
||||
).toBe("/characters/nayeli/chat");
|
||||
});
|
||||
|
||||
it.each([
|
||||
undefined,
|
||||
null,
|
||||
"",
|
||||
"https://example.com/characters/maya/chat",
|
||||
"//example.com/characters/maya/chat",
|
||||
"/characters/unknown/chat",
|
||||
"/characters/maya/private-room",
|
||||
"/characters/maya/chat?image=1",
|
||||
])("falls back to Elio for an invalid return target", (value) => {
|
||||
expect(resolveGlobalRouteContextValue(value)).toBe(
|
||||
"/characters/elio/chat",
|
||||
);
|
||||
});
|
||||
|
||||
it("sanitizes return targets when building a global page url", () => {
|
||||
expect(buildGlobalPageUrl(ROUTES.sidebar, "https://example.com")).toBe(
|
||||
"/sidebar?returnTo=%2Fcharacters%2Felio%2Fchat",
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { LEGACY_GLOBAL_ROUTE_REDIRECTS } from "../legacy-global-route-redirects";
|
||||
|
||||
describe("legacy global route redirects", () => {
|
||||
it("redirects character-scoped global pages without permanent caching", () => {
|
||||
expect(LEGACY_GLOBAL_ROUTE_REDIRECTS).toEqual([
|
||||
{
|
||||
source: "/characters/:characterSlug/sidebar",
|
||||
destination: "/sidebar?returnTo=/characters/:characterSlug/chat",
|
||||
permanent: false,
|
||||
},
|
||||
{
|
||||
source: "/characters/:characterSlug/feedback",
|
||||
destination: "/feedback?returnTo=/characters/:characterSlug/chat",
|
||||
permanent: false,
|
||||
},
|
||||
{
|
||||
source: "/characters/:characterSlug/coins-rules",
|
||||
destination:
|
||||
"/coins-rules?returnTo=/characters/:characterSlug/chat",
|
||||
permanent: false,
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
@@ -59,9 +59,10 @@ describe("navigation resolver", () => {
|
||||
ROUTE_BUILDERS.subscription("topup", {
|
||||
payChannel: "stripe",
|
||||
returnTo: "private-room",
|
||||
sourceCharacterSlug: "maya",
|
||||
}),
|
||||
).toBe(
|
||||
"/subscription?type=topup&payChannel=stripe&returnTo=private-room",
|
||||
"/subscription?type=topup&payChannel=stripe&returnTo=private-room&character=maya",
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { getRouteAccess, isInternalRoute } from "../route-meta";
|
||||
import { ALL_STATIC_ROUTES, getCharacterRoutes, ROUTES } from "../routes";
|
||||
|
||||
describe("route meta", () => {
|
||||
it("classifies static routes by access level", () => {
|
||||
it("classifies global routes by access level", () => {
|
||||
expect(getRouteAccess(ROUTES.splash)).toBe("authOnly");
|
||||
expect(getRouteAccess(ROUTES.auth)).toBe("authOnly");
|
||||
expect(getRouteAccess(ROUTES.chat)).toBe("guestEntry");
|
||||
@@ -23,13 +23,22 @@ describe("route meta", () => {
|
||||
|
||||
it("classifies character-scoped routes by their page", () => {
|
||||
const routes = getCharacterRoutes("maya");
|
||||
expect(routes).toEqual({
|
||||
splash: "/characters/maya/splash",
|
||||
chat: "/characters/maya/chat",
|
||||
privateRoom: "/characters/maya/private-room",
|
||||
tip: "/characters/maya/tip",
|
||||
});
|
||||
expect(getRouteAccess(routes.splash)).toBe("authOnly");
|
||||
expect(getRouteAccess(routes.chat)).toBe("guestEntry");
|
||||
expect(getRouteAccess(routes.privateRoom)).toBe("guestEntry");
|
||||
expect(getRouteAccess(routes.tip)).toBe("public");
|
||||
expect(getRouteAccess(routes.sidebar)).toBe("session");
|
||||
expect(getRouteAccess(routes.feedback)).toBe("session");
|
||||
expect(getRouteAccess(routes.coinsRules)).toBe("public");
|
||||
});
|
||||
|
||||
it("does not classify removed character-scoped global pages", () => {
|
||||
expect(getRouteAccess("/characters/maya/sidebar")).toBe("public");
|
||||
expect(getRouteAccess("/characters/maya/feedback")).toBe("public");
|
||||
expect(getRouteAccess("/characters/maya/coins-rules")).toBe("public");
|
||||
});
|
||||
|
||||
it("includes private room in static routes", () => {
|
||||
|
||||
Reference in New Issue
Block a user