import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import {
  decodeToken,
  signToken,
  verifyToken,
} from "@/modules/auth/jwt";

describe("modules/auth/jwt", () => {
  beforeEach(() => {
    process.env.JWT_SECRET = "test-jwt-secret-for-unit-tests";
  });

  it("签发后校验通过", async () => {
    const token = await signToken({ sub: "ADMIN_001", role: "admin" });
    const payload = await verifyToken(token);
    expect(payload).toEqual({ sub: "ADMIN_001", role: "admin" });
  });

  it("篡改 token 后校验失败", async () => {
    const token = await signToken({ sub: "ADMIN_001", role: "admin" });
    const tampered = `${token.slice(0, -4)}xxxx`;
    await expect(verifyToken(tampered)).rejects.toMatchObject({
      code: "UNAUTHORIZED",
    });
  });

  it("过期 token 校验失败", async () => {
    const { SignJWT } = await import("jose");
    const secret = new TextEncoder().encode(process.env.JWT_SECRET);
    const expired = await new SignJWT({ role: "admin" })
      .setProtectedHeader({ alg: "HS256" })
      .setSubject("ADMIN_001")
      .setIssuedAt(Math.floor(Date.now() / 1000) - 7200)
      .setExpirationTime(Math.floor(Date.now() / 1000) - 3600)
      .sign(secret);

    await expect(verifyToken(expired)).rejects.toMatchObject({
      code: "UNAUTHORIZED",
    });
  });

  it("decodeToken 可解析有效载荷", async () => {
    const token = await signToken({ sub: "ADMIN_001", role: "admin" });
    expect(decodeToken(token)).toEqual({ sub: "ADMIN_001", role: "admin" });
  });
});
