184 lines
5.5 KiB
TypeScript
184 lines
5.5 KiB
TypeScript
import type { Page } from "@playwright/test";
|
|
|
|
import {
|
|
apiEnvelope,
|
|
chatSendResponse,
|
|
createPaymentOrderResponse,
|
|
createChatSendResponse,
|
|
createPaidImageHistoryResponse,
|
|
createWeeklyLimitChatSendResponse,
|
|
e2eEmailUser,
|
|
emptyChatHistoryResponse,
|
|
emailLoginResponse,
|
|
guestLoginResponse,
|
|
insufficientCreditsUnlockImageResponse,
|
|
insufficientCreditsUnlockVoiceResponse,
|
|
paidImageChatSendResponse,
|
|
paidImageUnlockHistoryResponse,
|
|
paidVoiceHistoryResponse,
|
|
paidPaymentOrderStatusResponse,
|
|
paymentPlansResponse,
|
|
userEntitlementsResponse,
|
|
vipStatusResponse,
|
|
} from "./test-data";
|
|
|
|
interface MockCoreApisOptions {
|
|
chatLimitTriggerAt?: number;
|
|
paidImageFlow?: boolean;
|
|
paidImageInsufficientCreditsFlow?: boolean;
|
|
paidVoiceInsufficientCreditsFlow?: boolean;
|
|
}
|
|
|
|
export async function mockCoreApis(
|
|
page: Page,
|
|
options: MockCoreApisOptions = {},
|
|
): Promise<void> {
|
|
const {
|
|
chatLimitTriggerAt,
|
|
paidImageFlow = false,
|
|
paidImageInsufficientCreditsFlow = false,
|
|
paidVoiceInsufficientCreditsFlow = false,
|
|
} = options;
|
|
let sendCount = 0;
|
|
let paidImageRequested = false;
|
|
let paidImageUnlocked = false;
|
|
|
|
await page.route("**/api/auth/guest", async (route) => {
|
|
await route.fulfill({ json: apiEnvelope(guestLoginResponse) });
|
|
});
|
|
|
|
await page.route("**/api/auth/login", async (route) => {
|
|
if (paidImageFlow) {
|
|
paidImageRequested = true;
|
|
}
|
|
|
|
await route.fulfill({ json: apiEnvelope(emailLoginResponse) });
|
|
});
|
|
|
|
await page.route("**/api/auth/logout", async (route) => {
|
|
await route.fulfill({ json: apiEnvelope(null) });
|
|
});
|
|
|
|
await page.route("**/api/user/profile", async (route) => {
|
|
await route.fulfill({ json: apiEnvelope(e2eEmailUser) });
|
|
});
|
|
|
|
await page.route("**/api/user/entitlements", async (route) => {
|
|
await route.fulfill({ json: apiEnvelope(userEntitlementsResponse) });
|
|
});
|
|
|
|
await page.route("**/api/chat/history**", async (route) => {
|
|
const response =
|
|
paidVoiceInsufficientCreditsFlow
|
|
? paidVoiceHistoryResponse
|
|
: paidImageInsufficientCreditsFlow
|
|
? createPaidImageHistoryResponse(false)
|
|
: paidImageFlow && paidImageRequested
|
|
? createPaidImageHistoryResponse(paidImageUnlocked)
|
|
: emptyChatHistoryResponse;
|
|
|
|
await route.fulfill({ json: apiEnvelope(response) });
|
|
});
|
|
|
|
await page.route("**/api/chat/send", async (route) => {
|
|
sendCount += 1;
|
|
const requestBody = route.request().postDataJSON() as
|
|
| { message?: unknown }
|
|
| undefined;
|
|
const message =
|
|
typeof requestBody?.message === "string" ? requestBody.message : "";
|
|
|
|
const response =
|
|
paidImageFlow && message.includes("给我发图片")
|
|
? paidImageChatSendResponse
|
|
: chatLimitTriggerAt != null && sendCount >= chatLimitTriggerAt
|
|
? createWeeklyLimitChatSendResponse(sendCount, chatLimitTriggerAt)
|
|
: chatLimitTriggerAt != null
|
|
? createChatSendResponse(sendCount)
|
|
: chatSendResponse;
|
|
|
|
if (paidImageFlow && message.includes("给我发图片")) {
|
|
paidImageRequested = true;
|
|
paidImageUnlocked = false;
|
|
}
|
|
|
|
await route.fulfill({ json: apiEnvelope(response) });
|
|
});
|
|
|
|
await page.route("**/api/chat/unlock-history", async (route) => {
|
|
if (paidImageFlow && paidImageRequested) {
|
|
paidImageUnlocked = true;
|
|
}
|
|
|
|
const response =
|
|
paidImageFlow && paidImageRequested
|
|
? paidImageUnlockHistoryResponse
|
|
: {
|
|
unlocked: true,
|
|
reason: "no_locked_messages",
|
|
totalLocked: 0,
|
|
unlockedCount: 0,
|
|
privateCount: 0,
|
|
imageCount: 0,
|
|
voiceCount: 0,
|
|
requiredCredits: 0,
|
|
currentCredits: 0,
|
|
remainingCredits: 0,
|
|
shortfallCredits: 0,
|
|
costsByMessage: {},
|
|
messageIds: [],
|
|
};
|
|
|
|
await route.fulfill({ json: apiEnvelope(response) });
|
|
});
|
|
|
|
await page.route("**/api/chat/unlock-private", async (route) => {
|
|
const response =
|
|
paidVoiceInsufficientCreditsFlow
|
|
? insufficientCreditsUnlockVoiceResponse
|
|
: paidImageInsufficientCreditsFlow
|
|
? insufficientCreditsUnlockImageResponse
|
|
: paidImageFlow && paidImageRequested && !paidImageUnlocked
|
|
? insufficientCreditsUnlockImageResponse
|
|
: {
|
|
unlocked: true,
|
|
content: "Unlocked message",
|
|
reason: "ok",
|
|
creditBalance: 100,
|
|
creditsCharged: 0,
|
|
requiredCredits: 0,
|
|
shortfallCredits: 0,
|
|
lockDetail: {
|
|
locked: false,
|
|
showContent: true,
|
|
showUpgrade: false,
|
|
reason: null,
|
|
hint: null,
|
|
detail: null,
|
|
},
|
|
};
|
|
|
|
await route.fulfill({ json: apiEnvelope(response) });
|
|
});
|
|
|
|
await page.route("**/api/payment/plans**", async (route) => {
|
|
await route.fulfill({ json: apiEnvelope(paymentPlansResponse) });
|
|
});
|
|
|
|
await page.route("**/api/payment/create-order", async (route) => {
|
|
await route.fulfill({ json: apiEnvelope(createPaymentOrderResponse) });
|
|
});
|
|
|
|
await page.route("**/api/payment/order-status**", async (route) => {
|
|
if (paidImageFlow && paidImageRequested) {
|
|
paidImageUnlocked = true;
|
|
}
|
|
|
|
await route.fulfill({ json: apiEnvelope(paidPaymentOrderStatusResponse) });
|
|
});
|
|
|
|
await page.route("**/api/payment/vip-status**", async (route) => {
|
|
await route.fulfill({ json: apiEnvelope(vipStatusResponse) });
|
|
});
|
|
}
|