Public Access
LinkGameDialog (user request or auditor link), EditionsCard on the details page, LinkQueuePage and AuditLogPage for auditors with paging, hideDuplicates filter and editions badge in the library, audit menu entries, de/en texts.
96 lines
3.8 KiB
React
96 lines
3.8 KiB
React
// @vitest-environment jsdom
|
|
import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest';
|
|
import {cleanup, fireEvent, render, screen, waitFor} from '@testing-library/react';
|
|
import {MemoryRouter} from 'react-router-dom';
|
|
import LinkQueuePage from './LinkQueuePage.jsx';
|
|
import {PreferencesProvider} from '../context/PreferencesContext.jsx';
|
|
import {fetchRoutes, json} from '../test/fetchRoutes.js';
|
|
|
|
vi.mock('react-i18next', () => import('../test/i18n-mock.js'));
|
|
vi.mock('sonner', () => ({toast: {success: vi.fn(), error: vi.fn()}}));
|
|
|
|
const pair = {a: {appid: 10, name: 'Dark Souls', imageUrl: null}, b: {appid: -7, name: 'Dark Souls Remastered', imageUrl: null},
|
|
igdb: true, requests: 2, createdAt: '2026-10-01T10:00:00Z'};
|
|
|
|
const queue = (content, totalPages = 1) => json(200, {content, page: 0, size: 20, totalElements: content.length, totalPages});
|
|
|
|
const renderPage = (routes) => {
|
|
fetchRoutes(routes);
|
|
render(<MemoryRouter><PreferencesProvider><LinkQueuePage/></PreferencesProvider></MemoryRouter>);
|
|
};
|
|
|
|
beforeEach(() => {
|
|
localStorage.setItem('tbp_session', '1');
|
|
});
|
|
|
|
afterEach(() => {
|
|
cleanup();
|
|
localStorage.clear();
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
describe('LinkQueuePage', () => {
|
|
it('listsThePairWithItsBadges', async () => {
|
|
renderPage({'GET /api/library/link-queue': queue([pair])});
|
|
|
|
expect(await screen.findByText('Dark Souls')).toBeTruthy();
|
|
expect(screen.getByText('Dark Souls Remastered')).toBeTruthy();
|
|
expect(screen.getByText('LINKS.FROM_IGDB')).toBeTruthy();
|
|
expect(screen.getByText('LINKS.REQUESTED_BY:2')).toBeTruthy();
|
|
});
|
|
|
|
it('linksThePairAndLoadsTheQueueAgain', async () => {
|
|
let pending = [pair];
|
|
renderPage({
|
|
'GET /api/library/link-queue': () => queue(pending),
|
|
'POST /api/library/games/10/link': () => {
|
|
pending = [];
|
|
return json(204);
|
|
},
|
|
});
|
|
|
|
fireEvent.click(await screen.findByRole('button', {name: 'LINKS.LINK'}));
|
|
|
|
expect(await screen.findByText('LINKS.QUEUE_EMPTY')).toBeTruthy();
|
|
const post = fetch.mock.calls.find(([, init]) => init?.method === 'POST');
|
|
expect(JSON.parse(post[1].body)).toEqual({otherAppid: -7});
|
|
});
|
|
|
|
it('dismissesThePair', async () => {
|
|
renderPage({
|
|
'GET /api/library/link-queue': queue([pair]),
|
|
'DELETE /api/library/link-queue/10/-7': json(204),
|
|
});
|
|
|
|
fireEvent.click(await screen.findByRole('button', {name: 'LINKS.DISMISS'}));
|
|
|
|
await waitFor(() => expect(fetch.mock.calls.some(([url, init]) => init?.method === 'DELETE' && url.endsWith('/link-queue/10/-7'))).toBe(true));
|
|
});
|
|
|
|
it('pagesThroughTheQueue', async () => {
|
|
renderPage({'GET /api/library/link-queue': () => queue([pair], 2)});
|
|
await screen.findByText('Dark Souls');
|
|
|
|
fireEvent.click(screen.getByRole('button', {name: /ADMIN.NEXT/}));
|
|
|
|
await waitFor(() => expect(fetch.mock.calls.at(-1)[0]).toContain('page=1'));
|
|
expect(screen.getByText('LINKS.PAGE_OF')).toBeTruthy();
|
|
});
|
|
|
|
it('goesBackAPageWhenThePageIsEmpty', async () => {
|
|
renderPage({'GET /api/library/link-queue': (url) => (url.includes('page=1') ? queue([], 2) : queue([pair], 2))});
|
|
await screen.findByText('Dark Souls');
|
|
fireEvent.click(screen.getByRole('button', {name: /ADMIN.NEXT/}));
|
|
|
|
await waitFor(() => expect(fetch.mock.calls.at(-1)[0]).toContain('page=0'));
|
|
expect(fetch.mock.calls.some(([url]) => url.includes('page=1'))).toBe(true);
|
|
expect(await screen.findByText('Dark Souls')).toBeTruthy();
|
|
});
|
|
|
|
it('showsNoAccessOn403', async () => {
|
|
renderPage({'GET /api/library/link-queue': json(403, {})});
|
|
|
|
expect(await screen.findByText('LINKS.NO_ACCESS')).toBeTruthy();
|
|
});
|
|
});
|