Files
easyai-ai-gateway/apps/web/src/pages/PlaygroundPage.pricing.test.ts
T
chengcheng 7cea21f765 feat(web): 增加参数即时估价与显式免费编辑
估价请求统一使用 350ms 防抖、AbortController 和请求序号,区分免费、计算中、价格不可用与失败状态,并展示候选冻结上限。价格未就绪时阻止生产提交。\n\n计价规则编辑器新增显式免费开关和 9 位价格步进。\n\n验证:Web 88 项测试和生产构建通过。
2026-07-20 23:22:50 +08:00

50 lines
1.7 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import type { GatewayPricingEstimate } from '@easyai-ai-gateway/contracts';
import {
MEDIA_ESTIMATE_DEBOUNCE_MS,
billingEstimateSignature,
mediaEstimateFromResponse,
} from './PlaygroundPage';
describe('playground pricing estimate', () => {
it('uses the specified 350ms debounce interval', () => {
expect(MEDIA_ESTIMATE_DEBOUNCE_MS).toBe(350);
});
it('only changes its signature for billing-relevant parameters', () => {
const first = billingEstimateSignature({
kind: 'images.generations', model: 'image-model', prompt: 'first',
count: 1, quality: 'high', resolution: '2K',
});
const promptOnly = billingEstimateSignature({
kind: 'images.generations', model: 'image-model', prompt: 'second',
count: 1, quality: 'high', resolution: '2K',
});
const changedCount = billingEstimateSignature({
kind: 'images.generations', model: 'image-model', prompt: 'second',
count: 2, quality: 'high', resolution: '2K',
});
expect(promptOnly).toBe(first);
expect(changedCount).not.toBe(first);
});
it('distinguishes explicit free and exposes the reservation ceiling', () => {
const response: GatewayPricingEstimate = {
candidateCount: 2,
currency: 'resource',
items: [{ amount: 0, currency: 'resource', isFree: true }],
pricingVersion: 'effective-pricing-v2',
requestFingerprint: 'fingerprint',
reservationAmount: 0,
resolver: 'effective-pricing-v2',
totalAmount: 0,
};
expect(mediaEstimateFromResponse(response)).toMatchObject({
amount: 0,
candidateCount: 2,
reservationAmount: 0,
status: 'free',
});
});
});