const test = require('node:test'); const assert = require('node:assert/strict'); const fs = require('node:fs'); require('../src/common'); const timetableRegionSource = fs.readFileSync(require.resolve('../src/player/regions/timetable.js'), 'utf8'); const { mediaKind, normalizeSlide, renderEditorJsContent, renderHtmlRegionContent, sanitizeRichText } = require('../src/player/render-helpers'); test('mediaKind classifies player media by extension', () => { assert.equal(mediaKind('poster.PNG'), 'image'); assert.equal(mediaKind('intro.mp4'), 'video'); assert.equal(mediaKind('manual.pdf'), 'pdf'); assert.equal(mediaKind('notes.txt'), 'file'); }); test('sanitizeRichText strips unsafe content but preserves allowed markup', () => { const html = '
'; assert.equal( sanitizeRichText(html), '' ); }); test('normalizeSlide normalizes nested content without mutating the source', () => { const slide = { id: 12, content: { hero: { value: '{"headline":"Hello"}', font_family: ' Open Sans! ', font_size: '42', font_color: 'not-a-color', type: 'text' }, footer: 'plain text' } }; const normalized = normalizeSlide(slide); assert.notEqual(normalized.content, slide.content); assert.deepEqual(normalized.content.hero, { value: { headline: 'Hello' }, font_family: ' Open Sans! ', font_size: '42', font_color: 'not-a-color', type: 'text' }); assert.deepEqual(normalized.content.footer, { type: 'text', value: 'plain text' }); assert.deepEqual(slide.content.hero, { value: '{"headline":"Hello"}', font_family: ' Open Sans! ', font_size: '42', font_color: 'not-a-color', type: 'text' }); }); test('renderEditorJsContent sanitizes editor blocks and wraps legacy text', () => { const editorJson = { blocks: [ { type: 'header', data: { level: 2, text: 'Title' } }, { type: 'paragraph', data: { text: 'badok' } }, { type: 'list', data: { style: 'ordered', items: ['One', { text: 'Two' }] } } ] }; assert.equal( renderEditorJsContent(editorJson), 'badok
plain text
'); }); test('timetable region registers the timetable type', () => { assert.ok(timetableRegionSource.includes("registry.register('timetable'")); assert.ok(timetableRegionSource.includes("sanitizeRichText(substituteTimetableVariables(value")); }); test('shared iframe renderers size preview content explicitly', () => { const playerHtmlRegionSource = fs.readFileSync(require.resolve('../src/player/regions/html.js'), 'utf8'); const playerWebpageRegionSource = fs.readFileSync(require.resolve('../src/player/regions/webpage.js'), 'utf8'); const playerRenderHelpersSource = fs.readFileSync(require.resolve('../src/player/render-helpers.js'), 'utf8'); const slideThumbnailPreviewSource = fs.readFileSync(require.resolve('../src/web/lib/media/slide-thumbnail-preview.js'), 'utf8'); const slideThumbnailsSource = fs.readFileSync(require.resolve('../src/web/lib/media/slide-thumbnails.js'), 'utf8'); assert.ok(playerHtmlRegionSource.includes('style="width:100%;height:100%;border:0;display:block;background:transparent;overflow:hidden;"')); assert.ok(playerWebpageRegionSource.includes('style="width:100%;height:100%;border:0;display:block;background:#fff;overflow:hidden;"')); assert.ok(playerRenderHelpersSource.includes('style="width:100%;height:100%;border:0;display:block;background:transparent;overflow:hidden;"')); assert.ok(slideThumbnailPreviewSource.includes('slide-preview-webpage-region')); assert.ok(slideThumbnailPreviewSource.includes('style="width:100%;height:100%;border:0;display:block;background:transparent;overflow:hidden;"')); assert.ok(slideThumbnailsSource.includes('slide-preview-webpage-placeholder')); assert.ok(slideThumbnailsSource.includes('style="width:100%;height:100%;border:0;display:block;background:transparent;overflow:hidden;"')); }); test('html region helpers unwrap object-shaped values before rendering', () => { const rendered = renderHtmlRegionContent({ html: '