71 lines
2.9 KiB
JavaScript
71 lines
2.9 KiB
JavaScript
'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 & <Live>', 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, /^<svg /);
|
|
assert.ok(svg.includes('Tom &'));
|
|
assert.ok(svg.includes('<Live>'));
|
|
assert.ok(svg.includes('Interpret'));
|
|
assert.ok(!svg.includes('<Live>'));
|
|
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('<image'));
|
|
});
|
|
|
|
test('Fortschrittsbalken ist auf 0..100% begrenzt', () => {
|
|
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('<svg/>');
|
|
assert.equal(Buffer.from(uri.split(',')[1], 'base64').toString(), '<svg/>');
|
|
});
|
|
|
|
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');
|
|
});
|