125 lines
3.2 KiB
TypeScript
125 lines
3.2 KiB
TypeScript
import React from 'react';
|
|
import { describe, expect, it, vi } from 'vitest';
|
|
import { fireEvent, render, screen } from '@testing-library/react';
|
|
|
|
const updateAppearance = vi.fn();
|
|
|
|
vi.mock('@/hooks/use-appearance', () => ({
|
|
useAppearance: () => ({ appearance: 'dark', updateAppearance }),
|
|
}));
|
|
|
|
vi.mock('@/guest/i18n/useTranslation', () => ({
|
|
useTranslation: () => ({ t: (_key: string, fallback?: string) => fallback ?? _key }),
|
|
}));
|
|
|
|
vi.mock('@/guest/i18n/LocaleContext', () => ({
|
|
useLocale: () => ({ locale: 'de', availableLocales: [], setLocale: vi.fn() }),
|
|
}));
|
|
|
|
vi.mock('../context/EventDataContext', () => ({
|
|
useEventData: () => ({ token: 'demo-token' }),
|
|
}));
|
|
|
|
vi.mock('../context/GuestIdentityContext', () => ({
|
|
useOptionalGuestIdentity: () => ({ hydrated: false, name: '', setName: vi.fn(), clearName: vi.fn() }),
|
|
}));
|
|
|
|
vi.mock('@/guest/hooks/useHapticsPreference', () => ({
|
|
useHapticsPreference: () => ({ enabled: false, setEnabled: vi.fn(), supported: true }),
|
|
}));
|
|
|
|
vi.mock('@/contexts/consent', () => ({
|
|
useConsent: () => ({ preferences: { analytics: false }, savePreferences: vi.fn() }),
|
|
}));
|
|
|
|
vi.mock('react-router-dom', () => ({
|
|
Link: ({ children }: { children: React.ReactNode }) => <span>{children}</span>,
|
|
}));
|
|
|
|
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/button', () => ({
|
|
Button: ({
|
|
children,
|
|
onPress,
|
|
...rest
|
|
}: {
|
|
children: React.ReactNode;
|
|
onPress?: () => void;
|
|
}) => (
|
|
<button type="button" onClick={onPress} {...rest}>
|
|
{children}
|
|
</button>
|
|
),
|
|
}));
|
|
|
|
vi.mock('@tamagui/input', () => ({
|
|
Input: ({
|
|
value,
|
|
onChange,
|
|
onChangeText,
|
|
...rest
|
|
}: React.InputHTMLAttributes<HTMLInputElement> & { onChangeText?: (next: string) => void }) => (
|
|
<input
|
|
value={value}
|
|
onChange={(event) => {
|
|
onChange?.(event);
|
|
onChangeText?.(event.target.value);
|
|
}}
|
|
readOnly={!onChange && !onChangeText}
|
|
{...rest}
|
|
/>
|
|
),
|
|
}));
|
|
|
|
vi.mock('@tamagui/card', () => ({
|
|
Card: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
|
}));
|
|
|
|
vi.mock('@tamagui/switch', () => ({
|
|
Switch: Object.assign(
|
|
({
|
|
checked,
|
|
onCheckedChange,
|
|
'aria-label': ariaLabel,
|
|
children,
|
|
}: {
|
|
checked?: boolean;
|
|
onCheckedChange?: (next: boolean) => void;
|
|
'aria-label'?: string;
|
|
children?: React.ReactNode;
|
|
}) => (
|
|
<label>
|
|
<input
|
|
type="checkbox"
|
|
aria-label={ariaLabel}
|
|
checked={checked}
|
|
onChange={(event) => onCheckedChange?.(event.target.checked)}
|
|
/>
|
|
{children}
|
|
</label>
|
|
),
|
|
{ Thumb: ({ children }: { children?: React.ReactNode }) => <span>{children}</span> },
|
|
),
|
|
}));
|
|
|
|
import SettingsContent from '../components/SettingsContent';
|
|
|
|
describe('SettingsContent', () => {
|
|
it('toggles appearance mode', () => {
|
|
render(<SettingsContent />);
|
|
|
|
const toggle = screen.getByLabelText('Dark mode');
|
|
fireEvent.click(toggle);
|
|
|
|
expect(updateAppearance).toHaveBeenCalledWith('light');
|
|
});
|
|
});
|