Spaces:
Running
Running
| /** | |
| * 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(); | |
| }); | |
| }); | |