feat(stats): add TMDB metadata for live-action dramas in the Library (#252)

This commit is contained in:
2026-09-21 00:10:00 -07:00
committed by GitHub
parent 4dd30f44d1
commit 1508863dbb
76 changed files with 3595 additions and 238 deletions
@@ -5,6 +5,7 @@ import { act } from 'react';
import { createRoot } from 'react-dom/client';
import { apiClient } from '../../lib/api-client';
import type { AnimeLibraryItem, StatsMergeAnimeResponse } from '../../types/stats';
import { AnimeMergeDialog } from './AnimeMergeDialog';
import { AnimeTab } from './AnimeTab';
interface TestWindow extends Window {
@@ -49,6 +50,8 @@ function libraryItem(animeId: number, title: string, episodeCount: number): Anim
animeId,
canonicalTitle: title,
anilistId: null,
tmdbId: null,
tmdbType: null,
totalSessions: 1,
totalActiveMs: 1000,
totalCards: 1,
@@ -165,6 +168,52 @@ test('AnimeTab merges the selected duplicate entries into the chosen keeper', as
}
});
test('AnimeMergeDialog refuses to merge an AniList entry with a TMDB entry', async () => {
const uninstallDom = installDom();
const originalMerge = apiClient.mergeAnime;
let mergeCalls = 0;
apiClient.mergeAnime = (async () => {
mergeCalls += 1;
throw new Error('unexpected merge');
}) as typeof apiClient.mergeAnime;
const anime = { ...libraryItem(1, 'Show', 2), anilistId: 100 };
const drama = {
...libraryItem(2, 'Show', 1),
mediaKind: 'live_action' as const,
tmdbId: 200,
tmdbType: 'tv' as const,
};
try {
const container = document.createElement('div');
document.body.append(container);
const root = createRoot(container);
await act(async () => {
root.render(
<AnimeMergeDialog entries={[anime, drama]} onClose={() => {}} onMerged={() => {}} />,
);
});
const merge = findButton(container, 'Merge Entries') as HTMLButtonElement;
assert.equal(merge.disabled, true);
assert.match(container.textContent ?? '', /cannot be merged together/);
await act(async () => {
merge.click();
});
assert.equal(mergeCalls, 0);
await act(async () => {
root.unmount();
});
} finally {
apiClient.mergeAnime = originalMerge;
uninstallDom();
}
});
test('AnimeTab keeps a suggested duplicate visible until it is reviewed and merged', async () => {
const uninstallDom = installDom();
const original = {