86 lines · 3.1 KB
import { beforeEach, describe, expect, mock, test } from "bun:test";

const objects = new Map<string, Uint8Array<ArrayBuffer>>();
const cached = new Map<string, Response>();
const r2Gets: string[] = [];

function r2Object(
  key: string,
  bytes: Uint8Array<ArrayBuffer>,
  range?: { offset?: number; length?: number; suffix?: number },
) {
  let body: Uint8Array<ArrayBuffer> = bytes;
  if (range && "offset" in range)
    body = bytes.slice(range.offset ?? 0, (range.offset ?? 0) + (range.length ?? bytes.length));
  return { key, size: bytes.length, httpEtag: '"abc"', range, body: new Blob([body]).stream() };
}

mock.module("cloudflare:workers", () => ({
  waitUntil: (promise: Promise<unknown>) => void promise,
  env: {
    BUCKET: {
      async get(key: string, options?: { range?: { offset?: number; length?: number } }) {
        r2Gets.push(key);
        const bytes = objects.get(key);
        return bytes ? r2Object(key, bytes, options?.range) : null;
      },
      async head(key: string) {
        const bytes = objects.get(key);
        return bytes ? { key, size: bytes.length, httpEtag: '"abc"' } : null;
      },
    },
  },
}));

(globalThis as unknown as { caches: unknown }).caches = {
  open: async () => ({
    match: async (request: Request) => cached.get(request.url)?.clone(),
    put: async (key: string, response: Response) => void cached.set(key, response),
  }),
};