import { cleanup, render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { afterEach, describe, expect, it, vi } from 'vitest'; import { LocaleSwitcher } from './locale-switcher'; /** * locale-switcher.test — SameSite-Luecke im Sprachumschalter-Cookie * (quick-260921-i8x, Task 3 Teil C, T-i8x-05, RED first). * * Muster: header.test.tsx fuer next-intl/next-navigation-Mocks. Der Setter * von `document.cookie` wird per `Object.defineProperty` durch eine * Attrappe ersetzt, die jede geschriebene Zeichenkette sammelt — vor der * Aenderung faellt nur die SameSite-Zusicherung durch, das ist beabsichtigt * und zeigt genau die Luecke (T-i8x-05). */ vi.mock('next-intl', () => ({ useTranslations: () => (key: string) => { const translations: Record = { de: 'Deutsch', en: 'English', }; return translations[key] ?? key; }, useLocale: () => 'de', })); const refreshMock = vi.fn(); vi.mock('next/navigation', () => ({ useRouter: () => ({ refresh: refreshMock }), })); afterEach(() => { cleanup(); vi.clearAllMocks(); }); describe('LocaleSwitcher', () => { it('schreibt beim Klick genau ein Cookie mit NEXT_LOCALE, path=/, max-age=31536000 und SameSite=Lax', async () => { const writtenCookies: string[] = []; Object.defineProperty(document, 'cookie', { configurable: true, get: () => '', set: (value: string) => { writtenCookies.push(value); }, }); const user = userEvent.setup(); render(); await user.click(screen.getByRole('button')); expect(writtenCookies).toHaveLength(1); const written = writtenCookies[0]; expect(written).toContain('NEXT_LOCALE=en'); expect(written).toContain('path=/'); expect(written).toContain('max-age=31536000'); expect(written).toContain('SameSite=Lax'); }); });