/** * Unit tests for ShareableURL logic * Validates: Requirements 25.1, 25.2, 25.3, 25.4, 25.5 */ import { describe, it, expect, beforeEach } from 'vitest'; // ─── Pure logic extracted from ShareableURL for testability ───────────── const HASH_PREFIX = '#model='; /** * Parse a hash string and return the model ID, or null. * @param {string} hash - e.g. "#model=ppe" * @returns {string|null} */ function parseHash(hash) { if (!hash || !hash.startsWith(HASH_PREFIX)) { return null; } const raw = hash.substring(HASH_PREFIX.length); const decoded = decodeURIComponent(raw).trim(); return decoded || null; } /** * Build a hash string from a model ID. * @param {string} modelId * @returns {string} */ function buildHash(modelId) { return HASH_PREFIX + encodeURIComponent(modelId); } /** * Find a model by ID in a list. * @param {Array<{id: string}>} modelList * @param {string} modelId * @returns {object|null} */ function findModelById(modelList, modelId) { if (!modelList || !modelId) return null; return modelList.find((m) => m.id === modelId) || null; } /** * Validate a hash against a model list. Returns the model or an error. * @param {string} hash * @param {Array<{id: string}>} modelList * @returns {{ model: object|null, error: string|null }} */ function validateHash(hash, modelList) { const modelId = parseHash(hash); if (!modelId) { return { model: null, error: null }; } const model = findModelById(modelList, modelId); if (!model) { return { model: null, error: `Model "${modelId}" not found. The shared link may be outdated or invalid.` }; } return { model, error: null }; } // ─── Test Data ────────────────────────────────────────────────────────── const SAMPLE_MODELS = [ { id: 'jsl', name: 'JSL Model', path: 'models/jsl/model.onnx' }, { id: 'ppe', name: 'PPE Detection Model', path: 'models/ppe/model.onnx' }, { id: 'vsl', name: 'VSL Model', path: 'models/vsl/model.onnx' }, ]; // ─── Tests ────────────────────────────────────────────────────────────── describe('ShareableURL - parseHash', () => { it('should return null for empty hash', () => { expect(parseHash('')).toBeNull(); expect(parseHash(null)).toBeNull(); expect(parseHash(undefined)).toBeNull(); }); it('should return null for hash without model= prefix', () => { expect(parseHash('#other=value')).toBeNull(); expect(parseHash('#')).toBeNull(); expect(parseHash('#model')).toBeNull(); }); it('should parse a valid model hash', () => { expect(parseHash('#model=ppe')).toBe('ppe'); expect(parseHash('#model=jsl')).toBe('jsl'); }); it('should decode URI-encoded model IDs', () => { expect(parseHash('#model=my%20model')).toBe('my model'); }); it('should return null for #model= with empty value', () => { expect(parseHash('#model=')).toBeNull(); expect(parseHash('#model= ')).toBeNull(); }); }); describe('ShareableURL - buildHash', () => { it('should build a valid hash string', () => { expect(buildHash('ppe')).toBe('#model=ppe'); expect(buildHash('jsl')).toBe('#model=jsl'); }); it('should encode special characters', () => { const hash = buildHash('my model'); expect(hash).toBe('#model=my%20model'); }); }); describe('ShareableURL - round-trip', () => { it('should round-trip a model ID through build and parse', () => { const ids = ['ppe', 'jsl', 'vsl', 'some-id']; ids.forEach((id) => { const hash = buildHash(id); expect(parseHash(hash)).toBe(id); }); }); }); describe('ShareableURL - findModelById', () => { it('should find a model by ID', () => { const result = findModelById(SAMPLE_MODELS, 'ppe'); expect(result).not.toBeNull(); expect(result.id).toBe('ppe'); }); it('should return null for unknown ID', () => { expect(findModelById(SAMPLE_MODELS, 'unknown')).toBeNull(); }); it('should return null for null/empty inputs', () => { expect(findModelById(null, 'ppe')).toBeNull(); expect(findModelById(SAMPLE_MODELS, null)).toBeNull(); expect(findModelById(SAMPLE_MODELS, '')).toBeNull(); }); }); describe('ShareableURL - validateHash', () => { it('should return model for valid hash with known ID', () => { const { model, error } = validateHash('#model=ppe', SAMPLE_MODELS); expect(error).toBeNull(); expect(model).not.toBeNull(); expect(model.id).toBe('ppe'); }); it('should return error for valid hash with unknown ID (Req 25.4)', () => { const { model, error } = validateHash('#model=nonexistent', SAMPLE_MODELS); expect(model).toBeNull(); expect(error).toContain('nonexistent'); expect(error).toContain('not found'); }); it('should return null model and no error for empty hash', () => { const { model, error } = validateHash('', SAMPLE_MODELS); expect(model).toBeNull(); expect(error).toBeNull(); }); it('should return null model and no error for non-model hash', () => { const { model, error } = validateHash('#other=value', SAMPLE_MODELS); expect(model).toBeNull(); expect(error).toBeNull(); }); });