'use strict'; const test = require('node:test'); const assert = require('node:assert/strict'); const { EventEmitter } = require('node:events'); const { buildInfoSvg, formatTime, svgToDataUri } = require('../src/infoPanel'); const { Controller } = require('../src/controller'); const { PREFIX } = require('../src/actions'); const VIEW = { title: 'Tom & ', subtitle: 'Interpret', playing: true, currentTime: 65, duration: 200, volume: 42.4 }; test('formatTime formatiert Sekunden als m:ss', () => { assert.equal(formatTime(65), '1:05'); assert.equal(formatTime(0), '0:00'); assert.equal(formatTime(NaN), '0:00'); assert.equal(formatTime(-3), '0:00'); }); test('SVG enthaelt Titel (XML-escaped) und Interpret, quadratisch', () => { const svg = buildInfoSvg(VIEW); assert.match(svg, /^')); assert.ok(svg.includes('width="144" height="144"')); }); test('Cover wird eingebettet, sonst Platzhalter', () => { assert.ok(buildInfoSvg({ ...VIEW, coverDataUri: 'data:image/jpeg;base64,AAAA' }).includes('href="data:image/jpeg;base64,AAAA"')); assert.ok(!buildInfoSvg(VIEW).includes(' { assert.ok(buildInfoSvg({ ...VIEW, currentTime: 999 }).includes('width="124.0"')); assert.ok(buildInfoSvg({ ...VIEW, duration: 0 }).includes('width="0.0"')); }); test('offline und "nichts spielt" haben eigene Darstellungen', () => { assert.ok(buildInfoSvg(null).includes('offline')); assert.ok(buildInfoSvg({ ...VIEW, title: '' }).includes('spielt')); }); test('svgToDataUri erzeugt eine dekodierbare Data-URI', () => { const uri = svgToDataUri(''); assert.equal(Buffer.from(uri.split(',')[1], 'base64').toString(), ''); }); test('Controller: nowplaying auf dem Info-Display sendet ein SVG-Bild', () => { const calls = []; const host = new EventEmitter(); host.setTitle = (...a) => calls.push(['setTitle', ...a]); host.setImage = (...a) => calls.push(['setImage', ...a]); host.setState = () => {}; const client = new EventEmitter(); client.connected = true; client.status = async () => ({ activeTab: 'music', tabs: { music: { ...VIEW } } }); const controller = new Controller({ host, client, logger: { info() {}, warn() {}, error() {} }, fetchImage: async () => 'data:image/jpeg;base64,AA', }); controller.handleEvent({ event: 'willAppear', action: `${PREFIX}nowplaying`, context: 'INFO', payload: { controller: 'Information', settings: {} } }); controller.state = { activeTab: 'music', tabs: { music: { ...VIEW } } }; controller.renderAll(); const image = calls.filter((c) => c[0] === 'setImage').at(-1); assert.match(image[2], /^data:image\/svg\+xml;base64,/); const before = calls.length; controller.renderAll(); assert.equal(calls.length, before, 'unveraendert sendet nichts erneut'); });