Files
SubMiner/src/settings/settings-controls.test.ts
T
sudacode 236f22662c feat(youtube): add mediaCache mode and safer stream media extraction
- Add `youtube.mediaCache.mode` config option (`direct` | `background`)
- Resolve EDL stream URLs to single audio/video URLs before ffmpeg extraction
- Pass reconnect, user-agent, and safe headers to ffmpeg for remote streams
- Add background yt-dlp media cache with fallback to direct extraction
- Introduce `MediaInput` structured type replacing bare path strings
2026-06-20 02:25:32 -07:00

125 lines
3.5 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { renderControl } from './settings-controls';
import type { ConfigSettingsField } from '../types/settings';
class FakeOption {
value = '';
textContent: string | null = null;
selected = false;
className = '';
}
class FakeSelect {
value = '';
className = '';
options: FakeOption[] = [];
private readonly listeners = new Map<string, Array<() => void>>();
append(...children: FakeOption[]): void {
for (const child of children) {
this.options.push(child);
if (child.selected) {
this.value = child.value;
}
}
}
addEventListener(type: string, listener: () => void): void {
const listeners = this.listeners.get(type) ?? [];
listeners.push(listener);
this.listeners.set(type, listeners);
}
dispatchEvent(event: Event): boolean {
for (const listener of this.listeners.get(event.type) ?? []) {
listener();
}
return true;
}
}
function installDocumentStub(): () => void {
const previousDocument = globalThis.document;
globalThis.document = {
createElement(tagName: string) {
return tagName === 'select' ? new FakeSelect() : new FakeOption();
},
} as unknown as Document;
return () => {
globalThis.document = previousDocument;
};
}
function createSelectField(): ConfigSettingsField {
return {
id: 'updates.notificationType',
label: 'Notification Type',
description: 'How SubMiner announces available updates.',
configPath: 'updates.notificationType',
category: 'tracking-app',
section: 'Updates',
control: 'select',
defaultValue: 'system',
enumValues: ['overlay', 'system', 'both', 'none'],
restartBehavior: 'restart',
};
}
test('select controls show config-only current values without offering them otherwise', () => {
const restoreDocument = installDocumentStub();
const updates: Array<{ path: string; value: unknown }> = [];
try {
const control = renderControl(createSelectField(), {
valueForField: () => 'osd-system',
valueForPath: () => undefined,
updateDraft: (path, value) => updates.push({ path, value }),
resetDraftPath: () => {},
setFieldError: () => {},
}) as HTMLSelectElement;
assert.equal(control.value, 'osd-system');
assert.deepEqual(
Array.from(control.options).map((option) => option.value),
['osd-system', 'overlay', 'system', 'both', 'none'],
);
control.value = 'overlay';
control.dispatchEvent(new Event('change'));
assert.deepEqual(updates, [{ path: 'updates.notificationType', value: 'overlay' }]);
} finally {
restoreDocument();
}
});
test('select controls use configured option labels', () => {
const restoreDocument = installDocumentStub();
try {
const field = {
...createSelectField(),
enumValues: ['direct', 'background'],
enumLabels: {
direct: 'Direct stream extraction',
background: 'Background media cache',
},
} as ConfigSettingsField & { enumLabels: Record<string, string> };
const control = renderControl(field, {
valueForField: () => 'direct',
valueForPath: () => undefined,
updateDraft: () => {},
resetDraftPath: () => {},
setFieldError: () => {},
}) as HTMLSelectElement;
assert.deepEqual(
Array.from(control.options).map((option) => option.textContent),
['Direct stream extraction', 'Background media cache'],
);
} finally {
restoreDocument();
}
});