feat(images): report broken covers and achievement icons
Build, Test & Push Frontend / quality-check (push) Successful in 15s
Build, Test & Push Frontend / docker (push) Successful in 22s

This commit is contained in:
lobo committed 2026-09-26 12:07:47 +02:00
1 parent ca75e6a530
commit 42ed0afe51
9 files changed
+173 -9

No files matched your search

+22
View File
@@ -4,6 +4,7 @@ import {cleanup, fireEvent, render, screen, waitFor} from '@testing-library/reac
import {MemoryRouter, Route, Routes} from 'react-router-dom';
import GameDetail from './GameDetail.jsx';
import {PreferencesProvider} from '../context/PreferencesContext.jsx';
import {resetBrokenImageReports} from '../utils/brokenImages.js';
vi.mock('react-i18next', () => import('../test/i18n-mock.js'));
vi.mock('sonner', () => ({toast: {success: vi.fn(), error: vi.fn()}}));
@@ -32,9 +33,30 @@ beforeEach(() => {
afterEach(() => {
cleanup();
localStorage.clear();
resetBrokenImageReports();
});
describe('GameDetail', () => {
it('reports a broken achievement icon once and shows the empty tile', async () => {
const achievement = (apiName) => ({apiName, displayName: apiName, unlocked: false, iconUrl: `https://x/${apiName}.jpg`,
iconGrayUrl: `https://x/${apiName}_gray.jpg`});
globalThis.fetch = vi.fn(async (url, init) => init?.method === 'POST'
? {ok: true, status: 204}
: {ok: true, status: 200, json: async () => ({...game, hasAchievements: true, statsVisible: true,
achievementsTotal: 2, achievementsUnlocked: 0, completionPercent: 0,
achievements: [achievement('A'), achievement('B')]})});
const {container} = renderDetail();
await screen.findByText('A');
container.querySelectorAll('img[src^="https://x/"]').forEach((img) => fireEvent.error(img));
const reports = fetch.mock.calls.filter(([, init]) => init?.method === 'POST');
expect(reports).toHaveLength(1);
expect(reports[0][0]).toContain('/api/library/broken-images');
expect(JSON.parse(reports[0][1].body)).toEqual({appid: 220, kind: 'ACHIEVEMENT_ICONS'});
expect(container.querySelector('img[src^="https://x/"]')).toBeNull();
});
it('links the speedrun.com page when Core found one', async () => {
globalThis.fetch = vi.fn(async () => ({ok: true, status: 200,
json: async () => ({...game, speedrunUrl: 'https://www.speedrun.com/hl2'})}));