test: add webhook, credits, image-cache, and metadata tests

- New webhooks.test.ts: 34 tests covering all 3 payload parsers
  (Plex/Jellyfin/Emby), toOptionalInt, and processWebhook end-to-end
  (movie/episode watch logging, deduplication, resolution failures)
- Expand credits.test.ts: 6 new tests for refreshCredits (movie/TV
  cast+crew upsert, person deduplication, cast limit, notable crew filter)
- Expand image-cache.test.ts: 8 new tests for imageCacheEnabled,
  getLocalImagePath, and loadImageBuffer error handling
- Expand metadata.test.ts: 4 new tests for ensureBrowseTitlesExist
  (shell title creation, deduplication, mixed existing/new)

304 → 345 tests passing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
jakeandClaude Opus 4.6 committed 2026-03-22 12:23:50 -04:00
1 parent 5f3e14b415
commit 554271a888
4 files changed
+873 -10

No files matched your search

+64 -1
View File
@@ -1,13 +1,20 @@
import { describe, expect, test } from "vitest";
import { beforeEach, describe, expect, test } from "vitest";
import { titles } from "@sofa/db/schema";
import { clearAllTables, insertTitle, testDb } from "@sofa/test/db";
import type { TmdbMovieDetails, TmdbTvDetails, TmdbVideo } from "@sofa/tmdb/client";
import {
ensureBrowseTitlesExist,
extractMovieContentRating,
extractTvContentRating,
pickBestTrailer,
} from "../src/metadata";
beforeEach(() => {
clearAllTables();
});
function makeVideo(overrides: Partial<TmdbVideo> = {}): TmdbVideo {
return {
id: "v1",
@@ -213,3 +220,59 @@ describe("extractTvContentRating", () => {
expect(extractTvContentRating(show)).toBeNull();
});
});
// ─── ensureBrowseTitlesExist ────────────────────────────────────────
describe("ensureBrowseTitlesExist", () => {
test("creates shell titles for new entries", () => {
const result = ensureBrowseTitlesExist([
{ tmdbId: 100, type: "movie", title: "Movie A", posterPath: "/a.jpg" },
{ tmdbId: 200, type: "tv", title: "Show B", posterPath: "/b.jpg" },
]);
expect(result.size).toBe(2);
expect(result.get("100-movie")).toBeDefined();
expect(result.get("200-tv")).toBeDefined();
const allTitles = testDb.select().from(titles).all();
expect(allTitles).toHaveLength(2);
// Shell titles have no lastFetchedAt
expect(allTitles[0].lastFetchedAt).toBeNull();
expect(allTitles[1].lastFetchedAt).toBeNull();
});
test("returns existing titles without creating duplicates", () => {
insertTitle({ id: "existing-1", tmdbId: 100, type: "movie", title: "Movie A" });
const result = ensureBrowseTitlesExist([
{ tmdbId: 100, type: "movie", title: "Movie A", posterPath: "/a.jpg" },
]);
expect(result.size).toBe(1);
expect(result.get("100-movie")?.id).toBe("existing-1");
const allTitles = testDb.select().from(titles).all();
expect(allTitles).toHaveLength(1);
});
test("handles mix of existing and new titles", () => {
insertTitle({ id: "existing-1", tmdbId: 100, type: "movie", title: "Movie A" });
const result = ensureBrowseTitlesExist([
{ tmdbId: 100, type: "movie", title: "Movie A", posterPath: "/a.jpg" },
{ tmdbId: 200, type: "tv", title: "Show B", posterPath: "/b.jpg" },
]);
expect(result.size).toBe(2);
expect(result.get("100-movie")?.id).toBe("existing-1");
expect(result.get("200-tv")).toBeDefined();
const allTitles = testDb.select().from(titles).all();
expect(allTitles).toHaveLength(2);
});
test("returns empty map for empty input", () => {
const result = ensureBrowseTitlesExist([]);
expect(result.size).toBe(0);
});
});