Files
cozsweet-frontend-nextjs/src/lib/navigation/__tests__/external_entry.test.ts
T
admin 9deb320cf6 feat(profile)!: replace sidebar and add avatar navigation
Rename the global Sidebar route, UI, assets, analytics, and payment return context to Profile. Add accessible message-avatar navigation and preserve the source character across auth and logout flows.

BREAKING CHANGE: /sidebar has been removed; use /profile instead.
2026-07-21 18:08:12 +08:00

145 lines
4.0 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { getCharacterRoutes, ROUTES } from "@/router/routes";
import {
resolveExternalEntryDestination,
resolveExternalEntryPromotionType,
resolveExternalEntryTarget,
shouldBindExternalFacebookIdentity,
} from "../external_entry";
describe("external entry navigation", () => {
it("defaults to chat", () => {
expect(resolveExternalEntryTarget({})).toBe(ROUTES.chat);
});
it("resolves only canonical targets", () => {
expect(resolveExternalEntryTarget({ target: "chat" })).toBe(ROUTES.chat);
expect(resolveExternalEntryTarget({ target: "tip" })).toBe(ROUTES.tip);
expect(resolveExternalEntryTarget({ target: "private-room" })).toBe(
ROUTES.privateRoom,
);
});
it("rejects removed aliases and unsupported targets", () => {
expect(resolveExternalEntryTarget({ target: "tips" })).toBe(ROUTES.chat);
expect(resolveExternalEntryTarget({ target: "coffee" })).toBe(ROUTES.chat);
expect(resolveExternalEntryTarget({ target: "private_room" })).toBe(
ROUTES.chat,
);
expect(resolveExternalEntryTarget({ target: "/tip" })).toBe(ROUTES.chat);
expect(resolveExternalEntryTarget({ target: "profile" })).toBe(ROUTES.chat);
});
it("routes every tip entry to the tier selection page", () => {
expect(resolveExternalEntryDestination({ target: "tip" })).toBe(
getCharacterRoutes("elio").tip,
);
});
it("uses a known character slug and falls back to Elio", () => {
expect(
resolveExternalEntryDestination({ target: "chat", character: "maya" }),
).toBe(getCharacterRoutes("maya").chat);
expect(
resolveExternalEntryDestination({
target: "private-room",
character: "unknown",
}),
).toBe(getCharacterRoutes("elio").privateRoom);
});
});
describe("external entry facebook identity binding", () => {
it("binds only a ready real-user session with an external id", () => {
expect(
shouldBindExternalFacebookIdentity({
hasInitialized: true,
isLoading: false,
loginStatus: "email",
asid: "asid-1",
}),
).toBe(true);
expect(
shouldBindExternalFacebookIdentity({
hasInitialized: true,
isLoading: false,
loginStatus: "google",
asid: "asid-1",
}),
).toBe(true);
expect(
shouldBindExternalFacebookIdentity({
hasInitialized: true,
isLoading: false,
loginStatus: "facebook",
psid: "psid-1",
}),
).toBe(true);
});
it("skips guest, notLoggedIn, loading, and empty identity inputs", () => {
expect(
shouldBindExternalFacebookIdentity({
hasInitialized: true,
isLoading: false,
loginStatus: "guest",
asid: "asid-1",
}),
).toBe(false);
expect(
shouldBindExternalFacebookIdentity({
hasInitialized: true,
isLoading: false,
loginStatus: "notLoggedIn",
psid: "psid-1",
}),
).toBe(false);
expect(
shouldBindExternalFacebookIdentity({
hasInitialized: true,
isLoading: true,
loginStatus: "google",
asid: "asid-1",
}),
).toBe(false);
expect(
shouldBindExternalFacebookIdentity({
hasInitialized: true,
isLoading: false,
loginStatus: "google",
}),
).toBe(false);
});
});
describe("external entry promotion", () => {
it("accepts only explicit promotion mode and supported message types", () => {
expect(
resolveExternalEntryPromotionType({
mode: "promotion",
promotionType: "voice",
}),
).toBe("voice");
expect(
resolveExternalEntryPromotionType({
mode: "promotion",
promotionType: "image",
}),
).toBe("image");
expect(
resolveExternalEntryPromotionType({
mode: "normal",
promotionType: "private",
}),
).toBeNull();
expect(
resolveExternalEntryPromotionType({
mode: "promotion",
promotionType: "video",
}),
).toBeNull();
});
});