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

test("GraphQL handler enforces method, introspection and complexity limits", async () => {
  const handler = createGraphqlHandler({
    allowIntrospection: false,
    maxDepth: 2,
    execute: async () => ({ data: { ok: true } }),
  });
  expect((await handler(new Request("https://test/graphql"))).status).toBe(405);
  expect(
    (
      await handler(
        new Request("https://test/graphql", {
          method: "POST",
          body: JSON.stringify({ query: "{ __schema { types { name } } }" }),
        }),
      )
    ).status,
  ).toBe(403);
  expect(
    (
      await handler(
        new Request("https://test/graphql", {
          method: "POST",
          body: JSON.stringify({ query: "{ a { b { c } } }" }),
        }),
      )
    ).status,
  ).toBe(400);
});

test("GraphQL handler delegates valid requests and hides thrown errors", async () => {
  const handler = createGraphqlHandler({
    execute: async (request) => ({ data: { query: request.query } }),
  });
  const response = await handler(
    new Request("https://test/graphql", {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ query: "{ health }" }),
    }),
  );
  expect(response.status).toBe(200);
  expect(await response.json()).toEqual({ data: { query: "{ health }" } });
  const failing = createGraphqlHandler({
    execute: async () => {
      throw new Error("secret");
    },
  });
  expect(
    await (
      await failing(
        new Request("https://test/graphql", {
          method: "POST",
          body: JSON.stringify({ query: "{ health }" }),
        }),
      )
    ).text(),
  ).not.toContain("secret");
});
