153 lines
4.0 KiB
TypeScript
153 lines
4.0 KiB
TypeScript
import React from 'react';
|
|
import { describe, expect, it, vi } from 'vitest';
|
|
import { render, screen } from '@testing-library/react';
|
|
|
|
const navigateMock = vi.fn();
|
|
const logoutMock = vi.fn();
|
|
|
|
const tMock = (
|
|
_key: string,
|
|
fallback?: string | Record<string, unknown>,
|
|
options?: Record<string, unknown>,
|
|
) => {
|
|
let value = typeof fallback === 'string' ? fallback : _key;
|
|
if (options) {
|
|
Object.entries(options).forEach(([key, val]) => {
|
|
value = value.replaceAll(`{{${key}}}`, String(val));
|
|
});
|
|
}
|
|
return value;
|
|
};
|
|
|
|
vi.mock('react-router-dom', () => ({
|
|
useNavigate: () => navigateMock,
|
|
}));
|
|
|
|
vi.mock('react-i18next', () => ({
|
|
useTranslation: () => ({ t: tMock }),
|
|
initReactI18next: {
|
|
type: '3rdParty',
|
|
init: () => undefined,
|
|
},
|
|
}));
|
|
|
|
vi.mock('../../auth/context', () => ({
|
|
useAuth: () => ({ user: { name: 'Test User', tenant_id: 123 }, logout: logoutMock }),
|
|
}));
|
|
|
|
vi.mock('../../api', () => ({
|
|
getNotificationPreferences: vi.fn().mockResolvedValue({ defaults: {}, preferences: {} }),
|
|
updateNotificationPreferences: vi.fn(),
|
|
}));
|
|
|
|
vi.mock('../components/MobileShell', () => ({
|
|
MobileShell: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
|
}));
|
|
|
|
vi.mock('../components/Primitives', () => ({
|
|
MobileCard: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
|
CTAButton: ({ label, onPress }: { label: string; onPress?: () => void }) => (
|
|
<button type="button" onClick={onPress}>
|
|
{label}
|
|
</button>
|
|
),
|
|
PillBadge: ({ children }: { children: React.ReactNode }) => <span>{children}</span>,
|
|
}));
|
|
|
|
vi.mock('../components/MobileInstallBanner', () => ({
|
|
MobileInstallBanner: () => null,
|
|
}));
|
|
|
|
vi.mock('../hooks/useAdminPushSubscription', () => ({
|
|
useAdminPushSubscription: () => ({ supported: false, permission: 'default', subscribed: false }),
|
|
}));
|
|
|
|
vi.mock('../hooks/useDevicePermissions', () => ({
|
|
useDevicePermissions: () => ({
|
|
loading: false,
|
|
notifications: 'granted',
|
|
camera: 'granted',
|
|
storage: 'available',
|
|
requestPersistentStorage: vi.fn().mockResolvedValue(false),
|
|
refresh: vi.fn(),
|
|
}),
|
|
}));
|
|
|
|
vi.mock('../hooks/useInstallPrompt', () => ({
|
|
useInstallPrompt: () => ({
|
|
isInstalled: false,
|
|
isStandalone: false,
|
|
canInstall: false,
|
|
isIos: false,
|
|
promptInstall: vi.fn(),
|
|
}),
|
|
}));
|
|
|
|
vi.mock('../hooks/useBackNavigation', () => ({
|
|
useBackNavigation: () => vi.fn(),
|
|
}));
|
|
|
|
vi.mock('../hooks/useOnlineStatus', () => ({
|
|
useOnlineStatus: () => true,
|
|
}));
|
|
|
|
vi.mock('../lib/installBanner', () => ({
|
|
getInstallBannerDismissed: () => false,
|
|
setInstallBannerDismissed: () => undefined,
|
|
shouldShowInstallBanner: () => false,
|
|
}));
|
|
|
|
vi.mock('../lib/mobileTour', () => ({
|
|
setTourSeen: () => undefined,
|
|
}));
|
|
|
|
vi.mock('../theme', () => ({
|
|
useAdminTheme: () => ({
|
|
text: '#111827',
|
|
muted: '#6b7280',
|
|
border: '#e5e7eb',
|
|
danger: '#b91c1c',
|
|
}),
|
|
}));
|
|
|
|
vi.mock('@tamagui/stacks', () => ({
|
|
YStack: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
|
XStack: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
|
}));
|
|
|
|
vi.mock('@tamagui/text', () => ({
|
|
SizableText: ({ children }: { children: React.ReactNode }) => <span>{children}</span>,
|
|
}));
|
|
|
|
vi.mock('@tamagui/group', () => ({
|
|
YGroup: Object.assign(({ children }: { children: React.ReactNode }) => <div>{children}</div>, {
|
|
Item: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
|
}),
|
|
}));
|
|
|
|
vi.mock('@tamagui/list-item', () => ({
|
|
ListItem: ({ title, subTitle }: { title?: React.ReactNode; subTitle?: React.ReactNode }) => (
|
|
<div>
|
|
{title}
|
|
{subTitle}
|
|
</div>
|
|
),
|
|
}));
|
|
|
|
vi.mock('@tamagui/switch', () => ({
|
|
Switch: Object.assign(
|
|
({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
|
{ Thumb: () => <div /> },
|
|
),
|
|
}));
|
|
|
|
import MobileSettingsPage from '../SettingsPage';
|
|
|
|
describe('MobileSettingsPage', () => {
|
|
it('renders account badge for the current user', async () => {
|
|
render(<MobileSettingsPage />);
|
|
|
|
expect(await screen.findByText('Account #123')).toBeInTheDocument();
|
|
});
|
|
});
|