- viewer.js: dynamic hls.js loading, HLS-aware panel creation, error handling - schema.json: hlsManifest and mediaType fields (optional, backward compatible) - types.ts: VideoEntry interface with MediaType type - isHls() null guard fix - tests: 39 tests (schema, viewer units, data flow, integration) - CI: GitHub/Gitea Actions workflow (npm test on push/PR) - deps: ajv, ajv-formats, jsdom for testing
This commit is contained in:
1 parent
baa72a4c33
commit
90c3425200
12 files changed
+2295
-27
No files matched your search
@@ -0,0 +1,123 @@
|
||||
import { describe, it } from './runner.mjs';
|
||||
import Ajv from 'ajv';
|
||||
import addFormats from 'ajv-formats';
|
||||
import schema from '../src/viewer/schema.json' with { type: 'json' };
|
||||
|
||||
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)}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user