import { describe, expect, it } from "vitest"; import { ChatLockDetailSchema, ChatSendResponseSchema, PaymentGuidanceSchema, UnlockHistoryResponseSchema, UnlockPrivateResponseSchema, } from "@/data/schemas/chat"; const guidance = { guidanceId: "guidance-1", characterId: "maya-tan", characterName: "Maya Tan", scene: "voiceLocked", mode: "guide", title: "Keep talking with Maya", copy: "Hey love, I want to keep talking. This voice message needs 20 credits.", ctaLabel: "View VIP & credit options", purchaseOptions: ["vip", "topup"], target: "subscription", ruleId: "payment_guidance_voiceLocked", } as const; describe("payment guidance wire contract", () => { it("parses the public decision without changing role identity", () => { expect(PaymentGuidanceSchema.parse(guidance)).toEqual(guidance); }); it("accepts the supportCharacter guidance scene", () => { expect( PaymentGuidanceSchema.parse({ ...guidance, scene: "supportCharacter", ruleId: "payment_guidance_supportCharacter", }).scene, ).toBe("supportCharacter"); }); it("keeps all backend lock facts instead of dropping hint and CTA", () => { expect( ChatLockDetailSchema.parse({ locked: true, showContent: false, showUpgrade: true, reason: "voice_message", hint: "This voice message needs 20 credits.", actionLabel: "Unlock", detail: { requiredCredits: 20 }, }), ).toEqual({ locked: true, showContent: false, showUpgrade: true, reason: "voice_message", hint: "This voice message needs 20 credits.", actionLabel: "Unlock", detail: { requiredCredits: 20 }, }); }); it("keeps backward compatibility when guidance is absent", () => { const parsed = ChatSendResponseSchema.parse({ reply: "Hello" }); expect(parsed.paymentGuidance).toBeNull(); }); it("parses guidance on chat and both unlock responses", () => { expect( ChatSendResponseSchema.parse({ reply: "", canSendMessage: false, paymentGuidance: guidance, }).paymentGuidance, ).toEqual(guidance); expect( UnlockPrivateResponseSchema.parse({ unlocked: false, reason: "insufficient_credits", paymentGuidance: guidance, }).paymentGuidance, ).toEqual(guidance); expect( UnlockHistoryResponseSchema.parse({ unlocked: false, reason: "insufficient_balance", paymentGuidance: { ...guidance, scene: "historyLocked" }, }).paymentGuidance?.scene, ).toBe("historyLocked"); }); });