import { describe, test, expect } from 'bun:test'; import * as fc from 'fast-check'; import { generateRequestId, generateIdempotencyKey, base64UrlEncode, base64UrlDecode, RequestIdSchema, } from '../../src/index.js'; describe('generateRequestId', () => { test('produces 22-char base64url string', () => { const id = generateRequestId(); expect(id.length).toBe(22); expect(RequestIdSchema.safeParse(id).success).toBe(true); }); test('1e5 generated IDs are all unique', () => { const seen = new Set(); for (let i = 0; i < 100_000; i++) { const id = generateRequestId(); expect(seen.has(id)).toBe(false); seen.add(id); } expect(seen.size).toBe(100_000); }); test('generateIdempotencyKey returns the same shape', () => { expect(generateIdempotencyKey().length).toBe(22); }); }); describe('base64url encode/decode', () => { test('roundtrip arbitrary bytes (property-based)', () => { fc.assert( fc.property(fc.uint8Array({ minLength: 0, maxLength: 64 }), (bytes) => { const decoded = base64UrlDecode(base64UrlEncode(bytes)); expect(decoded).toEqual(bytes); }), { numRuns: 500 }, ); }); test('produces URL-safe alphabet only', () => { fc.assert( fc.property(fc.uint8Array({ minLength: 1, maxLength: 64 }), (bytes) => { const enc = base64UrlEncode(bytes); expect(enc).not.toMatch(/[+/=]/); }), { numRuns: 200 }, ); }); test('handles empty input', () => { expect(base64UrlEncode(new Uint8Array(0))).toBe(''); expect(base64UrlDecode('')).toEqual(new Uint8Array(0)); }); test('decodes inputs without padding correctly', () => { expect(base64UrlDecode('YQ')).toEqual(new Uint8Array([0x61])); expect(base64UrlDecode('YWI')).toEqual(new Uint8Array([0x61, 0x62])); expect(base64UrlDecode('YWJj')).toEqual(new Uint8Array([0x61, 0x62, 0x63])); }); });