import { describe, expect, test } from "vitest"; import { completeVipLevels, levelToForm, vipConfigPayloadFromForm } from "./useVipConfigPage.js"; describe("VIP config form semantics", () => { test("keeps only explicit target-level benefits and never restores catalog omissions", () => { const program = tieredProgram({ benefits: [ benefit({ benefitCode: "vip_badge_identity", name: "VIP标识", status: "active", unlockLevel: 1 }), benefit({ benefitCode: "daily_coin_rebate", name: "金币返现", status: "active", unlockLevel: 6 }), ], }); const levels = completeVipLevels( [ { ...level(), benefits: [benefit({ benefitCode: "vip_badge_identity", name: "VIP标识", status: "disabled" })], }, ], program, ); expect(levels[0].benefits).toHaveLength(1); expect(levels[0].benefits[0]).toMatchObject({ benefitCode: "vip_badge_identity", status: "disabled" }); expect(levels[0].benefits.some((item) => item.benefitCode === "daily_coin_rebate")).toBe(false); }); test("allows an active Fami level without a reward group and saves typed benefit metadata", () => { const payload = vipConfigPayloadFromForm( { levels: [ level({ benefits: [ benefit({ benefitCode: "daily_coin_rebate", metadataJson: '{"source":"daily","coin_amount":"88"}', name: "金币返现", status: "active", trialEnabled: true, unlockLevel: 6, }), benefit({ benefitCode: "online_global_notice", executionScope: "notice", metadataJson: '{"message":" 欢迎上线 ","theme":"gold"}', name: "上线全服通知", status: "active", unlockLevel: 9, }), ], rewardResourceGroupId: "", }), ], }, tieredProgram(), ); expect(payload.levels[0].rewardResourceGroupId).toBe(0); expect(JSON.parse(payload.levels[0].benefits[0].metadataJson)).toEqual({ source: "daily", coin_amount: 88, }); expect(payload.levels[0].benefits[0].trialEnabled).toBe(false); expect(JSON.parse(payload.levels[0].benefits[1].metadataJson)).toEqual({ message: "欢迎上线", theme: "gold", }); }); test("shows missing catalog benefits as disabled placeholders without persisting untouched rows", () => { const program = tieredProgram({ benefits: [ benefit({ benefitCode: "vip_badge_identity", name: "VIP标识", status: "active" }), benefit({ benefitCode: "visitor_history", name: "查看访客", status: "active" }), ], }); const formLevel = levelToForm( level({ benefits: [benefit({ benefitCode: "vip_badge_identity", name: "VIP标识", status: "active" })], }), program, ); expect(formLevel.benefits).toHaveLength(34); const visitorIndex = formLevel.benefits.findIndex((item) => item.benefitCode === "visitor_history"); expect(formLevel.benefits[visitorIndex]).toMatchObject({ benefitCode: "visitor_history", catalogPlaceholder: true, status: "disabled", }); expect(vipConfigPayloadFromForm({ levels: [formLevel] }, program).levels[0].benefits).toHaveLength(1); formLevel.benefits[visitorIndex] = { ...formLevel.benefits[visitorIndex], status: "active" }; expect(vipConfigPayloadFromForm({ levels: [formLevel] }, program).levels[0].benefits).toHaveLength(2); }); test("keeps the reward group requirement for an active classic VIP level", () => { expect(() => vipConfigPayloadFromForm( { levels: [level({ benefits: [], rewardResourceGroupId: "" })] }, { ...tieredProgram(), programType: "legacy_timed" }, ), ).toThrow("启用时必须选择奖励资源组"); }); }); function tieredProgram(patch = {}) { return { levelCount: 1, programType: "tiered_privilege_v1", ...patch, }; } function level(patch = {}) { return { benefits: [], durationDays: "30", durationMs: 30 * 24 * 60 * 60 * 1000, level: 1, name: "VIP1", priceCoin: "100", rewardResourceGroupId: "", sortOrder: "10", status: "active", ...patch, }; } function benefit(patch = {}) { return { autoEquip: false, benefitCode: "room_entry_notice", benefitType: "function", executionScope: "room", metadataJson: "{}", name: "VIP进房通知", resourceId: "", resourceType: "", sortOrder: "10", status: "active", trialEnabled: true, unlockLevel: 1, ...patch, }; }