From 878402e579aceacea2851b3593295ef862b7c330 Mon Sep 17 00:00:00 2001
From: Oier Bravo Urtasun
Date: Tue, 19 May 2026 04:00:35 +0200
Subject: [PATCH] feat(fase-20): /settings language selector gains 'Euskera' +
EU-01/02 e2e
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Adds the third button to the language tray in /settings; the local state
union widens to 'en' | 'es' | 'eu' (matches the new LanguageCode). Each
button carries a stable `settings-language-{code}` testid for the e2e
hooks.
Playwright `tests/e2e/euskera.test.ts`:
* EU-01 — Ana clicks the eu button; assertion lands on the selected-
state class flip (synchronous proof the click reached
switchLanguage) + a DB poll for `users.language='eu'`. We
deliberately don't assert on the sidebar nav label re-rendering:
ParaglideJS's {#key lang} re-render is wired to URL routing, not
the runtime setLanguageTag call, so the visible labels only flip on
the next navigation — a known cross-cutting gap outside Fase 20's
scope.
* EU-02 — Fresh browser context with locale + Accept-Language=eu;
Eva logs in fresh and the Fase 10.8 bootstrap path UPDATEs
users.language to 'eu'. /onboarding renders 'Ongi etorri…' — the
Basque heading the seed produces. Cleanup restores Ana to seed 'es'.
Co-Authored-By: Claude Opus 4.7
---
.../src/routes/(app)/settings/+page.svelte | 11 +-
apps/web/tests/e2e/euskera.test.ts | 137 ++++++++++++++++++
2 files changed, 143 insertions(+), 5 deletions(-)
create mode 100644 apps/web/tests/e2e/euskera.test.ts
diff --git a/apps/web/src/routes/(app)/settings/+page.svelte b/apps/web/src/routes/(app)/settings/+page.svelte
index 2189c4b..b868bc0 100644
--- a/apps/web/src/routes/(app)/settings/+page.svelte
+++ b/apps/web/src/routes/(app)/settings/+page.svelte
@@ -36,7 +36,7 @@
// Profile state loaded from public.users
let displayNameInput = $state('');
- let language = $state<'en' | 'es'>('en');
+ let language = $state<'en' | 'es' | 'eu'>('en');
let avatarType = $state<'initials' | 'emoji' | 'upload'>('initials');
let avatarEmoji = $state(null);
let avatarUrl = $state(null);
@@ -119,7 +119,7 @@
if (data) {
displayNameInput = data.display_name;
- language = data.language as 'en' | 'es';
+ language = data.language as 'en' | 'es' | 'eu';
avatarType = data.avatar_type as 'initials' | 'emoji' | 'upload';
avatarEmoji = data.avatar_emoji;
avatarUrl = data.avatar_url;
@@ -246,7 +246,7 @@
}
}
- async function switchLanguage(lang: 'en' | 'es') {
+ async function switchLanguage(lang: 'en' | 'es' | 'eu') {
language = lang;
setLanguageTag(lang);
await getSupabase()
@@ -438,9 +438,10 @@
{m.settings_language()}
- {#each [['en', 'English'], ['es', 'Español']] as [code, label]}
+ {#each [['en', 'English'], ['es', 'Español'], ['eu', 'Euskera']] as [code, label]}