import { describe, expect, it, vi } from "vitest";
import { createRecycleBinApi } from "../recycleBinApi";
import {
  jsonResult,
  recycleItem,
  restoreResult,
} from "./fixtures";

const page = {
  items: [recycleItem],
  page: 1,
  pageSize: 20,
  total: 1,
  totalPages: 1,
};

describe("recycleBinApi", () => {
  it("GET recycle-bin/documents透传全部正式查询参数", async () => {
    const client = { get: vi.fn().mockResolvedValue(jsonResult(page)) };
    const query = {
      keyword: "F8",
      documentType: "MAIN" as const,
      categoryId: "1",
      deletedFrom: "2026-07-01T00:00:00.000Z",
      deletedTo: "2026-08-01T00:00:00.000Z",
      page: 2,
      pageSize: 50,
      sortField: "documentName" as const,
      sortDirection: "asc" as const,
    };
    const signal = new AbortController().signal;
    await createRecycleBinApi(client as never).list(query, signal);
    expect(client.get).toHaveBeenCalledWith("recycle-bin/documents", {
      query,
      signal,
    });
    expect(client.get.mock.calls[0][0]).not.toContain("/api/v1");
  });

  it("POST正式恢复路径且请求体只有rowVersion", async () => {
    const client = {
      post: vi.fn().mockResolvedValue(jsonResult(restoreResult)),
    };
    const response = await createRecycleBinApi(client as never).restore(
      "10",
      { rowVersion: 12 },
    );
    expect(response.data).toEqual(restoreResult);
    expect(client.post).toHaveBeenCalledWith(
      "recycle-bin/documents/10/restore",
      { rowVersion: 12 },
      { signal: undefined },
    );
    expect(client.post).toHaveBeenCalledTimes(1);
  });

  it("拒绝number ID、负数版本和额外请求字段", async () => {
    const client = { post: vi.fn() };
    const api = createRecycleBinApi(client as never);
    await expect(
      api.restore(10 as never, { rowVersion: 1 }),
    ).rejects.toThrow("字符串");
    await expect(api.restore("10", { rowVersion: -1 })).rejects.toThrow(
      "不符合",
    );
    await expect(
      api.restore("10", {
        rowVersion: 1,
        documentType: "MAIN",
      } as never),
    ).rejects.toThrow("不符合");
    expect(client.post).not.toHaveBeenCalled();
  });

  it("DTO错误保留requestId且不伪造成功", async () => {
    const client = {
      post: vi
        .fn()
        .mockResolvedValue(
          jsonResult({ ...restoreResult, skippedBindingCount: "1" }),
        ),
    };
    await expect(
      createRecycleBinApi(client as never).restore("10", {
        rowVersion: 12,
      }),
    ).rejects.toMatchObject({
      code: "INTERNAL_ERROR",
      requestId: "60980159-8fb2-4ca2-95fc-9bc5ce6b3ce1",
    });
  });
});

