import { describe, it, expect, vi } from "vitest";
import { withSecurityHeaders } from "@/security/tanstack/middleware";

const ALL_SIX_HEADERS = [
  "Strict-Transport-Security",
  "X-Frame-Options",
  "X-Content-Type-Options",
  "Referrer-Policy",
  "Permissions-Policy",
  "Content-Security-Policy",
] as const;

describe("withSecurityHeaders", () => {
  it("returns all six security headers", () => {
    const { headers } = withSecurityHeaders();

    for (const header of ALL_SIX_HEADERS) {
      expect(headers).toHaveProperty(header);
    }
  });

  it("returns x-nonce in headers equal to the returned nonce", () => {
    const { headers, nonce } = withSecurityHeaders();

    expect(headers["x-nonce"]).toBe(nonce);
    expect(typeof nonce).toBe("string");
    expect(nonce.length).toBeGreaterThan(0);
  });

  it("nonce in x-nonce matches nonce threaded into CSP in production mode", () => {
    vi.stubEnv("NODE_ENV", "production");

    const { headers, nonce } = withSecurityHeaders();

    expect(headers["Content-Security-Policy"]).toContain(`'nonce-${nonce}'`);
  });

  it("uses dev-mode CSP when NODE_ENV is not production", () => {
    vi.stubEnv("NODE_ENV", "test");

    const { headers } = withSecurityHeaders();

    expect(headers["Content-Security-Policy"]).toContain("'unsafe-inline'");
  });

  it("each call produces a unique nonce", () => {
    const a = withSecurityHeaders();
    const b = withSecurityHeaders();

    expect(a.nonce).not.toBe(b.nonce);
  });
});
