Initial import of zappier-edge from zapier monorepo
This commit is contained in:
commit
2e035b1e80
128 changed files with 20545 additions and 0 deletions
58
tests/db-billing.test.ts
Normal file
58
tests/db-billing.test.ts
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
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();
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue