feat(auth): add Messenger topup handoff entry

This commit is contained in:
Codex
2026-07-27 17:16:27 +08:00
parent f403c47052
commit 662e5e67ea
28 changed files with 271 additions and 319 deletions
@@ -1,49 +1,74 @@
import { expect, test } from "@playwright/test";
import { mockCoreApis } from "@e2e/fixtures/api-mocks";
import {
clearBrowserState,
defaultCharacterChatUrl,
} from "@e2e/fixtures/test-helpers";
import { clearBrowserState } from "@e2e/fixtures/test-helpers";
const psid = "e2e-facebook-psid";
const handoffToken = "e2e-handoff-token-that-is-at-least-32-characters";
test.beforeEach(async ({ baseURL, context, page }) => {
await clearBrowserState(context, page, baseURL);
await mockCoreApis(page, { psidLoginFlow: true });
await mockCoreApis(page, { topUpHandoffFlow: true });
});
test("user enters from an external PSID link and becomes a guest", async ({
test("user consumes a top-up handoff and opens credit packages as a formal Messenger user", async ({
page,
}) => {
const psidLoginRequestPromise = page.waitForRequest(
"**/api/auth/login/facebook/psid",
const handoffRequestPromise = page.waitForRequest(
"**/api/auth/handoff/topup/consume",
);
await page.goto(`/external-entry?target=chat&psid=${psid}`);
await page.goto(
`/external-entry?target=topup&handoffToken=${encodeURIComponent(handoffToken)}`,
);
const psidLoginRequest = await psidLoginRequestPromise;
expect(psidLoginRequest.method()).toBe("POST");
expect(psidLoginRequest.postDataJSON()).toMatchObject({
psid,
bindToGuest: true,
});
expect(psidLoginRequest.postDataJSON().deviceId).toEqual(expect.any(String));
const handoffRequest = await handoffRequestPromise;
expect(handoffRequest.method()).toBe("POST");
expect(handoffRequest.postDataJSON()).toEqual({ handoffToken });
await expect(page).toHaveURL(defaultCharacterChatUrl);
await expect(page.getByRole("textbox", { name: "Message" })).toBeVisible();
await expect(page).toHaveURL("/subscription?type=topup");
await expect(
page.getByRole("button", { name: /Pay and Top Up/i }),
).toBeVisible();
await expect
.poll(() =>
page.evaluate(() => ({
loginProvider: localStorage.getItem("cozsweet:login_provider"),
guestToken: localStorage.getItem("cozsweet:guest_token"),
psid: localStorage.getItem("cozsweet:psid"),
loginToken: localStorage.getItem("cozsweet:login_token"),
refreshToken: localStorage.getItem("cozsweet:refresh_token"),
})),
)
.toMatchObject({
loginProvider: "guest",
guestToken: "e2e-psid-guest-token",
psid,
loginProvider: "facebookMessenger",
loginToken: "e2e-messenger-token",
refreshToken: "e2e-messenger-refresh-token",
});
});
test("invalid top-up handoff does not log in and is removed from the URL", async ({
page,
}) => {
await page.route("**/api/auth/handoff/topup/consume", async (route) => {
await route.fulfill({
status: 410,
json: {
detail: {
code: "HANDOFF_EXPIRED",
message: "充值链接已过期",
},
},
});
});
await page.goto(
`/external-entry?target=topup&handoffToken=${encodeURIComponent(handoffToken)}`,
);
await expect(page).toHaveURL("/external-entry?target=topup");
await expect(
page.getByText(/invalid or has expired/i),
).toBeVisible();
await expect
.poll(() => page.evaluate(() => localStorage.getItem("cozsweet:login_provider")))
.not.toBe("facebookMessenger");
});