// @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 BacklogCard from './BacklogCard.jsx'; vi.mock('react-i18next', () => import('../test/i18n-mock.js')); vi.mock('sonner', () => ({toast: {success: vi.fn(), error: vi.fn()}})); const game = {appid: 220, status: 'PLAYING', rating: 4, notes: 'old', priority: null}; const saveButton = () => screen.getByRole('button', {name: 'BACKLOG.SAVE'}); describe('BacklogCard', () => { beforeEach(() => { localStorage.setItem('tbp_session', '1'); globalThis.fetch = vi.fn(async (url, init) => ({ok: true, status: 200, json: async () => JSON.parse(init.body)})); }); afterEach(() => { cleanup(); localStorage.clear(); }); it('enables saving only after a change', () => { render(); expect(saveButton().disabled).toBe(true); fireEvent.click(screen.getByRole('button', {name: 'BACKLOG.RATING_STARS:5'})); expect(saveButton().disabled).toBe(false); }); it('clears the rating on a click on the current star and sends blank notes as null', async () => { const onSaved = vi.fn(); render(); fireEvent.click(screen.getByRole('button', {name: 'BACKLOG.RATING_STARS:4'})); fireEvent.change(screen.getByRole('textbox'), {target: {value: ' '}}); fireEvent.click(saveButton()); await waitFor(() => expect(onSaved).toHaveBeenCalled()); const [url, init] = fetch.mock.calls[0]; expect(url).toMatch(/\/api\/library\/games\/220\/backlog$/); expect(init.method).toBe('PUT'); expect(JSON.parse(init.body)).toEqual({status: 'PLAYING', rating: null, notes: null, priority: null}); expect(saveButton().disabled).toBe(true); }); });