import React from 'react'; import { describe, expect, it, vi } from 'vitest'; import { act, fireEvent, render, screen, waitFor } from '@testing-library/react'; const backMock = vi.fn(); vi.mock('../hooks/useBackNavigation', () => ({ useBackNavigation: () => backMock, })); vi.mock('../../api', () => ({ fetchTenantProfile: vi.fn(), updateTenantProfile: vi.fn(), getTenantPackagesOverview: vi.fn(), getTenantSettings: vi.fn(), updateTenantSettings: vi.fn(), })); vi.mock('react-hot-toast', () => ({ default: { error: vi.fn(), success: vi.fn(), }, })); vi.mock('../components/MobileShell', () => ({ MobileShell: ({ children }: { children: React.ReactNode }) =>
{children}
, })); vi.mock('../components/Primitives', () => ({ MobileCard: ({ children }: { children: React.ReactNode }) =>
{children}
, PillBadge: ({ children }: { children: React.ReactNode }) =>
{children}
, CTAButton: ({ label, onPress, disabled, }: { label: string; onPress?: () => void; disabled?: boolean; }) => ( ), })); vi.mock('../components/FormControls', () => ({ MobileField: ({ children }: { children: React.ReactNode }) =>
{children}
, MobileInput: ({ hasError, compact, ...props }: React.InputHTMLAttributes & { hasError?: boolean; compact?: boolean }) => ( ), MobileColorInput: (props: React.InputHTMLAttributes) => , MobileSelect: ({ children, ...props }: { children: React.ReactNode }) => , })); vi.mock('@tamagui/stacks', () => ({ YStack: ({ children }: { children: React.ReactNode }) =>
{children}
, XStack: ({ children }: { children: React.ReactNode }) =>
{children}
, })); vi.mock('@tamagui/text', () => ({ SizableText: ({ children }: { children: React.ReactNode }) => {children}, })); vi.mock('@tamagui/react-native-web-lite', () => ({ Pressable: ({ children, ...props }: { children: React.ReactNode } & React.ButtonHTMLAttributes) => ( ), })); vi.mock('../theme', () => ({ useAdminTheme: () => ({ text: '#111827', muted: '#6b7280', subtle: '#94a3b8', danger: '#b91c1c', border: '#e5e7eb', surface: '#ffffff', primary: '#ff5a5f', accentSoft: '#fde7ea', glassSurface: 'rgba(255,255,255,0.8)', glassSurfaceStrong: 'rgba(255,255,255,0.9)', glassBorder: 'rgba(229,231,235,0.7)', glassShadow: 'rgba(15,23,42,0.14)', appBackground: 'linear-gradient(180deg, #f7fafc, #eef3f7)', }), })); import { fetchTenantProfile, updateTenantProfile, getTenantPackagesOverview, getTenantSettings } from '../../api'; import MobileProfileAccountPage from '../ProfileAccountPage'; const profileFixture = { id: 1, name: 'Test Admin', email: 'admin@example.com', preferred_locale: null, email_verified: true, email_verified_at: '2024-01-02T00:00:00.000Z', }; describe('MobileProfileAccountPage', () => { beforeEach(() => { vi.mocked(getTenantPackagesOverview).mockResolvedValue({ packages: [], activePackage: { branding_allowed: false }, }); vi.mocked(getTenantSettings).mockResolvedValue({ id: 1, settings: {}, updated_at: null }); }); it('submits account updates with name, email, and locale', async () => { vi.mocked(fetchTenantProfile).mockResolvedValue(profileFixture); vi.mocked(updateTenantProfile).mockResolvedValue(profileFixture); await act(async () => { render(); }); await screen.findByDisplayValue('Test Admin'); await act(async () => { fireEvent.click(screen.getByText('profile.actions.save')); }); expect(updateTenantProfile).toHaveBeenCalledWith({ name: 'Test Admin', email: 'admin@example.com', preferred_locale: null, }); }); it('submits password updates when all password fields are provided', async () => { vi.mocked(fetchTenantProfile).mockResolvedValue(profileFixture); vi.mocked(updateTenantProfile).mockResolvedValue(profileFixture); await act(async () => { render(); }); await screen.findByDisplayValue('Test Admin'); const passwordInputs = screen.getAllByPlaceholderText('••••••••'); await act(async () => { fireEvent.change(passwordInputs[0], { target: { value: 'old-pass' } }); fireEvent.change(passwordInputs[1], { target: { value: 'new-pass-123' } }); fireEvent.change(passwordInputs[2], { target: { value: 'new-pass-123' } }); }); await waitFor(() => { expect(screen.getByText('profile.actions.updatePassword')).not.toBeDisabled(); }); await act(async () => { fireEvent.click(screen.getByText('profile.actions.updatePassword')); }); expect(updateTenantProfile).toHaveBeenCalledWith({ name: 'Test Admin', email: 'admin@example.com', preferred_locale: null, current_password: 'old-pass', password: 'new-pass-123', password_confirmation: 'new-pass-123', }); }); });