// @vitest-environment jsdom import {afterEach, describe, expect, it, vi} from 'vitest'; import {cleanup, screen} from '@testing-library/react'; import WhatsNewPage from './WhatsNewPage.jsx'; import {fetchRoutes, json} from '../test/fetchRoutes.js'; import {renderWithProviders} from '../test/renderWithProviders.jsx'; vi.mock('react-i18next', () => import('../test/i18n-mock.js')); const entry = (id, title) => ({id, titleEn: title, titleDe: null, textEn: `${title} text`, textDe: null, publishedAt: '2026-10-01T10:00:00Z', seen: false}); const putCalls = () => fetch.mock.calls.filter(([, init]) => init?.method === 'PUT'); describe('WhatsNewPage', () => { afterEach(() => { cleanup(); vi.clearAllMocks(); }); it('lists the entries in the given order and marks them seen once', async () => { fetchRoutes({'GET /api/news': json(200, {results: [entry(2, 'Second'), entry(1, 'First')]}), 'PUT /api/news/seen': json(204)}); renderWithProviders(); await screen.findByText('Second'); expect(screen.getAllByRole('heading', {level: 3}).map((heading) => heading.textContent)).toEqual(['Second', 'First']); expect(putCalls()).toHaveLength(1); }); it('says so when there are no entries', async () => { fetchRoutes({'GET /api/news': json(200, {results: []}), 'PUT /api/news/seen': json(204)}); renderWithProviders(); expect(await screen.findByText('NEWS.EMPTY')).toBeTruthy(); }); it('shows an error and marks nothing when the load fails', async () => { fetchRoutes({'GET /api/news': json(500, {})}); renderWithProviders(); expect(await screen.findByText('NEWS.LOAD_ERROR')).toBeTruthy(); expect(putCalls()).toEqual([]); }); });