282 lines
7.3 KiB
TypeScript
282 lines
7.3 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import { PaymentPlan } from "@/data/dto/payment";
|
|
|
|
import {
|
|
canChooseSubscriptionPayChannel,
|
|
findSelectedSubscriptionPlan,
|
|
getDefaultPayChannelForCountryCode,
|
|
getDefaultSubscriptionPlanId,
|
|
getFirstRechargeOfferView,
|
|
resolveSubscriptionPayChannel,
|
|
toCoinsOfferPlanViews,
|
|
toVipOfferPlanViews,
|
|
} from "../subscription-screen.helpers";
|
|
|
|
function makePlan(
|
|
overrides: Partial<Parameters<typeof PaymentPlan.from>[0]>,
|
|
): PaymentPlan {
|
|
return PaymentPlan.from({
|
|
planId: "plan",
|
|
planName: "Plan",
|
|
orderType: "vip_monthly",
|
|
vipDays: 30,
|
|
dolAmount: null,
|
|
creditBalance: 0,
|
|
amountCents: 1990,
|
|
originalAmountCents: null,
|
|
dailyPriceCents: null,
|
|
currency: "USD",
|
|
...overrides,
|
|
});
|
|
}
|
|
|
|
describe("subscription screen helpers", () => {
|
|
it("defaults Philippines users to Ezpay and other countries to Stripe", () => {
|
|
expect(getDefaultPayChannelForCountryCode("PH")).toBe("ezpay");
|
|
expect(getDefaultPayChannelForCountryCode("ph")).toBe("ezpay");
|
|
expect(getDefaultPayChannelForCountryCode("HK")).toBe("stripe");
|
|
expect(getDefaultPayChannelForCountryCode("")).toBe("stripe");
|
|
expect(getDefaultPayChannelForCountryCode(null)).toBe("stripe");
|
|
});
|
|
|
|
it("only allows payment method switching for Philippines users", () => {
|
|
expect(canChooseSubscriptionPayChannel("PH")).toBe(true);
|
|
expect(canChooseSubscriptionPayChannel("ph")).toBe(true);
|
|
expect(canChooseSubscriptionPayChannel("HK")).toBe(false);
|
|
expect(canChooseSubscriptionPayChannel(null)).toBe(false);
|
|
});
|
|
|
|
it("resolves subscription pay channel by country", () => {
|
|
expect(
|
|
resolveSubscriptionPayChannel({
|
|
countryCode: "PH",
|
|
requestedPayChannel: null,
|
|
}),
|
|
).toBe("ezpay");
|
|
expect(
|
|
resolveSubscriptionPayChannel({
|
|
countryCode: "PH",
|
|
requestedPayChannel: "stripe",
|
|
}),
|
|
).toBe("stripe");
|
|
expect(
|
|
resolveSubscriptionPayChannel({
|
|
countryCode: "HK",
|
|
requestedPayChannel: "ezpay",
|
|
}),
|
|
).toBe("stripe");
|
|
});
|
|
|
|
it("maps at most three VIP plans and all coin plans", () => {
|
|
const plans = [
|
|
makePlan({ planId: "vip_monthly", planName: "Monthly" }),
|
|
makePlan({ planId: "vip_quarterly", planName: "Quarterly", vipDays: 90 }),
|
|
makePlan({ planId: "vip_annual", planName: "Annual", vipDays: 365 }),
|
|
makePlan({ planId: "vip_extra", planName: "Extra", vipDays: 30 }),
|
|
makePlan({
|
|
planId: "coin_1000",
|
|
planName: "Coins",
|
|
orderType: "coins_1000",
|
|
vipDays: null,
|
|
dolAmount: 1000,
|
|
amountCents: 990,
|
|
}),
|
|
];
|
|
|
|
expect(toVipOfferPlanViews(plans).map((plan) => plan.id)).toEqual([
|
|
"vip_monthly",
|
|
"vip_quarterly",
|
|
"vip_annual",
|
|
]);
|
|
expect(toCoinsOfferPlanViews(plans)).toMatchObject([
|
|
{
|
|
id: "coin_1000",
|
|
coins: 1000,
|
|
price: "9.9",
|
|
currency: "US$",
|
|
},
|
|
]);
|
|
});
|
|
|
|
it("finds selected coin plans in VIP mode", () => {
|
|
const selected = findSelectedSubscriptionPlan({
|
|
canSubscribeVip: true,
|
|
selectedPlanId: "coin_1000",
|
|
vipPlans: [
|
|
{
|
|
id: "vip_monthly",
|
|
title: "Monthly",
|
|
price: "19.90",
|
|
currency: "usd",
|
|
originalPrice: "",
|
|
},
|
|
],
|
|
coinPlans: [{ id: "coin_1000", coins: 1000, price: "9.90", currency: "US$" }],
|
|
});
|
|
|
|
expect(selected?.id).toBe("coin_1000");
|
|
});
|
|
|
|
it("formats plan amounts from cents with a dot decimal separator", () => {
|
|
expect(
|
|
toVipOfferPlanViews([
|
|
makePlan({
|
|
planId: "vip_test",
|
|
amountCents: 7790,
|
|
}),
|
|
]),
|
|
).toMatchObject([
|
|
{
|
|
id: "vip_test",
|
|
price: "77.9",
|
|
},
|
|
]);
|
|
});
|
|
|
|
it("maps first recharge offer fields to plan views", () => {
|
|
const vipViews = toVipOfferPlanViews([
|
|
makePlan({
|
|
planId: "vip_monthly",
|
|
amountCents: 995,
|
|
originalAmountCents: 1990,
|
|
isFirstRechargeOffer: true,
|
|
firstRechargeDiscountPercent: 50,
|
|
promotionType: "first_recharge_half_price",
|
|
}),
|
|
]);
|
|
const coinViews = toCoinsOfferPlanViews([
|
|
makePlan({
|
|
planId: "coin_1000",
|
|
orderType: "coins_1000",
|
|
vipDays: null,
|
|
dolAmount: 1000,
|
|
amountCents: 495,
|
|
originalAmountCents: 990,
|
|
isFirstRechargeOffer: true,
|
|
firstRechargeDiscountPercent: 50,
|
|
promotionType: "first_recharge_half_price",
|
|
}),
|
|
]);
|
|
|
|
expect(vipViews[0]).toMatchObject({
|
|
price: "9.95",
|
|
originalPrice: "19.9",
|
|
isFirstRechargeOffer: true,
|
|
firstRechargeDiscountPercent: 50,
|
|
});
|
|
expect(coinViews[0]).toMatchObject({
|
|
price: "4.95",
|
|
originalPrice: "9.9",
|
|
isFirstRechargeOffer: true,
|
|
firstRechargeDiscountPercent: 50,
|
|
});
|
|
expect(
|
|
getFirstRechargeOfferView({
|
|
isFirstRecharge: true,
|
|
vipPlans: vipViews,
|
|
coinPlans: coinViews,
|
|
}),
|
|
).toMatchObject({
|
|
badgeText: "50% OFF",
|
|
title: "First Recharge Offer",
|
|
});
|
|
expect(
|
|
getFirstRechargeOfferView({
|
|
isFirstRecharge: false,
|
|
vipPlans: vipViews,
|
|
coinPlans: coinViews,
|
|
}),
|
|
).toBeNull();
|
|
});
|
|
|
|
it("maps normal VIP original price outside first recharge activity", () => {
|
|
expect(
|
|
toVipOfferPlanViews([
|
|
makePlan({
|
|
planId: "vip_monthly",
|
|
amountCents: 1990,
|
|
originalAmountCents: 2499,
|
|
isFirstRechargeOffer: false,
|
|
}),
|
|
]),
|
|
).toMatchObject([
|
|
{
|
|
id: "vip_monthly",
|
|
price: "19.9",
|
|
originalPrice: "24.99",
|
|
isFirstRechargeOffer: false,
|
|
},
|
|
]);
|
|
});
|
|
|
|
it("selects the first VIP plan by default when VIP can be purchased", () => {
|
|
expect(
|
|
getDefaultSubscriptionPlanId({
|
|
canSubscribeVip: true,
|
|
selectedPlanId: "",
|
|
status: "ready",
|
|
isLoadingPlans: false,
|
|
selectedPlan: null,
|
|
vipPlans: [
|
|
{
|
|
id: "vip_monthly",
|
|
title: "Monthly",
|
|
price: "19.90",
|
|
currency: "usd",
|
|
originalPrice: "",
|
|
},
|
|
],
|
|
coinPlans: [],
|
|
}),
|
|
).toBe("vip_monthly");
|
|
});
|
|
|
|
it("selects the first coin plan by default in top-up-only mode", () => {
|
|
expect(
|
|
getDefaultSubscriptionPlanId({
|
|
canSubscribeVip: false,
|
|
selectedPlanId: "",
|
|
status: "ready",
|
|
isLoadingPlans: false,
|
|
selectedPlan: null,
|
|
vipPlans: [],
|
|
coinPlans: [
|
|
{
|
|
id: "coin_1000",
|
|
coins: 1000,
|
|
price: "9.9",
|
|
currency: "US$",
|
|
},
|
|
],
|
|
}),
|
|
).toBe("coin_1000");
|
|
});
|
|
|
|
it("does not override an existing selected plan", () => {
|
|
expect(
|
|
getDefaultSubscriptionPlanId({
|
|
canSubscribeVip: false,
|
|
selectedPlanId: "coin_1000",
|
|
status: "ready",
|
|
isLoadingPlans: false,
|
|
selectedPlan: {
|
|
id: "coin_1000",
|
|
coins: 1000,
|
|
price: "9.9",
|
|
currency: "US$",
|
|
},
|
|
vipPlans: [],
|
|
coinPlans: [
|
|
{
|
|
id: "coin_1000",
|
|
coins: 1000,
|
|
price: "9.9",
|
|
currency: "US$",
|
|
},
|
|
],
|
|
}),
|
|
).toBeNull();
|
|
});
|
|
});
|