Files
cozsweet-frontend-nextjs/e2e/fixtures/api/chat.ts
T

72 lines
3.7 KiB
TypeScript

import type { Page } from "@playwright/test";
import { apiEnvelope } from "../data/common";
import { chatSendResponse, createChatSendResponse, createPaidImageHistoryResponse, createWeeklyLimitChatSendResponse, emptyChatHistoryResponse, insufficientCreditsUnlockImageResponse, insufficientCreditsUnlockVoiceResponse, paidImageChatSendResponse, paidImageUnlockHistoryResponse, paidVoiceHistoryResponse } from "../data/chat";
export interface ChatMockOptions {
chatLimitTriggerAt?: number;
chatSendTokenRefreshFlow: boolean;
paidImageFlow: boolean;
paidImageInsufficientCreditsFlow: boolean;
paidVoiceInsufficientCreditsFlow: boolean;
}
export interface ChatMockState {
hasExpiredChatSend: boolean;
paidImageRequested: boolean;
paidImageUnlocked: boolean;
}
export async function registerChatMocks(page: Page, options: ChatMockOptions, state: ChatMockState) {
let sendCount = 0;
await page.route("**/api/chat/history**", async (route) => {
const response = options.paidVoiceInsufficientCreditsFlow
? paidVoiceHistoryResponse
: options.paidImageInsufficientCreditsFlow
? createPaidImageHistoryResponse(false)
: options.paidImageFlow && state.paidImageRequested
? createPaidImageHistoryResponse(state.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 : "";
if (options.chatSendTokenRefreshFlow && !state.hasExpiredChatSend) {
state.hasExpiredChatSend = true;
await route.fulfill({ status: 401, json: { message: "expired" } });
return;
}
const response = options.paidImageFlow && message.includes("给我发图片")
? paidImageChatSendResponse
: options.chatLimitTriggerAt != null && sendCount >= options.chatLimitTriggerAt
? createWeeklyLimitChatSendResponse(sendCount, options.chatLimitTriggerAt)
: options.chatLimitTriggerAt != null
? createChatSendResponse(sendCount)
: chatSendResponse;
if (options.paidImageFlow && message.includes("给我发图片")) {
state.paidImageRequested = true;
state.paidImageUnlocked = false;
}
await route.fulfill({ json: apiEnvelope(response) });
});
await page.route("**/api/chat/unlock-history", async (route) => {
if (options.paidImageFlow && state.paidImageRequested) state.paidImageUnlocked = true;
const response = options.paidImageFlow && state.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 = options.paidVoiceInsufficientCreditsFlow
? insufficientCreditsUnlockVoiceResponse
: options.paidImageInsufficientCreditsFlow || options.paidImageFlow && state.paidImageRequested && !state.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) });
});
}