Files
memind/billing.test.mjs
T
John 6d99d762da Add image-designer skill, align billing to DeepSeek ×1, and enrich Plaza demo.
Introduce AI image generation with chat shortcut and agent API, improve MindSpace chat-to-page save resolution, and seed Plaza covers with production deploy scripts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-16 16:29:19 -07:00

96 lines
3.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import test from 'node:test';
import assert from 'node:assert/strict';
import {
computeDeltaCostCents,
loadBillingConfig,
normalizeTokenState,
} from './billing.mjs';
const config = {
useBackendCost: false,
usdCnyRate: 7.2,
inputCentsPer1k: 2,
outputCentsPer1k: 6,
minBillCents: 1,
};
test('loadBillingConfig defaults to DeepSeek Flash × 1 at USD/CNY 7.2', () => {
const savedInput = process.env.H5_BILL_INPUT_CENTS_PER_1K;
const savedOutput = process.env.H5_BILL_OUTPUT_CENTS_PER_1K;
const savedRate = process.env.H5_USD_CNY_RATE;
delete process.env.H5_BILL_INPUT_CENTS_PER_1K;
delete process.env.H5_BILL_OUTPUT_CENTS_PER_1K;
process.env.H5_USD_CNY_RATE = '7.2';
try {
const billing = loadBillingConfig();
assert.ok(Math.abs(billing.inputCentsPer1k - 0.1008) < 1e-9);
assert.ok(Math.abs(billing.outputCentsPer1k - 0.2016) < 1e-9);
} finally {
if (savedInput == null) delete process.env.H5_BILL_INPUT_CENTS_PER_1K;
else process.env.H5_BILL_INPUT_CENTS_PER_1K = savedInput;
if (savedOutput == null) delete process.env.H5_BILL_OUTPUT_CENTS_PER_1K;
else process.env.H5_BILL_OUTPUT_CENTS_PER_1K = savedOutput;
if (savedRate == null) delete process.env.H5_USD_CNY_RATE;
else process.env.H5_USD_CNY_RATE = savedRate;
}
});
test('computeDeltaCostCents bills DeepSeek Flash × 1 defaults with min charge', () => {
const billing = {
useBackendCost: false,
usdCnyRate: 7.2,
inputCentsPer1k: 0.1008,
outputCentsPer1k: 0.2016,
minBillCents: 1,
};
const previous = { lastInputTokens: 0, lastOutputTokens: 0 };
const current = normalizeTokenState({
accumulatedInputTokens: 1000,
accumulatedOutputTokens: 500,
});
assert.equal(computeDeltaCostCents(previous, current, billing), 1);
});
test('normalizeTokenState reads camelCase fields', () => {
const state = normalizeTokenState({
inputTokens: 10,
outputTokens: 20,
accumulatedInputTokens: 100,
accumulatedOutputTokens: 200,
});
assert.equal(state.accumulatedInputTokens, 100);
assert.equal(state.accumulatedOutputTokens, 200);
});
test('computeDeltaCostCents bills token deltas', () => {
const previous = { lastInputTokens: 1000, lastOutputTokens: 500 };
const current = normalizeTokenState({
accumulatedInputTokens: 2000,
accumulatedOutputTokens: 1500,
});
const cost = computeDeltaCostCents(previous, current, config);
assert.equal(cost, 8);
});
test('computeDeltaCostCents returns zero when no usage delta', () => {
const previous = { lastInputTokens: 1000, lastOutputTokens: 500 };
const current = normalizeTokenState({
accumulatedInputTokens: 1000,
accumulatedOutputTokens: 500,
});
assert.equal(computeDeltaCostCents(previous, current, config), 0);
});
test('computeDeltaCostCents ignores backend USD cost unless explicitly enabled', () => {
const previous = { lastInputTokens: 0, lastOutputTokens: 0, lastAccumulatedCost: 0.01 };
const current = normalizeTokenState({
accumulatedInputTokens: 1000,
accumulatedOutputTokens: 500,
accumulatedCost: 0.02,
});
const rmbConfig = { ...config, useBackendCost: false };
assert.equal(computeDeltaCostCents(previous, current, rmbConfig), 5);
const usdConfig = { ...config, useBackendCost: true };
assert.equal(computeDeltaCostCents(previous, current, usdConfig), 8);
});