/**
 * 指示書I 段階1 の `verifyToken()` 期待値表をそのまま固定したテスト。
 */
import { describe, expect, it } from "vitest";
import { verifyToken } from "@/lib/auth/token";

describe("verifyToken() — 定数時間比較", () => {
  const cases: Array<{
    input: string;
    expected: string | undefined;
    result: boolean;
    note: string;
  }> = [
    { input: "abc", expected: "abc", result: true, note: "一致" },
    { input: "abc", expected: "abd", result: false, note: "不一致" },
    {
      input: "abc",
      expected: "abcd",
      result: false,
      note: "★長さ違いで例外を投げないこと（timingSafeEqual は長さが違うと throw する）★",
    },
    { input: "", expected: "abc", result: false, note: "空入力" },
    {
      input: "abc",
      expected: "",
      result: false,
      note: "★AUTH_TOKEN が未設定なら誰も通さない（空を『何でも通す』にしない）★",
    },
    {
      input: "abc",
      expected: undefined,
      result: false,
      note: "★同上（未設定）★",
    },
  ];

  for (const c of cases) {
    it(`input=${JSON.stringify(c.input)} / expected=${JSON.stringify(
      c.expected
    )} → ${c.result}（${c.note}）`, () => {
      expect(verifyToken(c.input, c.expected)).toBe(c.result);
    });
  }

  it("★長さ違いでも例外を投げない★（明示。ここが壊れると 500 になる）", () => {
    expect(() => verifyToken("a", "aaaaaaaaaaaaaaaaaaaa")).not.toThrow();
    expect(() => verifyToken("aaaaaaaaaaaaaaaaaaaa", "a")).not.toThrow();
    expect(verifyToken("a", "aaaaaaaaaaaaaaaaaaaa")).toBe(false);
  });

  it("input が null / undefined でも false", () => {
    expect(verifyToken(null, "abc")).toBe(false);
    expect(verifyToken(undefined, "abc")).toBe(false);
  });

  it("両方 undefined でも false（★全公開にならないこと★）", () => {
    expect(verifyToken(undefined, undefined)).toBe(false);
  });

  it("マルチバイト文字を含むトークンでも一致・不一致が正しい", () => {
    expect(verifyToken("トークンあ", "トークンあ")).toBe(true);
    expect(verifyToken("トークンあ", "トークンい")).toBe(false);
  });

  it("長いトークンの一致", () => {
    const token = "x".repeat(64);
    expect(verifyToken(token, token)).toBe(true);
    expect(verifyToken(token, "x".repeat(63) + "y")).toBe(false);
  });
});
