diff --git a/frontend/src/lib/components/LanguageSwitcher.svelte.spec.ts b/frontend/src/lib/components/LanguageSwitcher.svelte.spec.ts new file mode 100644 index 00000000..41e2df24 --- /dev/null +++ b/frontend/src/lib/components/LanguageSwitcher.svelte.spec.ts @@ -0,0 +1,94 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import { cleanup, render } from 'vitest-browser-svelte'; +import { page } from 'vitest/browser'; +import LanguageSwitcher from './LanguageSwitcher.svelte'; + +const mockSetLocale = vi.hoisted(() => vi.fn()); + +vi.mock('$lib/paraglide/runtime', () => ({ + getLocale: vi.fn(() => 'de'), + setLocale: mockSetLocale +})); + +beforeEach(() => mockSetLocale.mockClear()); +afterEach(cleanup); + +// ─── inverted=true (dark background) ────────────────────────────────────── + +describe('LanguageSwitcher – inverted=true', () => { + it('active locale button has text-white and font-bold', async () => { + render(LanguageSwitcher, { inverted: true }); + + const el = await page.getByRole('button', { name: 'DE' }).element(); + + expect(el.className).toMatch(/\btext-white\b/); + expect(el.className).toMatch(/\bfont-bold\b/); + }); + + it('inactive locale buttons have text-white/70', async () => { + render(LanguageSwitcher, { inverted: true }); + + const el = await page.getByRole('button', { name: 'EN' }).element(); + + expect(el.className).toMatch(/text-white\/70/); + }); + + it('inactive locale buttons do not have font-bold', async () => { + render(LanguageSwitcher, { inverted: true }); + + const el = await page.getByRole('button', { name: 'EN' }).element(); + + expect(el.className).not.toMatch(/\bfont-bold\b/); + }); +}); + +// ─── inverted=false (light background) ───────────────────────────────────── + +describe('LanguageSwitcher – inverted=false', () => { + it('active locale button has text-ink and font-bold', async () => { + render(LanguageSwitcher, { inverted: false }); + + const el = await page.getByRole('button', { name: 'DE' }).element(); + + expect(el.className).toMatch(/\btext-ink\b/); + expect(el.className).toMatch(/\bfont-bold\b/); + }); + + it('inactive locale buttons have text-ink-3', async () => { + render(LanguageSwitcher, { inverted: false }); + + const el = await page.getByRole('button', { name: 'EN' }).element(); + + expect(el.className).toMatch(/\btext-ink-3\b/); + }); + + it('inactive locale buttons do not have text-white', async () => { + render(LanguageSwitcher, { inverted: false }); + + const el = await page.getByRole('button', { name: 'EN' }).element(); + + expect(el.className).not.toMatch(/\btext-white\b/); + }); +}); + +// ─── locale switching ────────────────────────────────────────────────────── + +describe('LanguageSwitcher – locale switching', () => { + it('calls setLocale with en when EN button is clicked', async () => { + render(LanguageSwitcher, { inverted: false }); + + const el = await page.getByRole('button', { name: 'EN' }).element(); + el.click(); + + expect(mockSetLocale).toHaveBeenCalledWith('en'); + }); + + it('calls setLocale with es when ES button is clicked', async () => { + render(LanguageSwitcher, { inverted: false }); + + const el = await page.getByRole('button', { name: 'ES' }).element(); + el.click(); + + expect(mockSetLocale).toHaveBeenCalledWith('es'); + }); +});