Public Access
feat(library): Steam wishlist tab with prices and discounts
The library page gets a Bibliothek | Wunschliste tab bar. The wishlist shows the current store price, the discount and can show only games on sale.
This commit is contained in:
1 parent
89c5ba5253
commit
aa5124ea1e
8 files changed
+281
-5
No files matched your search
@@ -0,0 +1,72 @@
|
||||
// @vitest-environment jsdom
|
||||
import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest';
|
||||
import {cleanup, fireEvent, render, screen, waitFor} from '@testing-library/react';
|
||||
import {MemoryRouter, Route, Routes, useLocation} from 'react-router-dom';
|
||||
import WishlistPage from './WishlistPage.jsx';
|
||||
|
||||
vi.mock('react-i18next', () => import('../test/i18n-mock.js'));
|
||||
|
||||
const wishlist = {games: [
|
||||
{appid: 1257610, name: 'Prison Architect 2', addedAt: '2026-01-01T00:00:00Z', price: '7,49€', originalPrice: '29,99€', discountPct: 75},
|
||||
{appid: 3012600, name: 'Coming Soon', addedAt: '2025-06-01T00:00:00Z', price: null, originalPrice: null, discountPct: 0},
|
||||
]};
|
||||
|
||||
function LoginState() {
|
||||
return <div data-testid="login">{JSON.stringify(useLocation().state)}</div>;
|
||||
}
|
||||
|
||||
const renderPage = () => render(
|
||||
<MemoryRouter initialEntries={['/wishlist']}>
|
||||
<Routes>
|
||||
<Route path="/wishlist" element={<WishlistPage/>}/>
|
||||
<Route path="/login" element={<LoginState/>}/>
|
||||
</Routes>
|
||||
</MemoryRouter>,
|
||||
);
|
||||
|
||||
describe('WishlistPage', () => {
|
||||
beforeEach(() => {
|
||||
localStorage.setItem('tbp_jwt', 'token');
|
||||
globalThis.fetch = vi.fn(async () => ({ok: true, status: 200, json: async () => wishlist}));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
localStorage.clear();
|
||||
});
|
||||
|
||||
it('shows each game with its price, and the discount for games on sale', async () => {
|
||||
renderPage();
|
||||
|
||||
expect(await screen.findByText('Prison Architect 2')).toBeTruthy();
|
||||
expect(screen.getByText('-75%')).toBeTruthy();
|
||||
expect(screen.getByText('7,49€')).toBeTruthy();
|
||||
expect(screen.getByText('29,99€')).toBeTruthy();
|
||||
expect(screen.getByText('Coming Soon')).toBeTruthy();
|
||||
expect(screen.getByText('WISHLIST.NO_PRICE')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('can show only the games on sale', async () => {
|
||||
renderPage();
|
||||
await screen.findByText('Coming Soon');
|
||||
|
||||
fireEvent.click(screen.getByRole('button', {name: /WISHLIST.ONLY_ON_SALE/}));
|
||||
|
||||
expect(screen.queryByText('Coming Soon')).toBeNull();
|
||||
expect(screen.getByText('Prison Architect 2')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('explains an empty or private wishlist', async () => {
|
||||
fetch.mockResolvedValueOnce({ok: true, status: 200, json: async () => ({games: []})});
|
||||
renderPage();
|
||||
|
||||
expect(await screen.findByText('WISHLIST.EMPTY')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('opens the login page on a 401', async () => {
|
||||
fetch.mockResolvedValueOnce({ok: false, status: 401, json: async () => ({})});
|
||||
renderPage();
|
||||
|
||||
await waitFor(() => expect(JSON.parse(screen.getByTestId('login').textContent).sessionExpired).toBe(true));
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user