import { describe, it, expect } from "vitest" import { signToken, verifyToken } from "@/lib/jwt" process.env.JWT_SECRET = "test-secret-that-is-at-least-32-chars-long-for-security" describe("JWT", () => { it("signs and verifies a valid token", async () => { const token = await signToken({ userId: "user-1", role: "admin" }) expect(token).toBeTruthy() expect(typeof token).toBe("string") const payload = await verifyToken(token) expect(payload).not.toBeNull() expect(payload!.userId).toBe("user-1") expect(payload!.role).toBe("admin") }) it("rejects a tampered token", async () => { const token = await signToken({ userId: "user-1", role: "admin" }) const tampered = token.slice(0, -5) + "XXXXX" const payload = await verifyToken(tampered) expect(payload).toBeNull() }) it("rejects an expired token", async () => { const { SignJWT } = await import("jose") const { getJWTSecret } = await import("@/lib/jwt") const expiredToken = await new SignJWT({ userId: "user-1", role: "admin" }) .setProtectedHeader({ alg: "HS256" }) .setExpirationTime("0s") .sign(getJWTSecret()) const payload = await verifyToken(expiredToken) expect(payload).toBeNull() }) it("rejects a token with invalid signature", async () => { const { SignJWT } = await import("jose") const wrongSecret = new TextEncoder().encode("different-secret-key-for-signing-purposes-only") const token = await new SignJWT({ userId: "user-1", role: "admin" }) .setProtectedHeader({ alg: "HS256" }) .setExpirationTime("24h") .setIssuedAt() .sign(wrongSecret) const payload = await verifyToken(token) expect(payload).toBeNull() }) it("returns null for empty token", async () => { const payload = await verifyToken("") expect(payload).toBeNull() }) it("returns null for garbage token", async () => { const payload = await verifyToken("this.is.not.a.jwt") expect(payload).toBeNull() }) })