feat(achievements): dashboard card, library badge, 100 % hint and profile stats

This commit is contained in:
lobo committed 2026-09-25 10:13:31 +02:00
1 parent 2efdf64675
commit 085fcf15a4
14 files changed
+369 -19

No files matched your search

+52
View File
@@ -0,0 +1,52 @@
// @vitest-environment jsdom
import {afterEach, describe, expect, it, vi} from 'vitest';
import {cleanup, render, screen} from '@testing-library/react';
import {MemoryRouter} from 'react-router-dom';
import AchievementsCard from './AchievementsCard.jsx';
vi.mock('react-i18next', () => import('../test/i18n-mock.js'));
const summary = (extra = {}) => ({
unlocked: 24, startedGames: 4, perfectGames: 2, averageCompletion: 71.3, pendingGames: 0, hiddenGames: 0,
closest: [{appid: 20, name: 'Portal 2', unlocked: 3, total: 4}], ...extra,
});
const renderCard = (data) => render(<MemoryRouter><AchievementsCard summary={data}/></MemoryRouter>);
describe('AchievementsCard', () => {
afterEach(() => {
cleanup();
});
it('shows the totals and links the games closest to 100 %', () => {
renderCard(summary());
expect(screen.getByText('24')).toBeTruthy();
expect(screen.getByText('2')).toBeTruthy();
expect(screen.getByText('71,3 %')).toBeTruthy();
expect(screen.getByRole('link', {name: /Portal 2/}).getAttribute('href')).toBe('/library/20');
expect(screen.getByText('3 / 4')).toBeTruthy();
expect(screen.queryByText(/DASHBOARD.ACHIEVEMENTS.PENDING/)).toBeNull();
});
it('says how many games are still syncing', () => {
renderCard(summary({pendingGames: 7}));
expect(screen.getByText('DASHBOARD.ACHIEVEMENTS.PENDING:7')).toBeTruthy();
});
it('explains hidden achievements when nothing is visible', () => {
renderCard(summary({unlocked: 0, startedGames: 0, perfectGames: 0, averageCompletion: null, hiddenGames: 5,
pendingGames: 200, closest: []}));
expect(screen.getByText('DASHBOARD.ACHIEVEMENTS.HIDDEN')).toBeTruthy();
expect(screen.queryByText(/DASHBOARD.ACHIEVEMENTS.PENDING/)).toBeNull();
expect(screen.getByText('–')).toBeTruthy();
});
it('says so when nothing is unlocked yet', () => {
renderCard(summary({unlocked: 0, startedGames: 0, perfectGames: 0, averageCompletion: null, closest: []}));
expect(screen.getByText('DASHBOARD.ACHIEVEMENTS.NONE')).toBeTruthy();
});
});