From 5ccc6bcccc6154c57a28bc18e9db91f460428ca0 Mon Sep 17 00:00:00 2001 From: Train Chen Date: Sat, 20 Jun 2026 22:47:42 +0200 Subject: [PATCH 1/2] fix(circulation): E2E test auth setup and language filter Two blockers from test-engineer agent validation: 1. E2E circulation.spec.ts was missing auth mocks, causing 5 tests to timeout when trying to access home tile behind ProtectedRoute. Added injectMockSession() and mockAuthRoutes() to beforeEach. 2. useLoveLetters.refresh() had no language filter despite RLS comment claiming it enforces language isolation. Added .eq('language', primaryLang) for defense-in-depth and added primaryLang to dependency array. All 5 E2E tests now pass. All 359 unit tests still pass. Co-Authored-By: Claude Opus 4.7 --- e2e/circulation.spec.ts | 4 +++- src/hooks/useLoveLetters.ts | 7 ++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/e2e/circulation.spec.ts b/e2e/circulation.spec.ts index 80528e6..e013b40 100644 --- a/e2e/circulation.spec.ts +++ b/e2e/circulation.spec.ts @@ -1,5 +1,5 @@ import { test, expect, type Page } from '@playwright/test'; -import { setFrenchLanguage } from './helpers/mocks'; +import { injectMockSession, mockAuthRoutes, setFrenchLanguage } from './helpers/mocks'; // Inline mocks so the circulation hooks don't crash against an unmocked // Supabase URL on mount. Returning empty arrays / null is enough for the @@ -23,6 +23,8 @@ async function mockCirculationData(page: Page) { test.describe('Circulation of Love — navigation', () => { test.beforeEach(async ({ page }) => { + await injectMockSession(page); + await mockAuthRoutes(page); await setFrenchLanguage(page); await mockCirculationData(page); await page.goto('/'); diff --git a/src/hooks/useLoveLetters.ts b/src/hooks/useLoveLetters.ts index 13fbab3..1db0e6b 100644 --- a/src/hooks/useLoveLetters.ts +++ b/src/hooks/useLoveLetters.ts @@ -53,11 +53,12 @@ export function useLoveLetters(): UseLoveLetters { const refresh = useCallback(async () => { setLoading(true); setError(null); - // RLS already enforces language + opt-in + passed + live. We add the - // archived filter as a belt-and-suspenders client safeguard. + // RLS enforces opt-in + passed + live. We filter by language and archived + // here as client-side guards (defense-in-depth). const { data, error: selectError } = await supabase .from('love_letters') .select('*') + .eq('language', primaryLang) .eq('archived', false) .order('posted_at', { ascending: false }) .limit(50); @@ -68,7 +69,7 @@ export function useLoveLetters(): UseLoveLetters { } setCurrent((data ?? []) as LoveLetter[]); setLoading(false); - }, []); + }, [primaryLang]); useEffect(() => { refresh(); From f862583efe9191d9d0474a8c565761fc2066107b Mon Sep 17 00:00:00 2001 From: Train Chen Date: Sat, 20 Jun 2026 22:48:22 +0200 Subject: [PATCH 2/2] docs: add bug-fix notes to Circulation of Love CHANGELOG entry Co-Authored-By: Claude Opus 4.7 --- docs/CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 5f25951..6c08f59 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -30,9 +30,13 @@ What changed: Tests: - 11 new unit tests across `pseudonyms.test.ts` (8: FNV determinism, pool integrity per language, in-pool selection, stability, seed-based variation) and `usePseudonym.test.ts` (3: stable across rerenders, regenerate caps at 1, respects language pool). -- 5 new E2E specs in `circulation.spec.ts` covering: home tile visible + labelled bilingually, navigation tile→feed, non-opted-in shows Join CTA (and hides the Share button), feed→settings nav, TTL chooser exposes all three durations. +- 5 new E2E specs in `circulation.spec.ts` covering: home tile visible + labelled bilingually, navigation tile→feed, non-opted-in shows Join CTA (and hides the Share button), feed→settings nav, TTL chooser exposes all three durations. 🟡 Fixed E2E auth mock setup (was timing out before ProtectedRoute); all 5 specs now pass. - `tsc --noEmit` clean. All new vitest tests pass. +**Bug fixes discovered during test validation:** +- 🟡 **E2E test auth setup:** `circulation.spec.ts` was missing `injectMockSession()` and `mockAuthRoutes()`, causing tests to timeout at the home tile (behind ProtectedRoute). Fixed by adding both to beforeEach. +- 🟡 **Language filter missing:** `useLoveLetters.refresh()` had no client-side language filter despite RLS policy comment claiming it enforces language isolation. Added `.eq('language', primaryLang)` for defense-in-depth. Users in different primary languages now correctly see only letters in their language. + **ADHD-Friendly:** - **One thing at a time.** Each screen is single-focus (compose; or browse; or toggle settings). No multi-step share form. - **Skip is always available.** The whole feature is opt-in twice over — once via `receive_letters`, separately via `share_letters`. Defaults are both OFF.