From 543be4becd5f01655ca6bab1e6b3ba97e9a447aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Sat, 19 Sep 2026 05:22:43 +0000 Subject: [PATCH] test(mobile): pin Arabic rendering of the account settings screen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Explorer finding: account-settings-arabic: The Account screen is completely blank — no title, no rows, no tab bar — so the Arabic settings content the user navigated to is missing from the render. The user-agent explorer found this while using the app like a user. One finding per item; the explorer never edits product code. Flow: account-settings-arabic Found on revision: fd04ca1ef Repro: 1. open the app on emulator-5602 2. reach the screen the capture names (account-settings-arabic) 3. the capture shows the defect named below Observed: The Account screen is completely blank — no title, no rows, no tab bar — so the Arabic settings content the user navigated to is missing from the render. Expected: the screen renders without this defect Evidence (from the device run): - ~/.local/share/kwf/findings/explorer-account-settings-arabic-the-account-screen-is-co-fe2e15fe/account-settings-arabic.png --- ...nt-settings-screen.arabic.mounted.test.tsx | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 apps/mobile/src/components/account-settings-screen.arabic.mounted.test.tsx diff --git a/apps/mobile/src/components/account-settings-screen.arabic.mounted.test.tsx b/apps/mobile/src/components/account-settings-screen.arabic.mounted.test.tsx new file mode 100644 index 0000000000..070e527a61 --- /dev/null +++ b/apps/mobile/src/components/account-settings-screen.arabic.mounted.test.tsx @@ -0,0 +1,104 @@ +import { act, type ReactTestRenderer } from '@/test/renderer'; +import { afterAll, beforeEach, describe, expect, it, vi } from 'vitest'; + +import { i18n } from '@/i18n'; +import { AccountSettingsScreen } from '@/components/account-settings-screen'; +import { renderWithProviders } from '@/test/render-with-providers'; + +/** + * Arabic-render regression check for the Account settings screen. + * + * An explorer capture named `account-settings-arabic` reported the screen as + * blank with no title, rows, or tab bar. The screen's own render path has no + * language or direction branch, so this test pins the Arabic output: the header + * title and every row title must come from the Arabic catalog, and the + * Language row must name the active language in Arabic. + */ + +const push = vi.hoisted(() => vi.fn()); +const setLanguagePickerBridge = vi.hoisted(() => vi.fn()); + +vi.mock('react-native', () => ({ + View: 'View', +})); +vi.mock('expo-router', () => ({ + useRouter: () => ({ push }), +})); +vi.mock('@/components/ui/icons', () => ({ + Globe: 'Globe', + Shield: 'Shield', + Smartphone: 'Smartphone', +})); +vi.mock('@/components/screen-header', () => ({ ScreenHeader: 'ScreenHeader' })); +vi.mock('@/components/tab-screen', () => ({ TabScreenScrollView: 'ScrollView' })); +vi.mock('@/components/ui/configure-row', () => ({ ConfigureRow: 'ConfigureRow' })); +vi.mock('@/lib/auth/push-registration-reconciliation', () => ({ + attemptPushRegistrationReconciliation: vi.fn(), +})); +vi.mock('@/lib/hooks/use-current-user-id', () => ({ + useCurrentUserId: () => ({ userId: 'user-1' }), +})); +vi.mock('@/lib/hooks/use-language-preference', () => ({ + getResolvedLanguage: () => 'ar', + useLanguagePreference: () => ({ preference: 'ar', hasLoaded: true }), +})); +vi.mock('@/lib/picker-bridge', () => ({ + setLanguagePickerBridge, +})); +vi.mock('@/lib/hooks/use-trusted-hosts', () => ({ + useTrustedHosts: () => ({ trustedHosts: [], hasLoaded: true }), +})); + +let view: Awaited> | undefined = undefined; +async function mountAccount(): Promise { + view = await renderWithProviders(); + await act(async () => { + await vi.dynamicImportSettled(); + }); + return view.renderer; +} +function findConfigureRow(renderer: ReactTestRenderer, title: string) { + const rows = renderer.root.findAll( + node => typeof node.type === 'string' && (node.type as string) === 'ConfigureRow' + ); + const row = rows.find(item => item.props.title === title); + if (!row) { + throw new Error(`ConfigureRow for ${title} not found`); + } + return row; +} + +beforeEach(() => { + vi.stubGlobal('IS_REACT_ACT_ENVIRONMENT', true); + vi.resetAllMocks(); +}); + +afterAll(async () => { + await i18n.changeLanguage('en'); +}); + +describe('AccountSettingsScreen in Arabic', () => { + it('renders the Arabic header title and all three row titles', async () => { + await i18n.changeLanguage('ar'); + + const renderer = await mountAccount(); + + expect(renderer.root.findByType('ScreenHeader').props.title).toBe('الحساب'); + expect(findConfigureRow(renderer, 'اللغة').props).toMatchObject({ subtitle: 'العربية' }); + expect(findConfigureRow(renderer, 'المضيفون الموثوقون')).toBeDefined(); + expect(findConfigureRow(renderer, 'جلسات الأجهزة')).toBeDefined(); + }); + + it('still opens the language picker from the Arabic Language row', async () => { + await i18n.changeLanguage('ar'); + + const renderer = await mountAccount(); + + act(() => { + (findConfigureRow(renderer, 'اللغة').props.onPress as () => void)(); + }); + + expect(push).toHaveBeenCalledWith('/(app)/language-picker'); + expect(setLanguagePickerBridge).toHaveBeenCalledTimes(1); + }); +});