import test from 'node:test'; import assert from 'node:assert/strict'; import { getLauncherAction, inferLauncherMediaType, readLauncherMediaConfig } from '../vr180player/launcher/launcher-config.js'; function createLauncher({ attributes = {}, dataset = {} } = {}) { return { dataset, getAttribute(name) { return attributes[name] ?? ''; } }; } test('getLauncherAction opens immersive only when immersive VR is supported', () => { assert.equal(getLauncherAction(true), 'immersive'); assert.equal(getLauncherAction(false), 'fallback-modal'); }); test('inferLauncherMediaType detects common image and video extensions', () => { assert.equal(inferLauncherMediaType('https://cdn.example.com/demo.png'), 'image'); assert.equal(inferLauncherMediaType('/media/demo.JPG?cache=1'), 'image'); assert.equal(inferLauncherMediaType('/media/demo.webm'), 'video'); assert.equal(inferLauncherMediaType('/media/demo.mp4#clip'), 'video'); assert.equal(inferLauncherMediaType('/media/demo'), null); }); test('readLauncherMediaConfig reads explicit launcher data', () => { const config = readLauncherMediaConfig(createLauncher({ dataset: { crossorigin: 'anonymous', headLock: 'position', mediaType: 'video', poster: '/poster.jpg', preload: 'auto', projection: 'plane', src: '/media/demo', title: 'Demo Video', type: 'video/mp4' } })); assert.deepEqual(config, { carousel: false, crossOrigin: 'anonymous', headLockMode: 'position', mediaType: 'video', poster: '/poster.jpg', preload: 'auto', projectionMode: 'plane', src: '/media/demo', srcs: ['/media/demo'], title: 'Demo Video', type: 'video/mp4' }); }); test('readLauncherMediaConfig infers defaults from data-src and aria-label', () => { const config = readLauncherMediaConfig(createLauncher({ attributes: { 'aria-label': 'Demo Image' }, dataset: { src: '/media/demo-image.webp' } })); assert.equal(config.mediaType, 'image'); assert.equal(config.projectionMode, 'vr180'); assert.equal(config.headLockMode, 'auto'); assert.equal(config.preload, 'metadata'); assert.equal(config.carousel, false); assert.deepEqual(config.srcs, ['/media/demo-image.webp']); assert.equal(config.title, 'Demo Image'); }); test('readLauncherMediaConfig supports image carousel launchers', () => { const config = readLauncherMediaConfig(createLauncher({ dataset: { carousel: '', mediaType: 'image', projection: 'plane', src: '/media/first.png, /media/second.png', title: 'Demo Carousel' } })); assert.equal(config.carousel, true); assert.equal(config.mediaType, 'image'); assert.equal(config.projectionMode, 'plane'); assert.equal(config.src, '/media/first.png'); assert.deepEqual(config.srcs, ['/media/first.png', '/media/second.png']); }); test('readLauncherMediaConfig rejects missing source or unsupported values', () => { assert.equal(readLauncherMediaConfig(createLauncher()), null); assert.equal(readLauncherMediaConfig(createLauncher({ dataset: { projection: 'cube', src: '/media/demo.png' } })), null); assert.equal(readLauncherMediaConfig(createLauncher({ dataset: { headLock: 'bad', src: '/media/demo.png' } })), null); assert.equal(readLauncherMediaConfig(createLauncher({ dataset: { mediaType: 'audio', src: '/media/demo.png' } })), null); assert.equal(readLauncherMediaConfig(createLauncher({ dataset: { src: '/media/demo' } })), null); assert.equal(readLauncherMediaConfig(createLauncher({ dataset: { carousel: '', mediaType: 'video', src: '/media/demo.mp4, /media/other.mp4' } })), null); assert.equal(readLauncherMediaConfig(createLauncher({ dataset: { carousel: '', src: '/media/demo.png' } })), null); assert.equal(readLauncherMediaConfig(createLauncher({ dataset: { src: '/media/first.png, /media/second.png' } })), null); });