import { describe, it, expect } from "vitest";
import type { SanitizedConfig } from "payload";
import { bindProductionDsr } from "@/di/bind-production";
import { bindDevSeedDsr } from "@/di/bind-dev-seed";

const emptyConfig = { collections: [] } as unknown as SanitizedConfig;

describe("bindProductionDsr", () => {
  it("returns a DsrBinding with all four implementations", () => {
    const binding = bindProductionDsr({ config: emptyConfig });

    expect(binding.dataExport).toBeDefined();
    expect(binding.dataDelete).toBeDefined();
    expect(binding.dataRectify).toBeDefined();
    expect(binding.processingRestriction).toBeDefined();
  });

  it("each binding exposes the expected interface methods", () => {
    const binding = bindProductionDsr({ config: emptyConfig });

    expect(typeof binding.dataExport.exportSubjectData).toBe("function");
    expect(typeof binding.dataDelete.deleteSubjectData).toBe("function");
    expect(typeof binding.dataRectify.updateSubjectField).toBe("function");
    expect(typeof binding.processingRestriction.setRestriction).toBe(
      "function",
    );
    expect(typeof binding.processingRestriction.isRestricted).toBe("function");
  });

  it("uses the noop auditLog when none is provided", () => {
    expect(() => bindProductionDsr({ config: emptyConfig })).not.toThrow();
  });
});

describe("bindDevSeedDsr", () => {
  it("returns a DsrBinding with all four in-memory implementations", () => {
    const binding = bindDevSeedDsr();

    expect(binding.dataExport).toBeDefined();
    expect(binding.dataDelete).toBeDefined();
    expect(binding.dataRectify).toBeDefined();
    expect(binding.processingRestriction).toBeDefined();
  });

  it("each binding exposes the expected interface methods", () => {
    const binding = bindDevSeedDsr();

    expect(typeof binding.dataExport.exportSubjectData).toBe("function");
    expect(typeof binding.dataDelete.deleteSubjectData).toBe("function");
    expect(typeof binding.dataRectify.updateSubjectField).toBe("function");
    expect(typeof binding.processingRestriction.setRestriction).toBe(
      "function",
    );
    expect(typeof binding.processingRestriction.isRestricted).toBe("function");
  });
});
