test: cut low-value tests, rewrite the rest around behavior, parallelize lanes (#285)

This commit is contained in:
sudacode authored and GitHub committed 2026-10-05 00:07:44 -07:00
1 parent 4b6842d034
commit b48083ddd8
368 files changed
+18045 -60331

No files matched your search

+128 -149
View File
@@ -6,6 +6,7 @@ import {
createHandleJellyfinRemotePlaystate,
getConfiguredJellyfinSession,
type ActiveJellyfinRemotePlaybackState,
type JellyfinRemotePlayHandlerDeps,
} from './jellyfin-remote-commands';
test('getConfiguredJellyfinSession returns null for incomplete config', () => {
@@ -20,134 +21,17 @@ test('getConfiguredJellyfinSession returns null for incomplete config', () => {
);
});
test('createHandleJellyfinRemotePlay forwards parsed payload to play runtime', async () => {
const calls: Array<{
itemId: string;
audio?: number;
subtitle?: number;
start?: number;
fallback?: boolean;
}> = [];
const handlePlay = createHandleJellyfinRemotePlay({
getConfiguredSession: () => ({
serverUrl: 'https://jellyfin.local',
accessToken: 'token',
userId: 'user',
username: 'name',
}),
getClientInfo: () => ({ clientName: 'SubMiner', clientVersion: '1.0', deviceId: 'abc' }),
getJellyfinConfig: () => ({ enabled: true }),
playJellyfinItem: async (params) => {
calls.push({
itemId: params.itemId,
audio: params.audioStreamIndex,
subtitle: params.subtitleStreamIndex,
start: params.startTimeTicksOverride,
fallback: params.fallbackToPlanStartTimeOnZeroOverride,
});
},
logWarn: () => {},
});
await handlePlay({
ItemIds: ['item-1'],
AudioStreamIndex: 3,
SubtitleStreamIndex: 7,
StartPositionTicks: 1000,
});
assert.deepEqual(calls, [
{ itemId: 'item-1', audio: 3, subtitle: 7, start: 1000, fallback: true },
]);
});
test('createHandleJellyfinRemotePlay parses string StartPositionTicks', async () => {
const calls: Array<{ itemId: string; start?: number; fallback?: boolean }> = [];
const handlePlay = createHandleJellyfinRemotePlay({
getConfiguredSession: () => ({
serverUrl: 'https://jellyfin.local',
accessToken: 'token',
userId: 'user',
username: 'name',
}),
getClientInfo: () => ({ clientName: 'SubMiner', clientVersion: '1.0', deviceId: 'abc' }),
getJellyfinConfig: () => ({ enabled: true }),
playJellyfinItem: async (params) => {
calls.push({
itemId: params.itemId,
start: params.startTimeTicksOverride,
fallback: params.fallbackToPlanStartTimeOnZeroOverride,
});
},
logWarn: () => {},
});
await handlePlay({
ItemIds: ['item-2'],
StartPositionTicks: '12345',
});
assert.deepEqual(calls, [{ itemId: 'item-2', start: 12345, fallback: true }]);
});
test('createHandleJellyfinRemotePlay starts from beginning when StartPositionTicks is omitted', async () => {
const calls: Array<{ itemId: string; start?: number; fallback?: boolean }> = [];
const handlePlay = createHandleJellyfinRemotePlay({
getConfiguredSession: () => ({
serverUrl: 'https://jellyfin.local',
accessToken: 'token',
userId: 'user',
username: 'name',
}),
getClientInfo: () => ({ clientName: 'SubMiner', clientVersion: '1.0', deviceId: 'abc' }),
getJellyfinConfig: () => ({ enabled: true }),
playJellyfinItem: async (params) => {
calls.push({
itemId: params.itemId,
start: params.startTimeTicksOverride,
fallback: params.fallbackToPlanStartTimeOnZeroOverride,
});
},
logWarn: () => {},
});
await handlePlay({
ItemIds: ['item-3'],
});
assert.deepEqual(calls, [{ itemId: 'item-3', start: 0, fallback: false }]);
});
test('createHandleJellyfinRemotePlay lets explicit zero fall back to Jellyfin item progress', async () => {
const calls: Array<{ itemId: string; start?: number; fallback?: boolean }> = [];
const handlePlay = createHandleJellyfinRemotePlay({
getConfiguredSession: () => ({
serverUrl: 'https://jellyfin.local',
accessToken: 'token',
userId: 'user',
username: 'name',
}),
getClientInfo: () => ({ clientName: 'SubMiner', clientVersion: '1.0', deviceId: 'abc' }),
getJellyfinConfig: () => ({ enabled: true }),
playJellyfinItem: async (params) => {
calls.push({
itemId: params.itemId,
start: params.startTimeTicksOverride,
fallback: params.fallbackToPlanStartTimeOnZeroOverride,
});
},
logWarn: () => {},
});
await handlePlay({
ItemIds: ['item-4'],
StartPositionTicks: 0,
});
assert.deepEqual(calls, [{ itemId: 'item-4', start: 0, fallback: true }]);
});
test('createHandleJellyfinRemotePlay logs and skips payload without item id', async () => {
function makePlayHandler(overrides: Partial<JellyfinRemotePlayHandlerDeps> = {}) {
const played: Array<
Pick<
Parameters<JellyfinRemotePlayHandlerDeps['playJellyfinItem']>[0],
| 'itemId'
| 'audioStreamIndex'
| 'subtitleStreamIndex'
| 'startTimeTicksOverride'
| 'fallbackToPlanStartTimeOnZeroOverride'
>
> = [];
const warnings: string[] = [];
const handlePlay = createHandleJellyfinRemotePlay({
getConfiguredSession: () => ({
@@ -158,40 +42,92 @@ test('createHandleJellyfinRemotePlay logs and skips payload without item id', as
}),
getClientInfo: () => ({ clientName: 'SubMiner', clientVersion: '1.0', deviceId: 'abc' }),
getJellyfinConfig: () => ({}),
playJellyfinItem: async () => {
throw new Error('should not be called');
playJellyfinItem: async (params) => {
played.push({
itemId: params.itemId,
audioStreamIndex: params.audioStreamIndex,
subtitleStreamIndex: params.subtitleStreamIndex,
startTimeTicksOverride: params.startTimeTicksOverride,
fallbackToPlanStartTimeOnZeroOverride: params.fallbackToPlanStartTimeOnZeroOverride,
});
},
logWarn: (message) => warnings.push(message),
...overrides,
});
return { handlePlay, played, warnings };
}
const PLAY_PAYLOAD_CASES: Array<{
name: string;
payload: Record<string, unknown>;
expected: {
audioStreamIndex?: number;
subtitleStreamIndex?: number;
startTimeTicksOverride: number;
fallbackToPlanStartTimeOnZeroOverride: boolean;
};
}> = [
{
name: 'forwards audio, subtitle and numeric StartPositionTicks',
payload: { AudioStreamIndex: 3, SubtitleStreamIndex: 7, StartPositionTicks: 1000 },
expected: {
audioStreamIndex: 3,
subtitleStreamIndex: 7,
startTimeTicksOverride: 1000,
fallbackToPlanStartTimeOnZeroOverride: true,
},
},
{
name: 'parses string StartPositionTicks',
payload: { StartPositionTicks: '12345' },
expected: { startTimeTicksOverride: 12345, fallbackToPlanStartTimeOnZeroOverride: true },
},
{
name: 'starts from beginning when StartPositionTicks is omitted',
payload: {},
expected: { startTimeTicksOverride: 0, fallbackToPlanStartTimeOnZeroOverride: false },
},
{
name: 'lets explicit zero fall back to Jellyfin item progress',
payload: { StartPositionTicks: 0 },
expected: { startTimeTicksOverride: 0, fallbackToPlanStartTimeOnZeroOverride: true },
},
];
for (const c of PLAY_PAYLOAD_CASES) {
test(`createHandleJellyfinRemotePlay ${c.name}`, async () => {
const { handlePlay, played } = makePlayHandler();
await handlePlay({ ItemIds: ['item-1'], ...c.payload });
assert.deepEqual(played, [
{
itemId: 'item-1',
audioStreamIndex: undefined,
subtitleStreamIndex: undefined,
...c.expected,
},
]);
});
}
test('createHandleJellyfinRemotePlay logs and skips payload without item id', async () => {
const { handlePlay, played, warnings } = makePlayHandler();
await handlePlay({ ItemIds: [] });
assert.deepEqual(warnings, ['Ignoring Jellyfin remote Play event without ItemIds.']);
assert.deepEqual(played, []);
});
test('createHandleJellyfinRemotePlay ignores duplicate play for active item', async () => {
let playCalls = 0;
const handlePlay = createHandleJellyfinRemotePlay({
getConfiguredSession: () => ({
serverUrl: 'https://jellyfin.local',
accessToken: 'token',
userId: 'user',
username: 'name',
}),
getClientInfo: () => ({ clientName: 'SubMiner', clientVersion: '1.0', deviceId: 'abc' }),
getJellyfinConfig: () => ({}),
getActivePlayback: () => ({
itemId: 'item-1',
playMethod: 'DirectPlay',
}),
playJellyfinItem: async () => {
playCalls += 1;
},
logWarn: () => {},
const { handlePlay, played } = makePlayHandler({
getActivePlayback: () => ({ itemId: 'item-1', playMethod: 'DirectPlay' }),
});
await handlePlay({ ItemIds: ['item-1'] });
assert.equal(playCalls, 0);
assert.deepEqual(played, []);
});
test('createHandleJellyfinRemotePlaystate dispatches pause/seek/stop flows', async () => {
@@ -222,6 +158,49 @@ test('createHandleJellyfinRemotePlaystate dispatches pause/seek/stop flows', asy
assert.deepEqual(calls, ['progress:true', 'progress:true', 'stopped']);
});
test('createHandleJellyfinRemotePlaystate maps Unpause and PlayPause and reports progress', async () => {
const commands: Array<(string | number)[]> = [];
const progress: boolean[] = [];
const handlePlaystate = createHandleJellyfinRemotePlaystate({
getMpvClient: () => ({}),
sendMpvCommand: (_client, command) => commands.push(command),
reportJellyfinRemoteProgress: async (force) => {
progress.push(force);
},
reportJellyfinRemoteStopped: async () => {},
jellyfinTicksToSeconds: (ticks) => ticks / 10,
});
await handlePlaystate({ Command: 'Unpause' });
await handlePlaystate({ Command: 'PlayPause' });
assert.deepEqual(commands, [
['set_property', 'pause', 'no'],
['cycle', 'pause'],
]);
assert.deepEqual(progress, [true, true]);
});
test('createHandleJellyfinRemotePlaystate ignores Seek without a valid tick position', async () => {
const commands: Array<(string | number)[]> = [];
const progress: boolean[] = [];
const handlePlaystate = createHandleJellyfinRemotePlaystate({
getMpvClient: () => ({}),
sendMpvCommand: (_client, command) => commands.push(command),
reportJellyfinRemoteProgress: async (force) => {
progress.push(force);
},
reportJellyfinRemoteStopped: async () => {},
jellyfinTicksToSeconds: (ticks) => ticks / 10,
});
await handlePlaystate({ Command: 'Seek', SeekPositionTicks: 'soon' });
await handlePlaystate({ Command: 'Seek' });
assert.deepEqual(commands, []);
assert.deepEqual(progress, []);
});
test('createHandleJellyfinRemoteGeneralCommand mutates active playback indices', async () => {
const mpvClient = {};
const commands: Array<(string | number)[]> = [];