d9b94bd259
- withDesktopCookie in middleware.ts setzt tessera_desktop=1 auf JEDER Antwort (Fruehausstieg, Redirects, next()), wenn ?desktop=1 anliegt - desktop-client.ts: isDesktopClient() liest das Cookie, useIsDesktopClient() kapselt es hydration-sicher per useEffect - DesktopDownloadLinks fragt /desktop/latest im Desktop-Client gar nicht erst an und rendert nichts - DesktopContextMenuGuard unterdrueckt das WebView2-Kontextmenue ausserhalb von Eingabefeldern/contenteditable, in layout.tsx eingebunden - middleware.test.ts (neu), desktop-client.test.ts (neu), desktop-context-menu-guard.test.tsx (neu), Test 4 in desktop-download-links.test.tsx — alle 417 Web-Tests und type-check gruen Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
118 lines
4.0 KiB
TypeScript
118 lines
4.0 KiB
TypeScript
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<string, unknown>;
|
|
const lookup = (path: string): string | undefined =>
|
|
path.split('.').reduce<unknown>((o, k) => (o && typeof o === 'object' ? (o as any)[k] : undefined), messages) as
|
|
| string
|
|
| undefined;
|
|
return {
|
|
useTranslations:
|
|
(ns?: string) =>
|
|
(key: string, values?: Record<string, unknown>) => {
|
|
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<typeof import('@/lib/desktop')>();
|
|
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(<DesktopDownloadLinks />);
|
|
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(<DesktopDownloadLinks />);
|
|
|
|
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(<DesktopDownloadLinks />);
|
|
|
|
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(<DesktopDownloadLinks />);
|
|
await act(async () => {});
|
|
expect(loadDesktopLatest).not.toHaveBeenCalled();
|
|
expect(container.firstChild).toBeNull();
|
|
});
|
|
});
|