倍率问题和图片问题调整
This commit is contained in:
1 parent
f1993eb388
commit
3f29ba716a
20 files changed
+1210
-24
No files matched your search
@@ -0,0 +1,113 @@
|
||||
import { createElement } from "react";
|
||||
import { renderToStaticMarkup } from "react-dom/server";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { PriceCatalog } from "@/components/billing-manager";
|
||||
import { groupedPriceRuleSections, priceTierEditTarget } from "@/lib/client/billing-price-catalog";
|
||||
import type { BillingParameterDimension, BillingPriceRule } from "@/lib/types";
|
||||
|
||||
const size: BillingParameterDimension = {
|
||||
key: "size",
|
||||
label: "分辨率",
|
||||
baselineValue: "1.5K",
|
||||
tiers: [
|
||||
{ value: "1.5K", label: "1.5K", standardFactor: 1, markupMultiplier: 1.2, enabled: true },
|
||||
{ value: "2K", label: "2K", standardFactor: 2, markupMultiplier: 1.3, enabled: true }
|
||||
]
|
||||
};
|
||||
|
||||
function rule(id: string, overrides: Partial<BillingPriceRule> = {}): BillingPriceRule {
|
||||
return {
|
||||
id,
|
||||
provider: "seedream",
|
||||
capability: "image.generate",
|
||||
reqKey: "doubao-seedream-5-0-pro-260628",
|
||||
unit: "image",
|
||||
standardUnitPriceFen: 30,
|
||||
markupMultiplier: 1.2,
|
||||
enabled: true,
|
||||
createdAt: "2026-01-01T00:00:00Z",
|
||||
updatedAt: "2026-01-01T00:00:00Z",
|
||||
...overrides
|
||||
};
|
||||
}
|
||||
|
||||
describe("billing price catalog grouped rules", () => {
|
||||
it("keeps separate Seedream businesses and their resolution edit targets", () => {
|
||||
const basic = rule("basic", { parameterDimensions: [size] });
|
||||
const layers = rule("layers", {
|
||||
standardUnitPriceFen: 15,
|
||||
conditions: { layerDecomposition: true },
|
||||
parameterDimensions: [size]
|
||||
});
|
||||
const sections = groupedPriceRuleSections([basic, layers]);
|
||||
expect(sections.map(({ label, dimensions }) => [label, dimensions[0]?.key])).toEqual([
|
||||
["基础生图", "size"],
|
||||
["图层拆分", "size"]
|
||||
]);
|
||||
expect(priceTierEditTarget(sections[1].dimensions[0], size.tiers[1], sections[1].label)).toEqual({
|
||||
dimensionKey: "size",
|
||||
tierValue: "2K",
|
||||
label: "图层拆分 · 分辨率 · 2K",
|
||||
markupMultiplier: 1.3
|
||||
});
|
||||
|
||||
expect(sections[0].rule.id).toBe("basic");
|
||||
expect(sections[1].rule.id).toBe("layers");
|
||||
expect(sections.map((section) => section.dimensions[0].tiers.map((tier) => tier.value))).toEqual([
|
||||
["1.5K", "2K"],
|
||||
["1.5K", "2K"]
|
||||
]);
|
||||
const html = renderToStaticMarkup(createElement(PriceCatalog, { rules: [basic, layers], onEdit: () => {}, disabled: false }));
|
||||
expect(html).toContain("基础生图 · 分辨率");
|
||||
expect(html).toContain("图层拆分 · 分辨率");
|
||||
expect(html.match(/>调整倍率<\/button>/g)).toHaveLength(4);
|
||||
expect(html).toContain("¥0.15");
|
||||
expect(html).toContain("¥0.30");
|
||||
});
|
||||
|
||||
it("keeps grouped legacy video rules as independent flat rows", () => {
|
||||
const rules = [
|
||||
rule("720p", { provider: "seedance", capability: "video.generate", reqKey: "seedance-2.0", variantKey: "resolution=720p", unit: "video_second", standardUnitPriceFen: 99 }),
|
||||
rule("1080p", { provider: "seedance", capability: "video.generate", reqKey: "seedance-2.0", variantKey: "resolution=1080p", unit: "video_second", standardUnitPriceFen: 248 })
|
||||
];
|
||||
expect(groupedPriceRuleSections(rules).every((section) => section.dimensions.length === 0)).toBe(true);
|
||||
expect(groupedPriceRuleSections(rules).map((section) => section.label)).toEqual(["resolution=720p", "resolution=1080p"]);
|
||||
const html = renderToStaticMarkup(createElement(PriceCatalog, { rules, onEdit: () => {}, disabled: false }));
|
||||
expect(html).toContain("resolution=720p");
|
||||
expect(html).toContain("resolution=1080p");
|
||||
expect(html.match(/>调整倍率<\/button>/g)).toHaveLength(2);
|
||||
});
|
||||
|
||||
it("retains unnamed dimension and tier identifiers in edit labels", () => {
|
||||
const dimension: BillingParameterDimension = {
|
||||
key: "quality",
|
||||
label: "",
|
||||
baselineValue: "medium",
|
||||
tiers: [{ value: "high", label: "", standardFactor: 1, markupMultiplier: 1.25, enabled: true }]
|
||||
};
|
||||
expect(priceTierEditTarget(dimension, dimension.tiers[0])).toEqual({
|
||||
dimensionKey: "quality",
|
||||
tierValue: "high",
|
||||
label: "quality · high",
|
||||
markupMultiplier: 1.25
|
||||
});
|
||||
const single = rule("evolink", {
|
||||
provider: "evolink",
|
||||
reqKey: "gpt-image-2",
|
||||
parameterDimensions: [dimension]
|
||||
});
|
||||
const singleHtml = renderToStaticMarkup(createElement(PriceCatalog, { rules: [single], onEdit: () => {}, disabled: false }));
|
||||
expect(singleHtml).toContain(">quality</strong>");
|
||||
expect(singleHtml).toContain(">high</strong>");
|
||||
expect(singleHtml.match(/>调整倍率<\/button>/g)).toHaveLength(1);
|
||||
|
||||
const mixedHtml = renderToStaticMarkup(createElement(PriceCatalog, {
|
||||
rules: [single, rule("legacy", { provider: "evolink", reqKey: "gpt-image-2", variantKey: "legacy" })],
|
||||
onEdit: () => {},
|
||||
disabled: false
|
||||
}));
|
||||
expect(mixedHtml).toContain("规则 1 · quality</strong>");
|
||||
expect(mixedHtml).toContain("legacy");
|
||||
expect(mixedHtml.match(/>调整倍率<\/button>/g)).toHaveLength(2);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user