// Tests for server/anon-trial.js — focused on getClientIp, which underpins
// the per-IP trial cap. The DB-backed minting paths need a multi-mode SQLite
// handle and are exercised by integration tests; here we lock down that the
// client IP is taken from Express's trust-proxy-resolved req.ip, never from a
// raw client-supplied X-Forwarded-For header.

import { test, describe } from "node:test";
import { strict as assert } from "node:assert";
import { getClientIp } from "../anon-trial.js";

describe("getClientIp", () => {
  test("uses req.ip (Express's trust-proxy-resolved client address)", () => {
    assert.equal(getClientIp({ ip: "203.0.113.7" }), "203.0.113.7");
  });

  test("strips the IPv4-mapped IPv6 prefix", () => {
    assert.equal(getClientIp({ ip: "::ffff:203.0.113.7" }), "203.0.113.7");
  });

  test("falls back to the socket address when req.ip is absent", () => {
    assert.equal(
      getClientIp({ socket: { remoteAddress: "::ffff:198.51.100.9" } }),
      "198.51.100.9",
    );
  });

  test("does NOT trust a raw client-supplied X-Forwarded-For header", () => {
    // Express, not getClientIp, decides the client IP from trust proxy. A
    // header Express hasn't blessed must be ignored — so with no req.ip we
    // fall through to the socket address, never the spoofed header value.
    const spoofed = {
      headers: { "x-forwarded-for": "1.2.3.4" },
      socket: { remoteAddress: "203.0.113.7" },
    };
    assert.equal(getClientIp(spoofed), "203.0.113.7");
  });
});
