Files
0pt/tests/document-workbench/price-book.test.ts
T

50 lines
1.9 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import {
creditsForUsage,
findPack,
parseCreditPriceBook,
readCreditPriceBook,
} from '../../src/document-workbench/price-book';
const valid = {
version: '2026-11-01',
currency: 'SEK',
packs: [
{ id: 'starter', credits: 100, amountMinor: 9900 },
{ id: 'pro', credits: 2000, amountMinor: 129900 },
],
metering: { pagesPerCredit: 5, inputTokensPerCredit: 20000, outputTokensPerCredit: 4000 },
};
describe('credit price book', () => {
it('parses a valid server-owned price book', () => {
const book = parseCreditPriceBook(valid);
expect(book.packs).toHaveLength(2);
expect(findPack(book, 'pro')?.credits).toBe(2000);
});
it('fails closed when the env price book is absent or invalid', () => {
expect(readCreditPriceBook({} as unknown as NodeJS.ProcessEnv)).toBeUndefined();
expect(readCreditPriceBook({ OPT_CREDIT_PRICE_BOOK: '{not json' } as unknown as NodeJS.ProcessEnv)).toBeUndefined();
expect(
readCreditPriceBook({
OPT_CREDIT_PRICE_BOOK: JSON.stringify({ ...valid, currency: 'sek' }),
} as unknown as NodeJS.ProcessEnv),
).toBeUndefined();
});
it('rejects duplicate pack ids, unknown currencies and non-integer money', () => {
expect(() => parseCreditPriceBook({ ...valid, packs: [valid.packs[0], valid.packs[0]] })).toThrow();
expect(() =>
parseCreditPriceBook({ ...valid, packs: [{ id: 'x', credits: 1, amountMinor: 1.5 }] }),
).toThrow();
});
it('rounds every metered component up to its billing block', () => {
const book = parseCreditPriceBook(valid);
expect(creditsForUsage(book, { pages: 0, inputTokens: 0, outputTokens: 0 })).toBe(0);
expect(creditsForUsage(book, { pages: 1, inputTokens: 1, outputTokens: 1 })).toBe(3);
expect(creditsForUsage(book, { pages: 6, inputTokens: 40001, outputTokens: 8001 })).toBe(8);
});
});