Public Access
84 lines
3.6 KiB
React
84 lines
3.6 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 {toast} from 'sonner';
|
|
import GameMergeDialog from './GameMergeDialog.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 hades = {appid: 1145360, name: 'Hades'};
|
|
const hit = (appid, name) => ({appid, igdbId: Math.abs(appid), name, year: 2020, imageUrl: null,
|
|
platforms: ['Switch'], inLibrary: false, inCatalog: true});
|
|
|
|
function renderDialog(game, post, results) {
|
|
fetchRoutes({
|
|
'GET /api/library/game-search': json(200, {available: true, results}),
|
|
[`POST /api/library/games/${game.appid}/merge`]: post,
|
|
});
|
|
const onMerged = vi.fn();
|
|
render(<MemoryRouter><GameMergeDialog game={game} open onOpenChange={vi.fn()} onMerged={onMerged}/></MemoryRouter>);
|
|
return onMerged;
|
|
}
|
|
|
|
const search = (value) => fireEvent.change(screen.getByRole('searchbox'), {target: {value}});
|
|
|
|
beforeEach(() => {
|
|
localStorage.setItem('tbp_session', '1');
|
|
});
|
|
|
|
afterEach(() => {
|
|
cleanup();
|
|
localStorage.clear();
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
describe('GameMergeDialog', () => {
|
|
it('merges the picked game after the confirm step', async () => {
|
|
const onMerged = renderDialog(hades, json(200, {appid: 1145360}),
|
|
[hit(1145360, 'Hades'), hit(-113112, 'Hades (Switch)'), hit(1145350, 'Hades II'),
|
|
{...hit(-4711, 'Hades Fan Remake'), inCatalog: false}]);
|
|
search('hades');
|
|
|
|
const offered = await screen.findByRole('button', {name: /Hades \(Switch\)/});
|
|
// The page's own game, other Steam games and games not in ToBePlayed are not offered.
|
|
expect(screen.queryByRole('button', {name: /^Hades \(2020\)/})).toBeNull();
|
|
expect(screen.queryByRole('button', {name: /Hades II/})).toBeNull();
|
|
expect(screen.queryByRole('button', {name: /Fan Remake/})).toBeNull();
|
|
fireEvent.click(offered);
|
|
expect(fetch).toHaveBeenCalledTimes(1);
|
|
fireEvent.click(screen.getByRole('button', {name: 'MERGE.CONFIRM_BUTTON'}));
|
|
|
|
await waitFor(() => expect(onMerged).toHaveBeenCalledWith(1145360));
|
|
const [url, init] = fetch.mock.calls[1];
|
|
expect(url).toContain('/api/library/games/1145360/merge');
|
|
expect(JSON.parse(init.body)).toEqual({otherAppid: -113112});
|
|
expect(toast.success).toHaveBeenCalledWith('MERGE.DONE');
|
|
});
|
|
|
|
it('goes back from the confirm step without merging', async () => {
|
|
renderDialog(hades, json(200, {}), [hit(-113112, 'Hades (Switch)')]);
|
|
search('hades');
|
|
|
|
fireEvent.click(await screen.findByRole('button', {name: /Hades \(Switch\)/}));
|
|
fireEvent.click(screen.getByRole('button', {name: 'MERGE.BACK'}));
|
|
|
|
expect(await screen.findByRole('searchbox')).toBeTruthy();
|
|
expect(fetch).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('says why Core refused the merge', async () => {
|
|
const onMerged = renderDialog({appid: -113112, name: 'Hades (Switch)'},
|
|
json(404, {code: 'GAME_NOT_FOUND'}), [hit(1145360, 'Hades')]);
|
|
search('hades');
|
|
|
|
fireEvent.click(await screen.findByRole('button', {name: /Hades \(2020\)/}));
|
|
fireEvent.click(screen.getByRole('button', {name: 'MERGE.CONFIRM_BUTTON'}));
|
|
|
|
await waitFor(() => expect(toast.error).toHaveBeenCalledWith('MERGE.ERROR.GAME_NOT_FOUND'));
|
|
expect(onMerged).not.toHaveBeenCalled();
|
|
});
|
|
});
|