import { afterEach, expect, test } from "bun:test";
import { s3Driver } from "../src/index.ts";

const originalFetch = globalThis.fetch;
afterEach(() => {
  globalThis.fetch = originalFetch;
});

const config = {
  driver: "s3" as const,
  access: "public" as const,
  bucket: "bucket",
  region: "auto",
  accessKeyId: "key",
  secretAccessKey: "secret",
  endpoint: "https://storage.example.com/base/",
};

test("S3 driver preserves endpoint path prefixes and signs encoded keys", async () => {
  let url = "";
  let init: RequestInit | undefined;
  globalThis.fetch = (async (input: string | URL | Request, options?: RequestInit) => {
    url = String(input);
    init = options;
    return new Response(null, { status: 204 });
  }) as unknown as typeof fetch;
  await s3Driver(config).put("folder/a b.txt", new TextEncoder().encode("x"), {
    contentType: "text/plain",
  });
  expect(url).toBe("https://storage.example.com/base/bucket/folder/a%20b.txt");
  expect(new Headers(init?.headers).get("authorization")).toStartWith("AWS4-HMAC-SHA256");
});

test("S3 driver rejects unsafe configuration early", () => {
  expect(() => s3Driver({ ...config, bucket: "../bucket" })).toThrow("bucket");
  expect(() => s3Driver({ ...config, endpoint: "ftp://storage.example.com" })).toThrow(
    "http or https",
  );
  expect(() =>
    s3Driver({ ...config, endpoint: "https://storage.example.com/base", forcePathStyle: false }),
  ).toThrow("path prefix");
});
