import { describe, it } from './runner.mjs'; import Ajv from 'ajv'; import addFormats from 'ajv-formats'; import { readFileSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { dirname, join } from 'node:path'; const schema = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), '../src/viewer/schema.json'), 'utf8')); const ajv = new Ajv({ strict: false }); addFormats(ajv); const validate = ajv.compile(schema); describe('Schema: VideoEntry with HLS fields', () => { it('should validate a legacy entry (url only)', () => { const entry = { url: 'https://example.com/video.mp4' }; const valid = validate(entry); if (!valid) { throw new Error(`Legacy entry rejected: ${JSON.stringify(validate.errors)}`); } }); it('should validate a full legacy entry (all original fields)', () => { const entry = { url: 'https://example.com/video.mp4', src: 'https://example.com/video.mp4', poster: 'https://example.com/thumb.jpg', tab: 'Video Page', }; const valid = validate(entry); if (!valid) { throw new Error(`Full legacy entry rejected: ${JSON.stringify(validate.errors)}`); } }); it('should validate an HLS entry with hlsManifest and mediaType', () => { const entry = { url: 'https://example.com/playlist.m3u8', src: 'https://example.com/playlist.m3u8', hlsManifest: 'https://cdn.example.com/stream.m3u8', mediaType: 'hls', poster: 'https://example.com/thumb.jpg', tab: 'HLS Stream Page', }; const valid = validate(entry); if (!valid) { throw new Error(`HLS entry rejected: ${JSON.stringify(validate.errors)}`); } }); it('should validate an HLS entry with only hlsManifest (mediaType omitted)', () => { const entry = { url: 'https://example.com/page', hlsManifest: 'https://cdn.example.com/stream.m3u8', }; const valid = validate(entry); if (!valid) { throw new Error(`HLS entry with only hlsManifest rejected: ${JSON.stringify(validate.errors)}`); } }); it('should validate an entry with mediaType=direct', () => { const entry = { url: 'https://example.com/video.mp4', mediaType: 'direct', }; const valid = validate(entry); if (!valid) { throw new Error(`Direct entry rejected: ${JSON.stringify(validate.errors)}`); } }); it('should reject entries without url', () => { const entry = { hlsManifest: 'https://cdn.example.com/stream.m3u8', mediaType: 'hls', }; const valid = validate(entry); if (valid) { throw new Error('Entry without url should be rejected but was accepted'); } }); it('should reject invalid mediaType values', () => { const entry = { url: 'https://example.com/video.mp4', mediaType: 'dash', }; const valid = validate(entry); if (valid) { throw new Error('Invalid mediaType "dash" should be rejected but was accepted'); } }); it('should reject additional properties', () => { const entry = { url: 'https://example.com/video.mp4', customField: 'value', }; const valid = validate(entry); if (valid) { throw new Error('Entry with additional properties should be rejected but was accepted'); } }); it('should validate poster as null', () => { const entry = { url: 'https://example.com/video.mp4', poster: null, }; const valid = validate(entry); if (!valid) { throw new Error(`Entry with null poster rejected: ${JSON.stringify(validate.errors)}`); } }); it('should validate hlsManifest as URI format', () => { const entry = { url: 'https://example.com/page', hlsManifest: 'https://stream.example.com/hls/playlist.m3u8', }; const valid = validate(entry); if (!valid) { throw new Error(`Valid hlsManifest URI rejected: ${JSON.stringify(validate.errors)}`); } }); });