Files
ttstd-infinite-canvas/web/test/model-picker-prices.test.tsx
ddCat 8b8ea29148 fix(runtime): 运行稳定性 - 修复技能种子、任务续租与回归检查
保留社区技能作者与时间戳修复、Agent 参数约束、资源删除 worker 生命周期、PostgreSQL/Redis 测试门禁及相关回归。

Original-Commit: 0d05ff88bbe6c875d01964041788023a662ff7e8
2026-09-21 09:48:43 +08:00

70 lines
3.7 KiB
TypeScript

import { expect, test } from "bun:test";
import { renderToStaticMarkup } from "react-dom/server";
import { ModelLabel, ModelPicker } from "../src/components/model-picker";
import { canvasThemes } from "../src/lib/canvas-theme";
import { requestCreditCost } from "../src/lib/model-pricing";
import type { ModelRequirements } from "../src/lib/model-selection";
import { createModelChannel, defaultConfig, normalizeConfigSnapshot } from "../src/stores/use-config-store";
function fixture() {
const channel = createModelChannel({
id: "comfy",
name: "Comfy",
scope: "system",
models: ["h3-multi"],
modelCosts: [
{
model: "h3-multi",
displayName: "MiniMax H3",
channelLabel: "多图一致性",
capability: "video",
pricePolicy: "channel",
billingMode: "per_second",
unitPriceMicrocredits: 100_000,
logicalPriceTiers: [480, 720].map((resolution, index) => ({
selector: { vquality: resolution + "p", videoSeconds: "6" },
resolution: resolution + "p",
videoSeconds: 6,
billingMode: "per_second",
unitPriceMicrocredits: (index + 1) * 100_000,
inputTokenPriceMicrocredits: 0,
outputTokenPriceMicrocredits: 0,
cachedTokenPriceMicrocredits: 0,
})),
},
],
});
return normalizeConfigSnapshot({ config: { ...defaultConfig, channels: [channel], model: "comfy::h3-multi", videoModel: "comfy::h3-multi" } }).config;
}
const requirements: ModelRequirements = { capability: "video", videoSeconds: "5", options: { vquality: "1080p" } };
test("candidate rows show their configured prices instead of applying the previous model's specifications", () => {
const config = fixture();
for (const theme of [canvasThemes.light, canvasThemes.dark]) {
const markup = renderToStaticMarkup(<ModelLabel config={config} model={config.model} capability="video" theme={theme} creationVariant showConfiguredModelName={false} requirements={requirements} showPrice showDescription />);
expect(markup).toContain("0.1-0.2 积分/秒");
expect(markup).not.toContain("当前规格无报价");
}
});
test("candidate rows do not disguise missing prices as zero", () => {
const config = fixture();
config.channels[0].modelCosts![0].logicalPriceTiers = [];
const markup = renderToStaticMarkup(<ModelLabel config={config} model={config.model} capability="video" theme={canvasThemes.dark} creationVariant showConfiguredModelName={false} requirements={requirements} showPrice showDescription />);
expect(markup).toContain("未配置");
expect(markup).not.toContain("0 积分");
});
test("the selected model and request estimate still require an exact specification match", () => {
const config = fixture();
const render = (value: ModelRequirements) => renderToStaticMarkup(<ModelPicker config={config} value={config.model} capability="video" requirements={value} onChange={() => {}} />);
expect(render(requirements)).toContain("当前规格无报价");
const cost = (value: ModelRequirements) => requestCreditCost({ channelMode: "remote", modelCosts: config.channels[0].modelCosts, model: "h3-multi", capability: "video", config, requirements: value, seconds: "6" });
expect(cost(requirements)).toBeNull();
const matching = { ...requirements, videoSeconds: "6", options: { vquality: "720p" } };
expect(render(matching)).toContain("0.2 积分/秒");
expect(render(matching)).not.toContain("当前规格无报价");
expect(cost(matching)).toBeCloseTo(1.2);
});