/** * Unit tests for API Key utilities * * Note: Testing Convex component packages with convex-test requires special setup. * These tests verify the key format and structure expectations. * Full integration tests should be run in a real Convex deployment. */ import { describe, it, expect } from "vitest"; describe("API Key Format", () => { describe("Key Structure", () => { it("key format should be fb_ followed by 32 hex chars", () => { // Example of expected format const validKeyPattern = /^fb_[a-f0-9]{32}$/; const exampleKey = "fb_0123456789abcdef0123456789abcdef"; expect(exampleKey).toMatch(validKeyPattern); expect(exampleKey.length).toBe(35); // "fb_" (3) + 32 hex chars }); it("key prefix should be fb_ followed by 8 hex chars", () => { const validPrefixPattern = /^fb_[a-f0-9]{8}$/; const examplePrefix = "fb_01234567"; expect(examplePrefix).toMatch(validPrefixPattern); expect(examplePrefix.length).toBe(11); // "fb_" (3) + 8 hex chars }); it("key prefix should be the first 11 chars of the full key", () => { const fullKey = "fb_0123456789abcdef0123456789abcdef"; const expectedPrefix = fullKey.slice(0, 11); expect(expectedPrefix).toBe("fb_01234567"); }); }); describe("Key Hashing", () => { it("SHA-256 hash should produce 64 hex chars", async () => { const key = "fb_0123456789abcdef0123456789abcdef"; const encoder = new TextEncoder(); const data = encoder.encode(key); const hashBuffer = await crypto.subtle.digest("SHA-256", data); const hashArray = Array.from(new Uint8Array(hashBuffer)); const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join(""); expect(hashHex.length).toBe(64); expect(hashHex).toMatch(/^[a-f0-9]{64}$/); }); it("same key should always produce same hash", async () => { const key = "fb_testkey123456789abcdef12345678"; const hash1 = await hashKey(key); const hash2 = await hashKey(key); expect(hash1).toBe(hash2); }); it("different keys should produce different hashes", async () => { const key1 = "fb_testkey123456789abcdef12345678"; const key2 = "fb_testkey123456789abcdef12345679"; const hash1 = await hashKey(key1); const hash2 = await hashKey(key2); expect(hash1).not.toBe(hash2); }); }); }); // Helper function matching the implementation in apiKeys.ts async function hashKey(key: string): Promise { const encoder = new TextEncoder(); const data = encoder.encode(key); const hashBuffer = await crypto.subtle.digest("SHA-256", data); const hashArray = Array.from(new Uint8Array(hashBuffer)); return hashArray.map((b) => b.toString(16).padStart(2, "0")).join(""); }