import { describe, expect, it } from 'vitest' import { formatPrice, formatSubscriptionQuota, normalizeModel, normalizeSubscriptionPlan, providerDistribution, summarizeModels, summarizeSubscriptionPlans, } from './models' describe('models helpers', () => { it('normalizes fallback pricing and stale flags', () => { const model = normalizeModel({ id: 'anthropic/claude-sonnet-4.6', provider_cn: 'Anthropic', context_length: 200000, input_price: '3', output_price: '15', data_confidence: 'stale', }) expect(model).not.toBeNull() expect(model?.providerCN).toBe('Anthropic') expect(model?.inputPrice).toBe(3) expect(model?.outputPrice).toBe(15) expect(model?.stale).toBe(true) expect(model?.pricingAvailable).toBe(true) }) it('marks free models and pricing unavailable correctly', () => { const freeModel = normalizeModel({ id: 'qwen/qwen3-coder:free', }) const paidModel = normalizeModel({ id: 'openai/gpt-4.1', pricing: {}, }) expect(formatPrice(freeModel!, 'input')).toContain('免费') expect(formatPrice(paidModel!, 'input')).toBe('pricing unavailable') }) it('summarizes providers and currencies', () => { const models = [ normalizeModel({ id: 'deepseek/deepseek-chat', provider_cn: 'DeepSeek', currency: 'CNY', pricing: { input: 1, output: 2 } }), normalizeModel({ id: 'deepseek/deepseek-reasoner', provider_cn: 'DeepSeek', currency: 'CNY', pricing: { input: 2, output: 4 } }), normalizeModel({ id: 'anthropic/claude-sonnet-4.6', provider_cn: 'Anthropic', currency: 'USD', pricing: { input: 3, output: 15 } }), ].filter((model): model is NonNullable => model !== null) expect(summarizeModels(models)).toEqual({ modelCount: 3, providerCount: 2, cnyCount: 2, }) expect(providerDistribution(models)).toEqual([ { name: 'DeepSeek', value: 2 }, { name: 'Anthropic', value: 1 }, ]) }) it('normalizes subscription plans from API payload', () => { const plan = normalizeSubscriptionPlan({ planCode: 'token-plan-lite', planName: '通用 Token Plan Lite', planFamily: 'token_plan', tier: 'Lite', provider: 'Tencent', providerCN: '腾讯', operator: 'Tencent Cloud', operatorCN: '腾讯云', currency: 'CNY', listPrice: 39, priceUnit: 'CNY/month', quotaValue: 35000000, quotaUnit: 'tokens/month', contextWindow: 0, modelScope: ['tc-code-latest', 'glm-5', 'glm-5.1'], }) expect(plan).not.toBeNull() expect(plan?.planCode).toBe('token-plan-lite') expect(plan?.providerCN).toBe('腾讯') expect(plan?.modelScope.length).toBe(3) expect(plan?.modelPreview).toBe('tc-code-latest, glm-5, glm-5.1') }) it('formats subscription quotas and summarizes plan stats', () => { const plans = [ normalizeSubscriptionPlan({ planCode: 'token-plan-lite', planName: '通用 Token Plan Lite', providerCN: '腾讯', listPrice: 39, quotaValue: 35000000, quotaUnit: 'tokens/month', modelScope: ['tc-code-latest', 'glm-5', 'glm-5.1'], }), normalizeSubscriptionPlan({ planCode: 'hy-token-plan-max', planName: 'Hy Token Plan Max', providerCN: '腾讯', listPrice: 468, quotaValue: 650000000, quotaUnit: 'tokens/month', contextWindow: 262144, modelScope: ['hy3-preview'], }), ].filter((plan): plan is NonNullable => plan !== null) expect(formatSubscriptionQuota(plans[0].quotaValue, plans[0].quotaUnit)).toBe('3500万 Tokens/月') expect(formatSubscriptionQuota(plans[1].quotaValue, plans[1].quotaUnit)).toBe('6.5亿 Tokens/月') expect(summarizeSubscriptionPlans(plans)).toEqual({ planCount: 2, providerCount: 1, minMonthlyPrice: 39, }) }) })