mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-14 03:52:26 +08:00
152 lines
5.9 KiB
TypeScript
152 lines
5.9 KiB
TypeScript
import { mount } from "@vue/test-utils";
|
|
import { describe, expect, it } from "vitest";
|
|
import { createPinia } from "pinia";
|
|
import { createI18n } from "vue-i18n";
|
|
import type { SubscriptionPlan } from "@/types/payment";
|
|
import SubscriptionPlanCard from "../SubscriptionPlanCard.vue";
|
|
|
|
const i18n = createI18n({
|
|
legacy: false,
|
|
locale: "en",
|
|
fallbackWarn: false,
|
|
missingWarn: false,
|
|
messages: {
|
|
en: {
|
|
payment: {
|
|
days: "days",
|
|
weeks: "weeks",
|
|
months: "months",
|
|
perMonth: "month",
|
|
models: "Models",
|
|
planCard: {
|
|
quota: "Quota",
|
|
rate: "Rate",
|
|
unlimited: "Unlimited",
|
|
},
|
|
subscribeNow: "Subscribe now",
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
const mountPlanCard = (groupPlatform: string, overrides: Partial<SubscriptionPlan> = {}) =>
|
|
mount(SubscriptionPlanCard, {
|
|
props: {
|
|
plan: {
|
|
id: 1,
|
|
group_id: 10,
|
|
group_platform: groupPlatform,
|
|
name: "Pro",
|
|
price: 10,
|
|
amount: 1000,
|
|
features: [],
|
|
rate_multiplier: 1,
|
|
validity_days: 30,
|
|
validity_unit: "day",
|
|
supported_model_scopes: ["claude", "gemini_text", "gemini_image"],
|
|
is_active: true,
|
|
...overrides,
|
|
},
|
|
},
|
|
global: { plugins: [i18n, createPinia()] },
|
|
});
|
|
|
|
describe("SubscriptionPlanCard", () => {
|
|
it("does not show Antigravity model scopes for OpenAI plans", () => {
|
|
const text = mountPlanCard("openai").text();
|
|
|
|
expect(text).not.toContain("Claude");
|
|
expect(text).not.toContain("Gemini");
|
|
expect(text).not.toContain("Imagen");
|
|
});
|
|
|
|
it("shows model scopes for Antigravity plans", () => {
|
|
const text = mountPlanCard("antigravity").text();
|
|
|
|
expect(text).toContain("Claude");
|
|
expect(text).toContain("Gemini");
|
|
expect(text).toContain("Imagen");
|
|
});
|
|
|
|
// #4607:管理端保存的单位是复数(months/weeks),此前用户侧只匹配单数
|
|
// 'month',「1 个月」的套餐卡片被显示成「1天」。测试环境的 vue-i18n 为
|
|
// runtime-only 构建,t() 原样返回 key,故按 key 断言单位分支。
|
|
it("renders plural admin-form validity units instead of mislabeled days (#4607)", () => {
|
|
expect(mountPlanCard("openai", { validity_days: 1, validity_unit: "months" }).text()).toContain("/ payment.perMonth");
|
|
expect(mountPlanCard("openai", { validity_days: 3, validity_unit: "months" }).text()).toContain("/ 3payment.months");
|
|
expect(mountPlanCard("openai", { validity_days: 2, validity_unit: "weeks" }).text()).toContain("/ 2payment.weeks");
|
|
expect(mountPlanCard("openai", { validity_days: 30, validity_unit: "day" }).text()).toContain("/ 30payment.days");
|
|
});
|
|
|
|
it("uses the configured currency symbol while preserving USD for legacy plans", () => {
|
|
const cnyPlan = mountPlanCard("openai", { currency: "CNY", original_price: 20 }).text();
|
|
|
|
expect(cnyPlan).toContain("¥10CNY");
|
|
expect(cnyPlan).toContain("¥20CNY");
|
|
expect(mountPlanCard("openai", { currency: "USD" }).text()).toContain("$10USD");
|
|
expect(mountPlanCard("openai", { currency: "" }).text()).toContain("$10");
|
|
});
|
|
|
|
it.each([
|
|
["long Chinese", "企业全球加速专业订阅套餐(含高级模型与优先支持)"],
|
|
["long English", "Enterprise Global Acceleration Subscription with Priority Support"],
|
|
["unbroken token", "EnterpriseGlobalAccelerationSubscriptionWithPrioritySupport1234567890"],
|
|
])("keeps the full %s plan title accessible in a bounded two-line area", (_label, name) => {
|
|
const wrapper = mountPlanCard("openai", { name });
|
|
const title = wrapper.get("h3");
|
|
|
|
expect(title.text()).toBe(name);
|
|
expect(title.attributes("title")).toBe(name);
|
|
expect(title.classes()).toEqual(expect.arrayContaining([
|
|
"min-w-0",
|
|
"h-12",
|
|
"break-words",
|
|
"line-clamp-2",
|
|
"[overflow-wrap:anywhere]",
|
|
]));
|
|
expect(title.classes()).not.toContain("truncate");
|
|
});
|
|
|
|
it("keeps title, badge, price, description, and purchase action in separate bounded regions", () => {
|
|
const wrapper = mountPlanCard("openai", {
|
|
name: "Enterprise Global Acceleration Subscription with Priority Support",
|
|
price: 123.45,
|
|
currency: "USD",
|
|
description: "Includes advanced models and priority support.",
|
|
});
|
|
const title = wrapper.get("h3");
|
|
const badge = wrapper.findAll("span").find((node) => node.text() === "OpenAI");
|
|
const price = wrapper.findAll("span").find((node) => node.text() === "123.45");
|
|
|
|
expect(title.element.parentElement?.classList).toContain("min-w-0");
|
|
expect(title.element.parentElement?.classList).toContain("flex-1");
|
|
expect(badge?.classes()).toContain("shrink-0");
|
|
expect([...(badge?.element.parentElement?.classList ?? [])]).toEqual(expect.arrayContaining([
|
|
"flex",
|
|
"items-center",
|
|
"justify-end",
|
|
]));
|
|
expect(badge?.element.parentElement?.textContent).toContain("/ 30payment.days");
|
|
expect(badge?.element.parentElement?.parentElement?.classList).toContain("shrink-0");
|
|
expect(price?.element.parentElement?.parentElement?.classList).toContain("shrink-0");
|
|
expect(wrapper.get("p").text()).toBe("Includes advanced models and priority support.");
|
|
expect(wrapper.get("button").text()).toBe("payment.subscribeNow");
|
|
});
|
|
|
|
it("keeps short plan titles compact and aligned", () => {
|
|
const wrapper = mountPlanCard("openai", { name: "Pro", description: "" });
|
|
const title = wrapper.get("h3");
|
|
const badge = wrapper.findAll("span").find((node) => node.text() === "OpenAI");
|
|
|
|
expect(title.text()).toBe("Pro");
|
|
expect(title.attributes("title")).toBe("Pro");
|
|
expect(title.classes()).toEqual(expect.arrayContaining(["text-base", "font-bold", "h-12"]));
|
|
expect([...(badge?.element.parentElement?.classList ?? [])]).toEqual(expect.arrayContaining([
|
|
"flex",
|
|
"items-center",
|
|
"justify-end",
|
|
]));
|
|
expect(badge?.element.parentElement?.textContent).toContain("/ 30payment.days");
|
|
});
|
|
});
|