Discovery AniList client: drop removed recommendations (BL-0051)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
MaashkinoozheandClaude Opus 5.5 committed 2026-10-25 08:51:16 +01:00
1 parent 3e7b1ca49f
commit 60a25bacac
2 files changed
+10 -1

No files matched your search

+3 -1
View File
@@ -136,7 +136,9 @@ function createClient({ endpoint = process.env.DISCOVERY_ANILIST_URL || 'https:/
}, },
async recs(id) { async recs(id) {
const nodes = mediaOf(await post(QUERIES.recs, { id })).recommendations?.nodes; const nodes = mediaOf(await post(QUERIES.recs, { id })).recommendations?.nodes;
return entries(nodes, node => node.mediaRecommendation).filter(({ item }) => item.rating > 0) // AniList returns a null mediaRecommendation when the recommended media was removed: valid, just drop it.
const present = need(nodes).filter(node => !isObject(node) || node.mediaRecommendation !== null);
return entries(present, node => node.mediaRecommendation).filter(({ item }) => item.rating > 0)
.map(({ item, record }) => ({ anilistId: record.anilistId, rating: item.rating, record })); .map(({ item, record }) => ({ anilistId: record.anilistId, rating: item.rating, record }));
}, },
async creator(staffId) { async creator(staffId) {
+7
View File
@@ -75,6 +75,13 @@ test('requests refuse redirects', async () => {
await assert.rejects(clientFor(redirected).title(1), e => e instanceof AniListSkip && e.reason === 'upstream'); await assert.rejects(clientFor(redirected).title(1), e => e instanceof AniListSkip && e.reason === 'upstream');
}); });
test('recs drops recommendations whose media was removed', async () => {
const recs = fixture('recs');
recs.data.Media.recommendations.nodes = [recs.data.Media.recommendations.nodes[0], { rating: 10, mediaRecommendation: null }];
const out = await clientFor(() => json(recs)).recs(101);
assert.deepEqual(out.map(e => e.anilistId), [201]);
});
test('one malformed item invalidates a list response', async () => { test('one malformed item invalidates a list response', async () => {
const invalid = e => e instanceof AniListSkip && e.reason === 'invalid'; const invalid = e => e instanceof AniListSkip && e.reason === 'invalid';
const recs = fixture('recs'); const recs = fixture('recs');