113 lines
5.3 KiB
JavaScript
113 lines
5.3 KiB
JavaScript
'use strict';
|
|
|
|
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const {
|
|
DEFINITIONS, PREFIX, actionIdFromUuid, buildRequest, normalizeSettings, renderAction, wrapTitle,
|
|
} = require('../src/actions');
|
|
|
|
const STATE = {
|
|
activeTab: 'music',
|
|
visibleTab: 'music',
|
|
tabs: {
|
|
music: { playing: true, title: 'Ein sehr langer Songtitel', volume: 42.4, muted: false, likeStatus: 'like',
|
|
repeatMode: 'ALL', hasVideo: true, thumbnail: 'https://example.test/c=w60-h60' },
|
|
youtube: { playing: false, title: 'Video', volume: 80, muted: true, likeStatus: 'none', repeatMode: 'NONE' },
|
|
},
|
|
};
|
|
|
|
test('actionIdFromUuid erkennt nur bekannte Aktionen', () => {
|
|
assert.equal(actionIdFromUuid(`${PREFIX}volumeup`), 'volumeup');
|
|
assert.equal(actionIdFromUuid(`${PREFIX}gibtesnicht`), null);
|
|
assert.equal(actionIdFromUuid('com.other.volumeup'), null);
|
|
assert.equal(actionIdFromUuid(undefined), null);
|
|
});
|
|
|
|
test('normalizeSettings begrenzt Werte und ersetzt ungueltige durch Standardwerte', () => {
|
|
const settings = normalizeSettings({ step: '999', volume: -5, seconds: 'abc', target: 'x', tab: 'y' });
|
|
assert.equal(settings.step, 25);
|
|
assert.equal(settings.volume, 0);
|
|
assert.equal(settings.seconds, 10);
|
|
assert.equal(settings.target, 'auto');
|
|
assert.equal(settings.tab, 'toggle');
|
|
});
|
|
|
|
test('normalizeSettings: showTitle nutzt den Standard der Aktion, wenn nichts gespeichert ist', () => {
|
|
assert.equal(normalizeSettings({}, true).showTitle, true);
|
|
assert.equal(normalizeSettings({}, false).showTitle, false);
|
|
assert.equal(normalizeSettings({ showTitle: false }, true).showTitle, false);
|
|
assert.equal(normalizeSettings({ showTitle: 'true' }, false).showTitle, true);
|
|
});
|
|
|
|
test('Lauter/Leiser senden volume_change mit Vorzeichen und Schrittweite', () => {
|
|
assert.deepEqual(buildRequest('volumeup', { step: 7 }), { cmd: 'volume_change', fields: { target: 'auto', value: 7 } });
|
|
assert.deepEqual(buildRequest('volumedown', { step: 7, target: 'music' }),
|
|
{ cmd: 'volume_change', fields: { target: 'music', value: -7 } });
|
|
});
|
|
|
|
test('Lautstaerke setzen und Spulen', () => {
|
|
assert.deepEqual(buildRequest('volumeset', { volume: 55 }), { cmd: 'set_volume', fields: { target: 'auto', value: 55 } });
|
|
assert.deepEqual(buildRequest('seekback', { seconds: 15 }), { cmd: 'seek', fields: { target: 'auto', value: -15 } });
|
|
assert.deepEqual(buildRequest('seekforward', {}), { cmd: 'seek', fields: { target: 'auto', value: 10 } });
|
|
});
|
|
|
|
test('Playlist-Taste ohne ID sendet nichts, mit ID play_playlist', () => {
|
|
assert.equal(buildRequest('playlist', {}), null);
|
|
assert.deepEqual(buildRequest('playlist', { playlistId: ' PL123 ' }),
|
|
{ cmd: 'play_playlist', fields: { playlist: 'PL123' } });
|
|
});
|
|
|
|
test('Tab wechseln: "toggle" wird zu auto', () => {
|
|
assert.equal(buildRequest('switchtab', {}).fields.target, 'auto');
|
|
assert.equal(buildRequest('switchtab', { tab: 'youtube' }).fields.target, 'youtube');
|
|
});
|
|
|
|
test('jede Aktion hat request() und liefert gueltiges cmd', () => {
|
|
for (const id of Object.keys(DEFINITIONS)) {
|
|
const request = buildRequest(id, { playlistId: 'PLx' });
|
|
assert.ok(request && typeof request.cmd === 'string', id);
|
|
}
|
|
});
|
|
|
|
test('Play/Pause-Zustand folgt dem aktiven Tab bzw. dem gewaehlten Ziel', () => {
|
|
assert.equal(renderAction('playpause', {}, STATE, true).state, 1);
|
|
assert.equal(renderAction('playpause', { target: 'youtube' }, STATE, true).state, 0);
|
|
});
|
|
|
|
test('Lautstaerke-Tasten zeigen die gerundete Lautstaerke', () => {
|
|
assert.equal(renderAction('volumeup', {}, STATE, true).title, '42%');
|
|
assert.equal(renderAction('volumedown', { target: 'youtube' }, STATE, true).title, '80%');
|
|
});
|
|
|
|
test('offline: Titel leer bzw. Offline-Hinweis, Zustand 0', () => {
|
|
assert.equal(renderAction('volumeup', {}, null, false).title, '');
|
|
const view = renderAction('playpause', { showTitle: true }, null, false);
|
|
assert.equal(view.state, 0);
|
|
assert.match(view.title, /offline/);
|
|
});
|
|
|
|
test('Mute, Like und Repeat bilden den Playtube-Zustand auf State-Indizes ab', () => {
|
|
assert.equal(renderAction('mute', { target: 'youtube' }, STATE, true).state, 1);
|
|
assert.equal(renderAction('mute', {}, STATE, true).state, 0);
|
|
assert.equal(renderAction('like', {}, STATE, true).state, 1);
|
|
assert.equal(renderAction('repeat', {}, STATE, true).state, 1);
|
|
assert.equal(renderAction('repeat', { target: 'youtube' }, STATE, true).state, 0);
|
|
const one = { ...STATE, tabs: { ...STATE.tabs, music: { ...STATE.tabs.music, repeatMode: 'ONE' } } };
|
|
assert.equal(renderAction('repeat', {}, one, true).state, 2);
|
|
});
|
|
|
|
test('Cover-Taste liefert die Thumbnail-URL nur bei vorhandenem Video/Titel', () => {
|
|
assert.equal(renderAction('nowplaying', {}, STATE, true).coverUrl, 'https://example.test/c=w60-h60');
|
|
assert.equal(renderAction('nowplaying', { target: 'youtube' }, STATE, true).coverUrl, null);
|
|
assert.equal(renderAction('nowplaying', {}, null, false).coverUrl, null);
|
|
});
|
|
|
|
test('wrapTitle bricht um, trennt lange Woerter und kuerzt', () => {
|
|
assert.equal(wrapTitle('Hello World'), 'Hello\nWorld');
|
|
assert.equal(wrapTitle('Supercalifragilistic'), 'Supercal\nifragili\nstic');
|
|
const lines = wrapTitle('eins zwei drei vier fuenf sechs sieben acht neun zehn').split('\n');
|
|
assert.equal(lines.length, 3);
|
|
assert.ok(lines[2].endsWith('..'));
|
|
assert.equal(wrapTitle(''), '');
|
|
});
|