import type { createClient } from '@supabase/supabase-js' import { checkQuota, consumeQuota } from './quota.ts' import { isQuotaAllowed, parseQuotaConsumeResponse, quotaWindowStart } from './quota-policy.ts' function assert(condition: boolean, message: string): asserts condition { if (!condition) throw new Error(message) } type Row = Record type ServiceClient = ReturnType /** Minimal in-memory stand-in for the supabase-js query builder used by quota.ts. */ class FakeQuery implements PromiseLike<{ data: unknown; error: null }> { private filters: Array<(row: Row) => boolean> = [] private singleRow = false constructor(private rows: Row[]) {} select(_columns: string): this { return this } eq(column: string, value: unknown): this { this.filters.push((row) => row[column] === value) return this } gte(column: string, value: string): this { this.filters.push((row) => String(row[column]) >= value) return this } lte(column: string, value: string): this { this.filters.push((row) => String(row[column]) <= value) return this } single(): this { this.singleRow = true return this } then( onfulfilled?: ((value: { data: unknown; error: null }) => T1 | PromiseLike) | null, onrejected?: ((reason: unknown) => T2 | PromiseLike) | null, ): PromiseLike { const matched = this.rows.filter((row) => this.filters.every((f) => f(row))) const data = this.singleRow ? (matched[0] ?? null) : matched return Promise.resolve({ data, error: null }).then(onfulfilled, onrejected) } } class FakeQuotaClient { tables: Record = { subscriptions: [], daily_usage: [] } rpcCalls: Array<{ name: string; args: Record }> = [] rpcResult: unknown = { allowed: true, current: 1, limit: 250, overage_credits: 0, consumed_from: 'overage', } from(table: string): FakeQuery { return new FakeQuery(this.tables[table] ?? []) } rpc(name: string, args: Record): Promise<{ data: unknown; error: null }> { this.rpcCalls.push({ name, args }) return Promise.resolve({ data: this.rpcResult, error: null }) } asClient(): ServiceClient { return this as unknown as ServiceClient } } const NOW = new Date('2026-09-28T12:00:00Z') const USER = 'user-1' function freeUserWithUsage(rows: Array<[string, number]>, overageCredits = 0): FakeQuotaClient { const client = new FakeQuotaClient() client.tables.subscriptions.push({ user_id: USER, tier: 'free', overage_credits: overageCredits }) for (const [date, count] of rows) { client.tables.daily_usage.push({ user_id: USER, feature: 'llm_haiku', date, count }) } return client } Deno.test('weekly window is today-6..today (7 calendar days), same as the SQL quota functions', () => { assert(quotaWindowStart('weekly', NOW) === '2026-09-22', `weekly start ${quotaWindowStart('weekly', NOW)}`) assert(quotaWindowStart('daily', NOW) === '2026-09-28', 'daily start is today') // Month boundary in UTC. assert(quotaWindowStart('weekly', new Date('2026-10-03T00:30:00Z')) === '2026-09-27', 'month rollover') }) Deno.test('usage from 7 days ago no longer blocks a free user (8-day window regression)', async () => { const client = freeUserWithUsage([['2026-09-21', 250], ['2026-09-27', 10]]) const check = await checkQuota(USER, 'llm_haiku', client.asClient(), NOW) assert(check.current === 10, `stale usage counted: current=${check.current}`) assert(check.allowed, 'free user blocked by usage that already rolled off') assert(check.period === 'weekly' && check.limit === 250, 'free haiku policy') }) Deno.test('250 uses spread across 6 days reach the weekly limit; a credit keeps the call allowed', async () => { const days: Array<[string, number]> = [ ['2026-09-22', 45], ['2026-09-23', 41], ['2026-09-24', 41], ['2026-09-25', 41], ['2026-09-26', 41], ['2026-09-27', 41], ] const noCredit = await checkQuota(USER, 'llm_haiku', freeUserWithUsage(days).asClient(), NOW) assert(noCredit.current === 250 && !noCredit.allowed, `limit not enforced: ${JSON.stringify(noCredit)}`) const withCredit = await checkQuota(USER, 'llm_haiku', freeUserWithUsage(days, 1).asClient(), NOW) assert(withCredit.allowed && withCredit.overageCredits === 1, 'credit should allow the call') }) Deno.test('consumeQuota asks the RPC to consume over the policy period', async () => { const client = freeUserWithUsage([]) const result = await consumeQuota(USER, 'llm_haiku', client.asClient(), 250) const call = client.rpcCalls[0] assert(call?.name === 'consume_quota', 'consume_quota not called') assert(call.args.p_period === 'weekly', `free haiku must consume weekly, got ${String(call.args.p_period)}`) assert(call.args.p_base_limit === 250 && call.args.p_feature === 'llm_haiku', 'limit/feature passed through') assert(result.consumedFrom === 'overage' && result.overageCredits === 0, 'response mapped') const explicit = new FakeQuotaClient() await consumeQuota(USER, 'realtime_session', explicit.asClient(), 30, 'daily') assert(explicit.rpcCalls[0]?.args.p_period === 'daily', 'explicit period passed as-is') }) Deno.test('paid daily policies consume over a daily window', async () => { const client = new FakeQuotaClient() client.tables.subscriptions.push({ user_id: USER, tier: 'pro', overage_credits: 0 }) await consumeQuota(USER, 'llm_sonnet', client.asClient(), 300) assert(client.rpcCalls[0]?.args.p_period === 'daily', 'pro sonnet is daily') }) Deno.test('allow decision: 0 = unavailable even with credits, -1 = unlimited, credits extend the base', () => { assert(!isQuotaAllowed(0, 0, 5), 'unavailable feature allowed by credits') assert(isQuotaAllowed(-1, 10_000, 0), 'unlimited denied') assert(isQuotaAllowed(250, 249, 0), 'under limit denied') assert(!isQuotaAllowed(250, 250, 0), 'at limit without credit allowed') assert(isQuotaAllowed(250, 250, 1), 'at limit with credit denied') }) Deno.test('RPC response parser rejects malformed payloads', () => { const ok = parseQuotaConsumeResponse({ allowed: false, current: 250, limit: 250, overage_credits: 0, consumed_from: 'none', }) assert(!ok.allowed && ok.consumedFrom === 'none' && ok.current === 250, 'valid payload mapped') for (const bad of [null, [], { allowed: true }, { allowed: true, current: 1, limit: 1, overage_credits: 0, consumed_from: 'bogus', }]) { let threw = false try { parseQuotaConsumeResponse(bad) } catch { threw = true } assert(threw, `accepted ${JSON.stringify(bad)}`) } })