import { act, cleanup, render, screen } from '@testing-library/react'; import { afterEach, describe, expect, it, vi } from 'vitest'; import { DesktopDownloadLinks } from './desktop-download-links'; /** * desktop-download-links.test — Link-Block auf der Anmeldeseite (18-03). * next-intl-Mock nach dem Muster in widget-settings-panel.test.tsx * (de.json-gestuetzt), `@/lib/desktop` gemockt mit steuerbarem * `loadDesktopLatest`; `desktopDownloadUrl` wird echt durchgereicht. */ vi.mock('next-intl', async () => { const messages = (await import('@/messages/de.json')).default as Record; const lookup = (path: string): string | undefined => path.split('.').reduce((o, k) => (o && typeof o === 'object' ? (o as any)[k] : undefined), messages) as | string | undefined; return { useTranslations: (ns?: string) => (key: string, values?: Record) => { const raw = lookup(ns ? `${ns}.${key}` : key) ?? key; return values ? raw.replace(/\{(\w+)\}/g, (_: string, n: string) => String(values[n] ?? '')) : raw; }, useLocale: () => 'de', }; }); const { loadDesktopLatest } = vi.hoisted(() => ({ loadDesktopLatest: vi.fn() })); vi.mock('@/lib/desktop', async (importOriginal) => { const actual = await importOriginal(); return { ...actual, loadDesktopLatest, }; }); function clearDesktopCookie() { document.cookie = 'tessera_desktop=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/'; } afterEach(() => { cleanup(); vi.clearAllMocks(); clearDesktopCookie(); }); const windowsFile = { name: 'Tessera-Setup-1.1.0.exe', size: 6123456, sha256: 'x', url: '/desktop/download/windows', }; const linuxFile = { name: 'Tessera-1.1.0.AppImage', size: 106461688, sha256: 'y', url: '/desktop/download/linux', }; describe('DesktopDownloadLinks (18-03)', () => { it('Test 1 (keine Daten): rendert nichts, solange null zurueckkommt', async () => { loadDesktopLatest.mockResolvedValue(null); const { container } = render(); await vi.waitFor(() => expect(loadDesktopLatest).toHaveBeenCalled()); expect(container.firstChild).toBeNull(); }); it('Test 2 (beide Plattformen): Windows-Hauptlink, Linux-Kurzlink, Version', async () => { loadDesktopLatest.mockResolvedValue({ version: '1.1.0', channel: 'beta', commit: 'abc1234', buildTime: 'x', files: { windows: windowsFile, linux: linuxFile }, }); render(); const windowsLink = await screen.findByText('Desktop-App herunterladen (Windows)'); expect(windowsLink.closest('a')).toHaveAttribute('href', 'http://localhost:3001/desktop/download/windows'); const linuxLink = screen.getByText('Linux-Version'); expect(linuxLink.closest('a')).toHaveAttribute('href', 'http://localhost:3001/desktop/download/linux'); expect(screen.getByText('Version 1.1.0')).toBeInTheDocument(); }); it('Test 3 (nur Linux): genau ein Link mit dem Linux-Text', async () => { loadDesktopLatest.mockResolvedValue({ version: '1.1.0', channel: 'beta', commit: 'abc1234', buildTime: 'x', files: { linux: linuxFile }, }); render(); const linuxLink = await screen.findByText('Desktop-App herunterladen (Linux)'); expect(linuxLink.closest('a')).toHaveAttribute('href', 'http://localhost:3001/desktop/download/linux'); expect(screen.queryByText('Linux-Version')).not.toBeInTheDocument(); }); it('Test 4 (im Desktop-Client): rendert nichts und fragt /desktop/latest gar nicht erst an', async () => { document.cookie = 'tessera_desktop=1; path=/'; loadDesktopLatest.mockResolvedValue({ version: '1.1.0', channel: 'beta', commit: 'abc1234', buildTime: 'x', files: { windows: windowsFile, linux: linuxFile }, }); const { container } = render(); await act(async () => {}); expect(loadDesktopLatest).not.toHaveBeenCalled(); expect(container.firstChild).toBeNull(); }); });