686434f5c3
- delete server/services/jellyfin.ts, webhook.ts, mqtt.ts and their tests - strip jellyfin/mqtt imports and startup calls from index.tsx and settings.ts - remove /jellyfin, /mqtt, /mqtt/status, /mqtt/test, /jellyfin/webhook-plugin endpoints from settings router - clean ENV_MAP and isEnvConfigured of jellyfin/mqtt keys - add db/index.ts migrations for series_key, duration_seconds, scan_status, scan_error, last_scanned_at (new columns absent on older dev DBs) - move idx_media_items_series_key out of SCHEMA into migrate() so it runs after the column is added - fix all test fixtures: drop jellyfin_id/series_jellyfin_id column refs, update MediaItem/MediaStream object literals to match current types Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
68 lines
2.0 KiB
TypeScript
68 lines
2.0 KiB
TypeScript
import { Database } from "bun:sqlite";
|
|
import { describe, expect, test } from "bun:test";
|
|
import { SCHEMA } from "../../db/schema";
|
|
import { approveReady } from "../review";
|
|
|
|
function makeDb(): Database {
|
|
const db = new Database(":memory:");
|
|
for (const stmt of SCHEMA.split(";")) {
|
|
const trimmed = stmt.trim();
|
|
if (trimmed) db.run(trimmed);
|
|
}
|
|
return db;
|
|
}
|
|
|
|
function seedSortedPlan(db: Database, id: number, autoClass: "auto_heuristic" | "manual") {
|
|
db
|
|
.prepare(
|
|
"INSERT INTO media_items (id, type, name, file_path, container) VALUES (?, 'Movie', ?, ?, 'mkv')",
|
|
)
|
|
.run(id, `Item ${id}`, `/x/${id}.mkv`);
|
|
db
|
|
.prepare(
|
|
"INSERT INTO media_streams (item_id, stream_index, type, codec, language) VALUES (?, 0, 'Audio', 'eac3', 'eng')",
|
|
)
|
|
.run(id);
|
|
db
|
|
.prepare(
|
|
"INSERT INTO review_plans (item_id, status, is_noop, auto_class, sorted, apple_compat, job_type) VALUES (?, 'pending', 0, ?, 1, 'direct_play', 'copy')",
|
|
)
|
|
.run(id, autoClass);
|
|
db
|
|
.prepare(
|
|
"INSERT INTO stream_decisions (plan_id, stream_id, action, target_index) SELECT rp.id, ms.id, 'keep', 0 FROM review_plans rp, media_streams ms WHERE rp.item_id = ? AND ms.item_id = ?",
|
|
)
|
|
.run(id, id);
|
|
}
|
|
|
|
describe("approveReady", () => {
|
|
test("approves auto_heuristic only, leaves manual alone", () => {
|
|
const db = makeDb();
|
|
seedSortedPlan(db, 1, "auto_heuristic");
|
|
seedSortedPlan(db, 2, "manual");
|
|
seedSortedPlan(db, 3, "auto_heuristic");
|
|
|
|
const count = approveReady(db);
|
|
expect(count).toBe(2);
|
|
|
|
const statuses = db.prepare("SELECT item_id, status FROM review_plans ORDER BY item_id").all() as {
|
|
item_id: number;
|
|
status: string;
|
|
}[];
|
|
expect(statuses).toEqual([
|
|
{ item_id: 1, status: "approved" },
|
|
{ item_id: 2, status: "pending" },
|
|
{ item_id: 3, status: "approved" },
|
|
]);
|
|
|
|
const jobCount = (db.prepare("SELECT COUNT(*) as n FROM jobs").get() as { n: number }).n;
|
|
expect(jobCount).toBe(2);
|
|
});
|
|
|
|
test("noop when nothing is ready", () => {
|
|
const db = makeDb();
|
|
seedSortedPlan(db, 1, "manual");
|
|
expect(approveReady(db)).toBe(0);
|
|
});
|
|
});
|