Public Access
perf(dashboard): load core data in parallel with /me
The dashboard no longer waits for /me before it calls the library. History loads when games-count says canSync or fails. Refs #40.
This commit is contained in:
1 parent
84b16a2ca8
commit
4b25e7f5fe
3 files changed
+40
-15
No files matched your search
@@ -32,7 +32,7 @@ const dashboardRoutes = (settings) => ({
|
||||
'GET /api/library/steam-profile': json(200, {personaName: 'Lobo', avatarUrl: avatar}),
|
||||
'GET /api/library/activity': json(200, {totalMinutes: 90, days: [{day: '2026-09-23', minutes: 0}, {day: '2026-09-24', minutes: 90}], recentGames: [
|
||||
{appid: 1086940, name: "Baldur's Gate 3", playtimeMinutes: 900, playtime2Weeks: 90, status: 'PLAYING'}]}),
|
||||
'GET /api/library/games-count': json(200, {count: 1, hasSteamId: true}),
|
||||
'GET /api/library/games-count': json(200, {count: 1, hasSteamId: true, canSync: true}),
|
||||
'GET /api/library/backlog': json(200, {games: [{appid: 7, name: 'Hades'}]}),
|
||||
'GET /api/library/achievements/summary': json(200, {unlocked: 24, startedGames: 4, perfectGames: 2,
|
||||
averageCompletion: 71.3, pendingGames: 0, hiddenGames: 0, closest: []}),
|
||||
@@ -81,6 +81,22 @@ describe('Dashboard', () => {
|
||||
});
|
||||
|
||||
const order = (container) => [...container.querySelectorAll('[data-tile]')].map((el) => el.dataset.tile);
|
||||
const asked = (path) => fetch.mock.calls.some(([url]) => url.includes(path));
|
||||
|
||||
it('asks for the library before /me answers', async () => {
|
||||
let answerMe;
|
||||
const meAnswer = new Promise((resolve) => { answerMe = resolve; });
|
||||
const routes = dashboardRoutes();
|
||||
const me = routes['GET /api/users/me'];
|
||||
fetchRoutes({...routes, 'GET /api/users/me': () => meAnswer});
|
||||
const container = renderDashboard().container;
|
||||
|
||||
await waitFor(() => expect(asked('/api/library/games')).toBe(true));
|
||||
expect(asked('/api/library/summary')).toBe(true);
|
||||
|
||||
answerMe(me);
|
||||
await waitFor(() => expect(container.querySelector(`img[src="${avatar}"]`)).not.toBeNull());
|
||||
});
|
||||
|
||||
it('shows today\'s tiles without a saved layout', async () => {
|
||||
const container = mockDashboard();
|
||||
@@ -227,20 +243,28 @@ describe('Dashboard', () => {
|
||||
it('watches the sync the server started for this visit', async () => {
|
||||
fetchRoutes({
|
||||
...dashboardRoutes(),
|
||||
'GET /api/library/games-count': json(200, {count: 1, hasSteamId: true, syncStarted: true}),
|
||||
'GET /api/library/games-count': json(200, {count: 1, hasSteamId: true, canSync: true, syncStarted: true}),
|
||||
});
|
||||
renderDashboard();
|
||||
|
||||
await waitFor(() => expect(watchSync).toHaveBeenCalledTimes(1));
|
||||
});
|
||||
|
||||
it('loads the activity and the achievements of a Steam user when games-count fails', async () => {
|
||||
fetchRoutes({...dashboardRoutes(), 'GET /api/library/games-count': json(500, {})});
|
||||
renderDashboard();
|
||||
|
||||
expect(await screen.findByText(/DASHBOARD.HELLO/)).toBeTruthy();
|
||||
await waitFor(() => expect(asked('/api/library/activity')).toBe(true));
|
||||
await waitFor(() => expect(asked('/api/library/achievements/summary')).toBe(true));
|
||||
});
|
||||
|
||||
describe('of a user with a PlayStation link and no Steam ID', () => {
|
||||
const psnOnlyRoutes = (canSync) => ({
|
||||
...dashboardRoutes(),
|
||||
'GET /api/users/me': json(200, {email: 'a@b.de', displayName: 'Lobo', settings: {}}),
|
||||
'GET /api/library/games-count': json(200, {count: 1, hasSteamId: false, canSync}),
|
||||
});
|
||||
const asked = (path) => fetch.mock.calls.some(([url]) => url.includes(path));
|
||||
|
||||
it('loads the activity, the achievements and the sync result, but no Steam profile', async () => {
|
||||
fetchRoutes(psnOnlyRoutes(true));
|
||||
|
||||
Reference in new issue
Block a user