/** * Tests for state utility functions */ import { generateState, generateSessionId, generateNonce, validateState } from "../../src/utils/state-utils"; describe("state-utils", () => { describe("generateState", () => { it("should generate a random state string", () => { const state = generateState(); expect(state).toBeDefined(); expect(typeof state).toBe("string"); expect(state.length).toBeGreaterThan(0); }); it("should generate unique state values", () => { const state1 = generateState(); const state2 = generateState(); expect(state1).not.toBe(state2); }); it("should generate state with sufficient entropy (64 hex chars = 32 bytes)", () => { const state = generateState(); expect(state.length).toBe(64); expect(state).toMatch(/^[a-f0-9]{64}$/); }); }); describe("generateSessionId", () => { it("should generate a random session ID", () => { const sessionId = generateSessionId(); expect(sessionId).toBeDefined(); expect(typeof sessionId).toBe("string"); expect(sessionId.length).toBeGreaterThan(0); }); it("should generate unique session IDs", () => { const id1 = generateSessionId(); const id2 = generateSessionId(); expect(id1).not.toBe(id2); }); it("should generate session ID with sufficient entropy", () => { const sessionId = generateSessionId(); expect(sessionId.length).toBe(32); expect(sessionId).toMatch(/^[a-f0-9]{32}$/); }); }); describe("generateNonce", () => { it("should generate a random nonce", () => { const nonce = generateNonce(); expect(nonce).toBeDefined(); expect(typeof nonce).toBe("string"); expect(nonce.length).toBeGreaterThan(0); }); it("should generate unique nonces", () => { const nonce1 = generateNonce(); const nonce2 = generateNonce(); expect(nonce1).not.toBe(nonce2); }); it("should generate nonce with sufficient entropy", () => { const nonce = generateNonce(); expect(nonce.length).toBe(32); expect(nonce).toMatch(/^[a-f0-9]{32}$/); }); }); describe("validateState", () => { it("should return true for matching states", () => { const state = generateState(); const result = validateState(state, state); expect(result).toBe(true); }); it("should return false for non-matching states", () => { const state1 = generateState(); const state2 = generateState(); const result = validateState(state1, state2); expect(result).toBe(false); }); it("should use constant-time comparison to prevent timing attacks", () => { const state = "a".repeat(64); const wrongState1 = "b".repeat(64); const wrongState2 = "a".repeat(63) + "b"; // Both should return false expect(validateState(wrongState1, state)).toBe(false); expect(validateState(wrongState2, state)).toBe(false); }); it("should handle empty strings", () => { expect(validateState("", "")).toBe(false); expect(validateState("abc", "")).toBe(false); expect(validateState("", "abc")).toBe(false); }); }); });