129 lines · 4.8 KB
import { beforeEach, describe, expect, mock, test } from "bun:test";
import { fakeStorage } from "./do-test-storage";

mock.module("cloudflare:workers", () => ({
  env: {},
  waitUntil: () => undefined,
  DurableObject: class {
    ctx: unknown;
    env: unknown;
    constructor(ctx: unknown, env: unknown) {
      this.ctx = ctx;
      this.env = env;
    }
  },
}));

let failKeys = new Set<string>();
let flushedKeys: string[] = [];
mock.module("./metering/record", () => ({
  periodOf: () => "2026-10",
  eventStatements: (input: { idempotencyKey: string }) => [{ key: input.idempotencyKey }],
}));
const d1 = {
  first: async () => null,
  stmt: () => ({}),
  batch: async (statements: { key: string }[]) => {
    if (statements.some((statement) => failKeys.has(statement.key))) throw new Error("rejected");
    flushedKeys.push(...statements.map((statement) => statement.key));
    return [];
  },
};
mock.module("./db", () => d1);
// The meter buffer flushes into the billed account's object; the same fake records those batches.
mock.module("./scoped-db", () => ({ accountDb: () => d1, repoDb: () => d1, stmt: d1.stmt }));
mock.module("./repos", () => ({ inboxReadableSql: () => "1", loadRepoById: async () => ({ id: "r1" }) }));
mock.module("./notification-store", () => ({ unreadNotificationCount: async () => 0 }));

let credentialLookups = 0;
let allowed = true;
let live = true;