import { beforeEach, describe, expect, mock, test } from "bun:test";
import type { Viewer } from "~/lib/types";
class StubEntrypoint {}
mock.module("cloudflare:workers", () => ({
env: { PUBLIC_URL: "https://forge.example.com" },
waitUntil: () => undefined,
WorkflowEntrypoint: StubEntrypoint,
DurableObject: StubEntrypoint,
WorkerEntrypoint: StubEntrypoint,
}));
type Member = { userId: string; role: "owner" | "member" };
const users: Record<string, string> = { alice: "u-alice", bob: "u-bob", carol: "u-carol" };
let members: Member[] = [];
let invitations: { userId: string; role: string; invitedBy?: string | null }[] = [];
const d1 = {
first: async (sql: string, ...params: unknown[]) => {
if (sql.includes("kind = 'org'")) return params[0] === "acme" ? { id: "org-acme" } : null;
if (sql.includes("JOIN users u")) {
const id = users[String(params[0])];
return id ? { id } : null;
}
if (sql.includes("COUNT(*) AS count FROM org_invitations")) return { count: invitations.length };
if (sql.includes("COUNT(*)")) {
return { count: members.filter((item) => item.role === "owner" && item.userId !== params[1]).length };
}
if (sql.includes("FROM org_invitations WHERE org_id = ? AND user_id = ?")) {
const row = invitations.find((item) => item.userId === params[1]);
return row ? { role: row.role, invited_by: row.invitedBy ?? null, expires_at: Date.now() + 1000 } : null;
}
if (sql.includes("is_admin = 1")) {
return members.some((item) => item.userId === params[1] && item.role === "owner") ? { ok: 1 } : null;
}
if (sql.includes("SELECT role FROM org_members")) {
const userId = params.length > 1 ? params[1] : params[0];
const row = members.find((item) => item.userId === userId);
return row ? { role: row.role } : null;
}