import { describe, it, expect } from "vitest";
import { z } from "zod";
import { RecordingEventBus } from "@/instrumentation/recording-event-bus";

// Inline a descriptor literal so the test doesn't need to import from
// @repo/core-events (boundary-rule isolation, mirrors recording-tracer test).
const evt = {
  name: "test.evt" as const,
  schema: z.object({ id: z.string() }).strict(),
};

describe("RecordingEventBus", () => {
  it("records every publish call after schema validation", async () => {
    const bus = new RecordingEventBus();
    await bus.publish(evt, { id: "a" });
    await bus.publish(evt, { id: "b" });
    expect(bus.published).toEqual([
      { name: "test.evt", payload: { id: "a" } },
      { name: "test.evt", payload: { id: "b" } },
    ]);
  });

  it("rejects invalid payloads", async () => {
    const bus = new RecordingEventBus();
    await expect(
      bus.publish(evt, { id: 1 } as unknown as { id: string }),
    ).rejects.toThrow();
    expect(bus.published).toHaveLength(0);
  });

  it("invokes registered handlers sequentially in subscription order", async () => {
    const bus = new RecordingEventBus();
    const order: string[] = [];
    bus.subscribe(evt, "consumer-a", async () => {
      order.push("a");
    });
    bus.subscribe(evt, "consumer-b", async () => {
      order.push("b");
    });
    await bus.publish(evt, { id: "x" });
    expect(order).toEqual(["a", "b"]);
  });
});
