test: align standard commands with maintained test surface

This commit is contained in:
2026-03-06 00:58:32 -08:00
parent f160ca6af8
commit e2b51c6306
15 changed files with 364 additions and 103 deletions

View File

@@ -1,6 +1,5 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import * as childProcess from 'child_process';
import { guessAnilistMediaInfo, updateAnilistPostWatchProgress } from './anilist-updater';
@@ -12,67 +11,27 @@ function createJsonResponse(payload: unknown): Response {
}
test('guessAnilistMediaInfo uses guessit output when available', async () => {
const originalExecFile = childProcess.execFile;
(
childProcess as unknown as {
execFile: typeof childProcess.execFile;
}
).execFile = ((...args: unknown[]) => {
const callback = args[args.length - 1];
const cb =
typeof callback === 'function'
? (callback as (error: Error | null, stdout: string, stderr: string) => void)
: null;
cb?.(null, JSON.stringify({ title: 'Guessit Title', episode: 7 }), '');
return {} as childProcess.ChildProcess;
}) as typeof childProcess.execFile;
try {
const result = await guessAnilistMediaInfo('/tmp/demo.mkv', null);
assert.deepEqual(result, {
title: 'Guessit Title',
episode: 7,
source: 'guessit',
});
} finally {
(
childProcess as unknown as {
execFile: typeof childProcess.execFile;
}
).execFile = originalExecFile;
}
const result = await guessAnilistMediaInfo('/tmp/demo.mkv', null, {
runGuessit: async () => JSON.stringify({ title: 'Guessit Title', episode: 7 }),
});
assert.deepEqual(result, {
title: 'Guessit Title',
episode: 7,
source: 'guessit',
});
});
test('guessAnilistMediaInfo falls back to parser when guessit fails', async () => {
const originalExecFile = childProcess.execFile;
(
childProcess as unknown as {
execFile: typeof childProcess.execFile;
}
).execFile = ((...args: unknown[]) => {
const callback = args[args.length - 1];
const cb =
typeof callback === 'function'
? (callback as (error: Error | null, stdout: string, stderr: string) => void)
: null;
cb?.(new Error('guessit not found'), '', '');
return {} as childProcess.ChildProcess;
}) as typeof childProcess.execFile;
try {
const result = await guessAnilistMediaInfo('/tmp/My Anime S01E03.mkv', null);
assert.deepEqual(result, {
title: 'My Anime',
episode: 3,
source: 'fallback',
});
} finally {
(
childProcess as unknown as {
execFile: typeof childProcess.execFile;
}
).execFile = originalExecFile;
}
const result = await guessAnilistMediaInfo('/tmp/My Anime S01E03.mkv', null, {
runGuessit: async () => {
throw new Error('guessit not found');
},
});
assert.deepEqual(result, {
title: 'My Anime',
episode: 3,
source: 'fallback',
});
});
test('updateAnilistPostWatchProgress updates progress when behind', async () => {

View File

@@ -72,6 +72,10 @@ function runGuessit(target: string): Promise<string> {
});
}
type GuessAnilistMediaInfoDeps = {
runGuessit: (target: string) => Promise<string>;
};
function firstString(value: unknown): string | null {
if (typeof value === 'string') {
const trimmed = value.trim();
@@ -177,12 +181,13 @@ function pickBestSearchResult(
export async function guessAnilistMediaInfo(
mediaPath: string | null,
mediaTitle: string | null,
deps: GuessAnilistMediaInfoDeps = { runGuessit },
): Promise<AnilistMediaGuess | null> {
const target = mediaPath ?? mediaTitle;
if (target && target.trim().length > 0) {
try {
const stdout = await runGuessit(target);
const stdout = await deps.runGuessit(target);
const parsed = JSON.parse(stdout) as Record<string, unknown>;
const title = firstString(parsed.title);
const episode = firstPositiveInteger(parsed.episode);