import { describe, expect, test } from "bun:test";
import { createWebVitalsHandler, MetricsRegistry, webVitalsClient } from "../src/index.ts";

describe("@wrnexus/observability", () => {
  test("aggregates browser vitals and flushes them once at page exit", () => {
    const client = webVitalsClient({ sampleRate: 1 });
    expect(client).toContain("var flushed = false");
    expect(client).toContain('addEventListener("pagehide", flush');
    expect(client).not.toContain('send("INP",max)');
    expect(client).not.toContain('send("LCP", last.startTime)');
    expect(client).toContain("web-vitals delivery failed");
    expect(client).toContain("PerformanceObserver unavailable for");
  });

  test("records deterministic counters and histograms", () => {
    const registry = new MetricsRegistry(() => 123);
    registry.increment("requests", 1, { route: "/" });
    registry.increment("requests", 2, { route: "/" });
    registry.observe("duration", 10);
    registry.observe("duration", 20);
    expect(registry.snapshot()).toEqual(
      expect.arrayContaining([
        expect.objectContaining({ name: "requests", value: 3 }),
        expect.objectContaining({ name: "duration", value: 15, count: 2, min: 10, max: 20 }),
      ]),
    );
  });

  test("accepts same-origin Web Vitals and rejects cross-site beacons", async () => {
    const handler = createWebVitalsHandler();
    const good = await handler(
      new Request("https://example.com/__wrnexus/metrics/vitals", {
        method: "POST",
        headers: { origin: "https://example.com", "content-type": "application/json" },
        body: JSON.stringify({ name: "LCP", value: 1200, route: "/" }),
      }),
    );
    expect(good.status).toBe(204);
    const denied = await handler(
      new Request("https://example.com/__wrnexus/metrics/vitals", {
        method: "POST",
        headers: { origin: "https://evil.example", "content-type": "application/json" },
        body: JSON.stringify({ name: "LCP", value: 1200 }),
      }),
    );
    expect(denied.status).toBe(403);
  });
});
