mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-06-13 05:31:01 +00:00
Add comprehensive test infrastructure and Dark Mode tests
- Created test folder structure (__tests__, __mocks__) - Added mock contexts (Theme, BiometricAuth, Auth) - Added mock AsyncStorage - Implemented 11 passing Dark Mode tests: * Rendering tests (3 tests) * Toggle functionality tests (2 tests) * Persistence tests (2 tests) * Theme application tests (2 tests) * Edge case tests (2 tests) - Added testID props to SettingsScreen components - All tests passing (11/11) Test Coverage: - Dark Mode toggle on/off - AsyncStorage persistence - Theme color application - Rapid toggle handling - Multiple toggle calls
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
// Mock AsyncStorage for testing
|
||||
const storage: { [key: string]: string } = {};
|
||||
|
||||
export default {
|
||||
setItem: jest.fn((key: string, value: string) => {
|
||||
storage[key] = value;
|
||||
return Promise.resolve();
|
||||
}),
|
||||
getItem: jest.fn((key: string) => {
|
||||
return Promise.resolve(storage[key] || null);
|
||||
}),
|
||||
removeItem: jest.fn((key: string) => {
|
||||
delete storage[key];
|
||||
return Promise.resolve();
|
||||
}),
|
||||
clear: jest.fn(() => {
|
||||
Object.keys(storage).forEach(key => delete storage[key]);
|
||||
return Promise.resolve();
|
||||
}),
|
||||
getAllKeys: jest.fn(() => {
|
||||
return Promise.resolve(Object.keys(storage));
|
||||
}),
|
||||
multiGet: jest.fn((keys: string[]) => {
|
||||
return Promise.resolve(
|
||||
keys.map(key => [key, storage[key] || null])
|
||||
);
|
||||
}),
|
||||
multiSet: jest.fn((keyValuePairs: [string, string][]) => {
|
||||
keyValuePairs.forEach(([key, value]) => {
|
||||
storage[key] = value;
|
||||
});
|
||||
return Promise.resolve();
|
||||
}),
|
||||
multiRemove: jest.fn((keys: string[]) => {
|
||||
keys.forEach(key => delete storage[key]);
|
||||
return Promise.resolve();
|
||||
}),
|
||||
_clear: () => {
|
||||
Object.keys(storage).forEach(key => delete storage[key]);
|
||||
},
|
||||
_getStorage: () => storage,
|
||||
};
|
||||
@@ -0,0 +1,48 @@
|
||||
import React, { createContext, useContext, ReactNode } from 'react';
|
||||
import { User } from '@supabase/supabase-js';
|
||||
|
||||
// Mock Auth Context for testing
|
||||
interface AuthContextType {
|
||||
user: User | null;
|
||||
session: any | null;
|
||||
loading: boolean;
|
||||
signIn: (email: string, password: string) => Promise<{ error: any }>;
|
||||
signUp: (email: string, password: string, fullName: string) => Promise<{ error: any }>;
|
||||
signOut: () => Promise<void>;
|
||||
changePassword: (newPassword: string, currentPassword: string) => Promise<{ error: any }>;
|
||||
resetPassword: (email: string) => Promise<{ error: any }>;
|
||||
}
|
||||
|
||||
const mockUser: User = {
|
||||
id: 'test-user-id',
|
||||
email: 'test@pezkuwichain.io',
|
||||
app_metadata: {},
|
||||
user_metadata: {},
|
||||
aud: 'authenticated',
|
||||
created_at: new Date().toISOString(),
|
||||
};
|
||||
|
||||
const mockAuthContext: AuthContextType = {
|
||||
user: mockUser,
|
||||
session: null,
|
||||
loading: false,
|
||||
signIn: jest.fn().mockResolvedValue({ error: null }),
|
||||
signUp: jest.fn().mockResolvedValue({ error: null }),
|
||||
signOut: jest.fn().mockResolvedValue(undefined),
|
||||
changePassword: jest.fn().mockResolvedValue({ error: null }),
|
||||
resetPassword: jest.fn().mockResolvedValue({ error: null }),
|
||||
};
|
||||
|
||||
const AuthContext = createContext<AuthContextType>(mockAuthContext);
|
||||
|
||||
export const MockAuthProvider: React.FC<{
|
||||
children: ReactNode;
|
||||
value?: Partial<AuthContextType>
|
||||
}> = ({ children, value = {} }) => {
|
||||
const contextValue = { ...mockAuthContext, ...value };
|
||||
return <AuthContext.Provider value={contextValue}>{children}</AuthContext.Provider>;
|
||||
};
|
||||
|
||||
export const useAuth = () => useContext(AuthContext);
|
||||
|
||||
export default AuthContext;
|
||||
@@ -0,0 +1,38 @@
|
||||
import React, { createContext, useContext, ReactNode } from 'react';
|
||||
|
||||
// Mock Biometric Auth Context for testing
|
||||
interface BiometricAuthContextType {
|
||||
isBiometricSupported: boolean;
|
||||
isBiometricEnrolled: boolean;
|
||||
isBiometricAvailable: boolean;
|
||||
biometricType: 'fingerprint' | 'facial' | 'iris' | 'none';
|
||||
isBiometricEnabled: boolean;
|
||||
authenticate: () => Promise<boolean>;
|
||||
enableBiometric: () => Promise<boolean>;
|
||||
disableBiometric: () => Promise<void>;
|
||||
}
|
||||
|
||||
const mockBiometricContext: BiometricAuthContextType = {
|
||||
isBiometricSupported: true,
|
||||
isBiometricEnrolled: true,
|
||||
isBiometricAvailable: true,
|
||||
biometricType: 'fingerprint',
|
||||
isBiometricEnabled: false,
|
||||
authenticate: jest.fn().mockResolvedValue(true),
|
||||
enableBiometric: jest.fn().mockResolvedValue(true),
|
||||
disableBiometric: jest.fn().mockResolvedValue(undefined),
|
||||
};
|
||||
|
||||
const BiometricAuthContext = createContext<BiometricAuthContextType>(mockBiometricContext);
|
||||
|
||||
export const MockBiometricAuthProvider: React.FC<{
|
||||
children: ReactNode;
|
||||
value?: Partial<BiometricAuthContextType>
|
||||
}> = ({ children, value = {} }) => {
|
||||
const contextValue = { ...mockBiometricContext, ...value };
|
||||
return <BiometricAuthContext.Provider value={contextValue}>{children}</BiometricAuthContext.Provider>;
|
||||
};
|
||||
|
||||
export const useBiometricAuth = () => useContext(BiometricAuthContext);
|
||||
|
||||
export default BiometricAuthContext;
|
||||
@@ -0,0 +1,43 @@
|
||||
import React, { createContext, useContext, ReactNode } from 'react';
|
||||
|
||||
// Mock colors instead of importing from shared
|
||||
const LightColors = {
|
||||
background: '#F5F5F5',
|
||||
surface: '#FFFFFF',
|
||||
text: '#000000',
|
||||
textSecondary: '#666666',
|
||||
border: '#E0E0E0',
|
||||
};
|
||||
|
||||
// Mock Theme Context for testing
|
||||
interface ThemeContextType {
|
||||
isDarkMode: boolean;
|
||||
toggleDarkMode: () => Promise<void>;
|
||||
colors: typeof LightColors;
|
||||
fontSize: 'small' | 'medium' | 'large';
|
||||
setFontSize: (size: 'small' | 'medium' | 'large') => Promise<void>;
|
||||
fontScale: number;
|
||||
}
|
||||
|
||||
const mockThemeContext: ThemeContextType = {
|
||||
isDarkMode: false,
|
||||
toggleDarkMode: jest.fn().mockResolvedValue(undefined),
|
||||
colors: LightColors,
|
||||
fontSize: 'medium',
|
||||
setFontSize: jest.fn().mockResolvedValue(undefined),
|
||||
fontScale: 1,
|
||||
};
|
||||
|
||||
const ThemeContext = createContext<ThemeContextType>(mockThemeContext);
|
||||
|
||||
export const MockThemeProvider: React.FC<{ children: ReactNode; value?: Partial<ThemeContextType> }> = ({
|
||||
children,
|
||||
value = {}
|
||||
}) => {
|
||||
const contextValue = { ...mockThemeContext, ...value };
|
||||
return <ThemeContext.Provider value={contextValue}>{children}</ThemeContext.Provider>;
|
||||
};
|
||||
|
||||
export const useTheme = () => useContext(ThemeContext);
|
||||
|
||||
export default ThemeContext;
|
||||
Reference in New Issue
Block a user