Files
netfelix-audio-fix/server/services/__tests__/rescan.test.ts
T
2026-04-21 06:31:21 +02:00

128 lines
4.9 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import { Database } from "bun:sqlite";
import { upsertScannedItem } from "../rescan";
import { SCHEMA } from "../../db/schema";
import type { ProbeResult } from "../probe";
import type { ParsedPath } from "../path-parser";
function freshDb(): Database {
const db = new Database(":memory:");
db.exec(SCHEMA);
return db;
}
const PARSED: ParsedPath = {
type: "Movie",
name: "Hot Fuzz",
year: 2007,
seriesName: null,
seasonNumber: null,
episodeNumber: null,
imdbId: "tt0425112",
tmdbId: null,
tvdbId: null,
container: "mkv",
};
const PROBE: ProbeResult = {
fileSize: 5_000_000_000,
durationSeconds: 7200,
container: "matroska",
streams: [
{ streamIndex: 0, type: "Video", codec: "h264", profile: "High", language: null, title: null, isDefault: 1, isForced: 0, isHearingImpaired: 0, channels: null, channelLayout: null, bitRate: null, sampleRate: null, bitDepth: null },
{ streamIndex: 1, type: "Audio", codec: "dts", profile: "DTS-HD MA", language: "eng", title: "English 5.1", isDefault: 1, isForced: 0, isHearingImpaired: 0, channels: 6, channelLayout: "5.1(side)", bitRate: 1509000, sampleRate: 48000, bitDepth: 24 },
],
};
describe("upsertScannedItem", () => {
test("inserts new item with streams", () => {
const db = freshDb();
const result = upsertScannedItem(db, "/movies/Hot Fuzz (2007)/Hot Fuzz (2007).mkv", PARSED, PROBE);
expect(result.itemId).toBeGreaterThan(0);
expect(result.isNew).toBe(true);
const item = db.prepare("SELECT * FROM media_items WHERE id = ?").get(result.itemId) as any;
expect(item.name).toBe("Hot Fuzz");
expect(item.type).toBe("Movie");
expect(item.imdb_id).toBe("tt0425112");
expect(item.file_size).toBe(5_000_000_000);
expect(item.duration_seconds).toBe(7200);
expect(item.scan_status).toBe("scanned");
const streams = db.prepare("SELECT * FROM media_streams WHERE item_id = ?").all(result.itemId);
expect(streams).toHaveLength(2);
});
test("upserts on same file_path", () => {
const db = freshDb();
upsertScannedItem(db, "/movies/test.mkv", PARSED, PROBE);
const updated = { ...PROBE, fileSize: 6_000_000_000 };
const result = upsertScannedItem(db, "/movies/test.mkv", PARSED, updated);
expect(result.isNew).toBe(false);
const item = db.prepare("SELECT * FROM media_items WHERE id = ?").get(result.itemId) as any;
expect(item.file_size).toBe(6_000_000_000);
});
test("preserves manual language override on rescan", () => {
const db = freshDb();
const result = upsertScannedItem(db, "/movies/test.mkv", PARSED, PROBE);
db.prepare("UPDATE media_items SET original_language = 'fra', orig_lang_source = 'manual' WHERE id = ?").run(result.itemId);
const result2 = upsertScannedItem(db, "/movies/test.mkv", PARSED, PROBE);
const item = db.prepare("SELECT original_language, orig_lang_source FROM media_items WHERE id = ?").get(result2.itemId) as any;
expect(item.original_language).toBe("fra");
expect(item.orig_lang_source).toBe("manual");
});
test("creates review_plan stub", () => {
const db = freshDb();
const result = upsertScannedItem(db, "/movies/test.mkv", PARSED, PROBE);
const plan = db.prepare("SELECT * FROM review_plans WHERE item_id = ?").get(result.itemId) as any;
expect(plan).toBeDefined();
expect(plan.status).toBe("pending");
});
test("does not reset approved plan on rescan", () => {
const db = freshDb();
const result = upsertScannedItem(db, "/movies/test.mkv", PARSED, PROBE);
db.prepare("UPDATE review_plans SET status = 'approved' WHERE item_id = ?").run(result.itemId);
upsertScannedItem(db, "/movies/test.mkv", PARSED, PROBE);
const plan = db.prepare("SELECT status FROM review_plans WHERE item_id = ?").get(result.itemId) as any;
expect(plan.status).toBe("approved");
});
test("resets error plan to pending on rescan", () => {
const db = freshDb();
const result = upsertScannedItem(db, "/movies/test.mkv", PARSED, PROBE);
db.prepare("UPDATE review_plans SET status = 'error' WHERE item_id = ?").run(result.itemId);
upsertScannedItem(db, "/movies/test.mkv", PARSED, PROBE);
const plan = db.prepare("SELECT status FROM review_plans WHERE item_id = ?").get(result.itemId) as any;
expect(plan.status).toBe("pending");
});
test("guesses original language from default audio track", () => {
const db = freshDb();
const result = upsertScannedItem(db, "/movies/test.mkv", PARSED, PROBE);
expect(result.origLang).toBe("eng");
expect(result.origLangSource).toBe("probe");
});
test("sets series_key for episodes", () => {
const db = freshDb();
const episodeParsed: ParsedPath = {
...PARSED,
type: "Episode",
name: "Pilot",
seriesName: "Breaking Bad",
year: 2008,
seasonNumber: 1,
episodeNumber: 1,
};
const result = upsertScannedItem(db, "/tv/Breaking Bad (2008)/Season 01/file.mkv", episodeParsed, PROBE);
const item = db.prepare("SELECT series_key FROM media_items WHERE id = ?").get(result.itemId) as any;
expect(item.series_key).toBe("Breaking Bad|2008");
});
});