feat(subscription): highlight popular plans

This commit is contained in:
2026-07-15 18:30:18 +08:00
parent c37a2f9040
commit 7dce1b5d4c
10 changed files with 157 additions and 14 deletions
@@ -20,10 +20,12 @@ describe("PaymentPlan", () => {
originalAmountCents: 2499,
dailyPriceCents: 66,
currency: "JPY",
mostPopular: true,
});
expect(plan.planId).toBe("vip_monthly");
expect(plan.creditBalance).toBe(3000);
expect(plan.mostPopular).toBe(true);
expect(plan.toJson()).toEqual({
planId: "vip_monthly",
planName: "VIP Monthly",
@@ -36,6 +38,7 @@ describe("PaymentPlan", () => {
dailyPriceCents: 66,
currency: "JPY",
isFirstRechargeOffer: false,
mostPopular: true,
firstRechargeDiscountPercent: null,
promotionType: null,
});
@@ -56,6 +59,23 @@ describe("PaymentPlan", () => {
}),
).toThrow(z.ZodError);
});
it("defaults mostPopular to false when the backend omits it", () => {
const plan = PaymentPlan.from({
planId: "vip_monthly",
planName: "VIP Monthly",
orderType: "vip_monthly",
vipDays: 30,
dolAmount: null,
creditBalance: 3000,
amountCents: 1999,
originalAmountCents: null,
dailyPriceCents: null,
currency: "USD",
});
expect(plan.mostPopular).toBe(false);
});
});
describe("PaymentPlansResponse", () => {
+1
View File
@@ -18,6 +18,7 @@ export class PaymentPlan {
declare readonly originalAmountCents: number | null;
declare readonly currency: string;
declare readonly isFirstRechargeOffer: boolean;
declare readonly mostPopular: boolean;
declare readonly firstRechargeDiscountPercent: number | null;
declare readonly promotionType: string | null;
+1
View File
@@ -21,6 +21,7 @@ export const PaymentPlanSchema = z.object({
dailyPriceCents: numberOrNull,
currency: z.string(),
isFirstRechargeOffer: booleanOrFalse,
mostPopular: booleanOrFalse,
firstRechargeDiscountPercent: numberOrNull,
promotionType: stringOrNull,
});