import { describe, expect, test } from "vitest";
import { renderHook } from "@testing-library/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { http, HttpResponse } from "msw";
import type { ReactNode } from "react";

import { server } from "../test/server";
import { useSetVisibility } from "./queries";

function wrapper({ children }: { children: ReactNode }) {
  const qc = new QueryClient({ defaultOptions: { queries: { retry: false } } });
  return <QueryClientProvider client={qc}>{children}</QueryClientProvider>;
}

describe("useSetVisibility", () => {
  test("POSTs the target visibility and resolves on 204", async () => {
    let body: unknown;
    server.use(
      http.post("/api/admin/objects/:id/visibility", async ({ request }) => {
        body = await request.json();
        return new HttpResponse(null, { status: 204 });
      }),
    );
    const { result } = renderHook(() => useSetVisibility(), { wrapper });
    await result.current.mutateAsync({ id: "o1", visibility: "internal" });
    expect((body as { visibility: string }).visibility).toBe("internal");
  });

  test("throws a status-carrying error on 422 (publish gate)", async () => {
    server.use(
      http.post("/api/admin/objects/:id/visibility", () => new HttpResponse(null, { status: 422 })),
    );
    const { result } = renderHook(() => useSetVisibility(), { wrapper });
    await expect(
      result.current.mutateAsync({ id: "o1", visibility: "public" }),
    ).rejects.toMatchObject({ status: 422 });
  });
});
