Files
ToBePlayed-Frontend/src/pages/AdminUsersPage.test.jsx
T
lobo afe00ceae9
Build, Test & Push Frontend / quality-check (push) Successful in 17s
Build, Test & Push Frontend / docker (push) Successful in 28s
feat(admin): add the admin users page and view as
2026-09-27 12:18:10 +02:00

98 lines
4.3 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 AdminUsersPage from './AdminUsersPage.jsx';
import {PreferencesProvider} from '../context/PreferencesContext.jsx';
vi.mock('react-i18next', () => import('../test/i18n-mock.js'));
vi.mock('sonner', () => ({toast: {success: vi.fn(), error: vi.fn()}}));
const PLAYER = {
id: 7, email: 'player@example.com', displayName: 'Player', role: 'USER', registrationDate: '2026-09-01T10:00:00',
lastLoginDate: null, steamLinked: true, blocked: false, deletedAt: null,
};
const ADMIN = {...PLAYER, id: 1, email: 'admin@example.com', role: 'PLATFORM_ADMIN', steamLinked: false};
const page = (content, totalPages = 1) => ({content, page: 0, size: 20, totalElements: content.length, totalPages});
const answer = (status, body) => ({ok: status < 300, status, headers: new Headers(), json: async () => body});
const renderPage = () => render(<MemoryRouter><PreferencesProvider><AdminUsersPage/></PreferencesProvider></MemoryRouter>);
const calls = (method) => fetch.mock.calls.filter(([, init]) => (init?.method ?? 'GET') === method);
describe('AdminUsersPage', () => {
beforeEach(() => {
localStorage.setItem('tbp_session', '1');
globalThis.fetch = vi.fn(async (url, init) => (init?.method ? answer(204) : answer(200, page([ADMIN, PLAYER]))));
});
afterEach(() => {
cleanup();
localStorage.clear();
vi.clearAllMocks();
});
it('lists the users and offers no action on an admin', async () => {
renderPage();
expect(await screen.findByText('player@example.com')).toBeTruthy();
expect(screen.getByText('admin@example.com')).toBeTruthy();
expect(screen.getAllByRole('button', {name: 'ADMIN.BLOCK'})).toHaveLength(1);
expect(screen.getByText('ADMIN.STEAM')).toBeTruthy();
});
it('searches by the typed text from the first page', async () => {
renderPage();
await screen.findByText('player@example.com');
fireEvent.change(screen.getByPlaceholderText('ADMIN.SEARCH'), {target: {value: ' play '}});
fireEvent.submit(screen.getByPlaceholderText('ADMIN.SEARCH').closest('form'));
await waitFor(() => expect(calls('GET').at(-1)[0]).toContain('query=play&page=0'));
});
it('blocks a user after the confirm and loads the list again', async () => {
renderPage();
fireEvent.click(await screen.findByRole('button', {name: 'ADMIN.BLOCK'}));
fireEvent.click(screen.getAllByRole('button', {name: 'ADMIN.BLOCK'}).at(-1));
await waitFor(() => expect(toast.success).toHaveBeenCalledWith('ADMIN.DONE_BLOCK'));
const [url, init] = calls('PUT')[0];
expect(url).toMatch(/\/api\/admin\/users\/7\/blocked$/);
expect(JSON.parse(init.body)).toEqual({blocked: true});
expect(calls('GET')).toHaveLength(2);
});
it('deletes only after the email is typed', async () => {
renderPage();
fireEvent.click(await screen.findByRole('button', {name: 'ADMIN.DELETE'}));
const confirm = () => screen.getAllByRole('button', {name: 'ADMIN.DELETE'}).at(-1);
expect(confirm().disabled).toBe(true);
fireEvent.change(screen.getByLabelText('ADMIN.TYPE_EMAIL'), {target: {value: 'PLAYER@example.com'}});
fireEvent.click(confirm());
await waitFor(() => expect(calls('DELETE')[0][0]).toMatch(/\/api\/admin\/users\/7$/));
});
it('shows the reason when Auth refuses', async () => {
fetch.mockImplementation(async (url, init) => (init?.method
? answer(409, {code: 'TARGET_IS_ADMIN'}) : answer(200, page([PLAYER]))));
renderPage();
fireEvent.click(await screen.findByRole('button', {name: 'ADMIN.BLOCK'}));
fireEvent.click(screen.getAllByRole('button', {name: 'ADMIN.BLOCK'}).at(-1));
await waitFor(() => expect(toast.error).toHaveBeenCalledWith('ADMIN.ERROR_TARGET_IS_ADMIN'));
});
it('says no access to a user without the admin role', async () => {
fetch.mockResolvedValue(answer(403, {}));
renderPage();
expect(await screen.findByText('ADMIN.NO_ACCESS')).toBeTruthy();
});
});