zappier-edge/tests/db-billing.test.ts

58 lines
2.5 KiB
TypeScript

import Database from 'better-sqlite3';
import { SqliteBillingReportRepo } from '../src/db/billing-repo';
describe('SqliteBillingReportRepo', () => {
it('returns 0 for an unknown customer/period', () => {
const repo = new SqliteBillingReportRepo(new Database(':memory:'));
expect(repo.getReportedCents('cust_1', '2026-07')).toBe(0);
});
it('round-trips an upserted cumulative value', () => {
const repo = new SqliteBillingReportRepo(new Database(':memory:'));
repo.upsertReportedCents('cust_1', '2026-07', 500);
expect(repo.getReportedCents('cust_1', '2026-07')).toBe(500);
});
it('keeps periods and customers isolated', () => {
const repo = new SqliteBillingReportRepo(new Database(':memory:'));
repo.upsertReportedCents('cust_1', '2026-07', 500);
expect(repo.getReportedCents('cust_1', '2026-08')).toBe(0);
expect(repo.getReportedCents('cust_2', '2026-07')).toBe(0);
});
it('replaces the cumulative value on repeated upsert (latest wins, not summed)', () => {
const repo = new SqliteBillingReportRepo(new Database(':memory:'));
repo.upsertReportedCents('cust_1', '2026-07', 500);
repo.upsertReportedCents('cust_1', '2026-07', 800);
expect(repo.getReportedCents('cust_1', '2026-07')).toBe(800);
});
describe('job locks', () => {
it('acquires a free lock and refuses a second acquire until released', () => {
const repo = new SqliteBillingReportRepo(new Database(':memory:'));
expect(repo.tryAcquireLock('report-usage', 60_000)).toBe(true);
expect(repo.tryAcquireLock('report-usage', 60_000)).toBe(false);
repo.releaseLock('report-usage');
expect(repo.tryAcquireLock('report-usage', 60_000)).toBe(true);
});
it('takes over a lock whose age exceeds the TTL', () => {
let nowMs = 1_000_000;
const repo = new SqliteBillingReportRepo(new Database(':memory:'), () => nowMs);
expect(repo.tryAcquireLock('report-usage', 60_000)).toBe(true);
nowMs += 60_001; // lock is now stale
expect(repo.tryAcquireLock('report-usage', 60_000)).toBe(true);
});
it('keeps lock names independent', () => {
const repo = new SqliteBillingReportRepo(new Database(':memory:'));
expect(repo.tryAcquireLock('report-usage', 60_000)).toBe(true);
expect(repo.tryAcquireLock('other-job', 60_000)).toBe(true);
});
it('releaseLock is a no-op for a lock that was never held', () => {
const repo = new SqliteBillingReportRepo(new Database(':memory:'));
expect(() => repo.releaseLock('never-held')).not.toThrow();
});
});
});