mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-04-22 07:57:55 +00:00
c01abc79df
Added complete testing infrastructure with 160 passing tests across 34 suites: ✅ Test Infrastructure Setup: - Created babel.config.cjs with Expo preset - Configured jest.config.cjs with proper transformIgnorePatterns - Added jest.setup.cjs with comprehensive mocks - Added jest.setup.before.cjs for pre-setup configuration - Created __mocks__/ directory for custom mocks ✅ Component Tests (10 test files): - Badge.test.tsx (13 tests) - 100% coverage - Button.test.tsx (14 tests) - 100% statements - Card.test.tsx (7 tests) - Input.test.tsx (10 tests) - LoadingSkeleton.test.tsx (10 tests) - 93% coverage - TokenIcon.test.tsx (7 tests) - 100% coverage - BottomSheet.test.tsx (9 tests) - index.test.ts (1 test) ✅ Context Tests (4 test files): - AuthContext.test.tsx (7 tests) - PolkadotContext.test.tsx (10 tests) - BiometricAuthContext.test.tsx (11 tests) - LanguageContext.test.tsx (9 tests) ✅ Screen Tests (16 test files): - All major screens tested with provider wrappers - WelcomeScreen, SignIn/SignUp, Dashboard - Wallet, Swap, Staking, Governance - P2P, NFT Gallery, Education, Forum - BeCitizen, Security, Lock, Referral, Profile ✅ Utility Tests: - i18n/index.test.ts (4 tests) - lib/supabase.test.ts (3 tests) - theme/colors.test.ts (2 tests) ✅ App Integration Test: - App.test.tsx (3 tests) Coverage Metrics: - Statements: 37.74% (target: 35%) - Branches: 23.94% (target: 20%) - Functions: 28.53% (target: 25%) - Lines: 39.73% (target: 35%) All coverage thresholds met! ✅ Test Results: - 34/34 test suites passing - 160/160 tests passing - 17 snapshots Key Improvements: - Fixed ProfileScreen.tsx import bug (react-native import) - Added comprehensive mocks for Polkadot, Expo, Supabase - Created test-utils.tsx for provider wrappers - All tests use proper async/await patterns - Proper cleanup with React Testing Library Production Ready: Test infrastructure is complete and extensible.
214 lines
6.2 KiB
JavaScript
214 lines
6.2 KiB
JavaScript
// Jest setup for React Native testing
|
|
// @testing-library/react-native v12.4+ includes matchers by default
|
|
|
|
// Disable Expo's winter module system for tests
|
|
process.env.EXPO_USE_STATIC_RENDERING = 'true';
|
|
global.__ExpoImportMetaRegistry__ = {};
|
|
|
|
// Mock @react-navigation/native
|
|
jest.mock('@react-navigation/native', () => {
|
|
const actualNav = jest.requireActual('@react-navigation/native');
|
|
return {
|
|
...actualNav,
|
|
useNavigation: () => ({
|
|
navigate: jest.fn(),
|
|
goBack: jest.fn(),
|
|
setOptions: jest.fn(),
|
|
addListener: jest.fn(),
|
|
removeListener: jest.fn(),
|
|
}),
|
|
useRoute: () => ({
|
|
params: {},
|
|
}),
|
|
};
|
|
});
|
|
|
|
// Mock expo modules
|
|
jest.mock('expo-linear-gradient', () => ({
|
|
LinearGradient: 'LinearGradient',
|
|
}));
|
|
|
|
jest.mock('expo-secure-store', () => ({
|
|
setItemAsync: jest.fn(() => Promise.resolve()),
|
|
getItemAsync: jest.fn(() => Promise.resolve(null)),
|
|
deleteItemAsync: jest.fn(() => Promise.resolve()),
|
|
}));
|
|
|
|
jest.mock('expo-local-authentication', () => ({
|
|
authenticateAsync: jest.fn(() =>
|
|
Promise.resolve({ success: true })
|
|
),
|
|
hasHardwareAsync: jest.fn(() => Promise.resolve(true)),
|
|
isEnrolledAsync: jest.fn(() => Promise.resolve(true)),
|
|
supportedAuthenticationTypesAsync: jest.fn(() => Promise.resolve([1])), // 1 = FINGERPRINT
|
|
AuthenticationType: {
|
|
FINGERPRINT: 1,
|
|
FACIAL_RECOGNITION: 2,
|
|
IRIS: 3,
|
|
},
|
|
}));
|
|
|
|
// Mock AsyncStorage
|
|
jest.mock('@react-native-async-storage/async-storage', () =>
|
|
require('@react-native-async-storage/async-storage/jest/async-storage-mock')
|
|
);
|
|
|
|
// Mock Polkadot.js
|
|
jest.mock('@polkadot/api', () => ({
|
|
ApiPromise: {
|
|
create: jest.fn(() =>
|
|
Promise.resolve({
|
|
isReady: Promise.resolve(true),
|
|
query: {},
|
|
tx: {},
|
|
rpc: {},
|
|
disconnect: jest.fn(),
|
|
})
|
|
),
|
|
},
|
|
WsProvider: jest.fn(),
|
|
}));
|
|
|
|
// Mock Supabase
|
|
jest.mock('./src/lib/supabase', () => ({
|
|
supabase: {
|
|
auth: {
|
|
signInWithPassword: jest.fn(),
|
|
signUp: jest.fn(),
|
|
signOut: jest.fn(),
|
|
getSession: jest.fn(() => Promise.resolve({ data: { session: null }, error: null })),
|
|
onAuthStateChange: jest.fn(() => ({
|
|
data: {
|
|
subscription: {
|
|
unsubscribe: jest.fn(),
|
|
},
|
|
},
|
|
})),
|
|
},
|
|
from: jest.fn(() => ({
|
|
select: jest.fn().mockReturnThis(),
|
|
insert: jest.fn().mockReturnThis(),
|
|
update: jest.fn().mockReturnThis(),
|
|
delete: jest.fn().mockReturnThis(),
|
|
eq: jest.fn().mockReturnThis(),
|
|
order: jest.fn().mockReturnThis(),
|
|
single: jest.fn().mockReturnThis(),
|
|
})),
|
|
},
|
|
}));
|
|
|
|
// Mock shared blockchain utilities
|
|
jest.mock('../shared/blockchain/polkadot', () => ({
|
|
PEZKUWI_NETWORK: {
|
|
name: 'Pezkuwi',
|
|
endpoint: 'wss://beta-rpc.pezkuwi.art',
|
|
chainId: 'pezkuwi',
|
|
},
|
|
BLOCKCHAIN_ENDPOINTS: {
|
|
mainnet: 'wss://mainnet.pezkuwichain.io',
|
|
testnet: 'wss://ws.pezkuwichain.io',
|
|
local: 'ws://127.0.0.1:9944',
|
|
},
|
|
DEFAULT_ENDPOINT: 'ws://127.0.0.1:9944',
|
|
getExplorerUrl: jest.fn((txHash) => `https://explorer.pezkuwichain.app/tx/${txHash}`),
|
|
}));
|
|
|
|
// Mock shared DEX utilities
|
|
jest.mock('../shared/utils/dex', () => ({
|
|
formatTokenBalance: jest.fn((amount, decimals) => '0.00'),
|
|
parseTokenInput: jest.fn((input, decimals) => '0'),
|
|
calculatePriceImpact: jest.fn(() => '0'),
|
|
getAmountOut: jest.fn(() => '0'),
|
|
calculateMinAmount: jest.fn((amount, slippage) => '0'),
|
|
fetchPools: jest.fn(() => Promise.resolve([])),
|
|
fetchUserPositions: jest.fn(() => Promise.resolve([])),
|
|
}));
|
|
|
|
// Mock shared P2P fiat utilities
|
|
jest.mock('../shared/lib/p2p-fiat', () => ({
|
|
getActiveOffers: jest.fn(() => Promise.resolve([])),
|
|
createOffer: jest.fn(() => Promise.resolve({ id: '123' })),
|
|
acceptOffer: jest.fn(() => Promise.resolve(true)),
|
|
}));
|
|
|
|
// Mock shared i18n module
|
|
jest.mock('../shared/i18n', () => ({
|
|
translations: {
|
|
en: { welcome: 'Welcome' },
|
|
tr: { welcome: 'Hoş geldiniz' },
|
|
kmr: { welcome: 'Bi xêr hatî' },
|
|
ckb: { welcome: 'بەخێربێن' },
|
|
ar: { welcome: 'مرحبا' },
|
|
fa: { welcome: 'خوش آمدید' },
|
|
},
|
|
LANGUAGES: [
|
|
{ code: 'en', name: 'English', nativeName: 'English', rtl: false },
|
|
{ code: 'tr', name: 'Turkish', nativeName: 'Türkçe', rtl: false },
|
|
{ code: 'kmr', name: 'Kurdish Kurmanji', nativeName: 'Kurmancî', rtl: false },
|
|
{ code: 'ckb', name: 'Kurdish Sorani', nativeName: 'سۆرانی', rtl: true },
|
|
{ code: 'ar', name: 'Arabic', nativeName: 'العربية', rtl: true },
|
|
{ code: 'fa', name: 'Persian', nativeName: 'فارسی', rtl: true },
|
|
],
|
|
DEFAULT_LANGUAGE: 'en',
|
|
LANGUAGE_STORAGE_KEY: '@language',
|
|
isRTL: jest.fn((code) => ['ckb', 'ar', 'fa'].includes(code)),
|
|
}));
|
|
|
|
// Mock shared wallet utilities (handles import.meta)
|
|
jest.mock('../shared/lib/wallet', () => ({
|
|
formatBalance: jest.fn((amount, decimals) => '0.00'),
|
|
parseBalance: jest.fn((amount) => '0'),
|
|
NETWORK_ENDPOINTS: {
|
|
local: 'ws://127.0.0.1:9944',
|
|
testnet: 'wss://testnet.pezkuwichain.io',
|
|
mainnet: 'wss://mainnet.pezkuwichain.io',
|
|
staging: 'wss://staging.pezkuwichain.io',
|
|
beta: 'wss://rpc.pezkuwichain.io:9944',
|
|
},
|
|
}));
|
|
|
|
// Mock shared staking utilities (handles import.meta)
|
|
jest.mock('../shared/lib/staking', () => ({
|
|
formatBalance: jest.fn((amount) => '0.00'),
|
|
NETWORK_ENDPOINTS: {},
|
|
}));
|
|
|
|
// Mock shared citizenship workflow (handles polkadot/extension-dapp)
|
|
jest.mock('../shared/lib/citizenship-workflow', () => ({
|
|
createCitizenshipRequest: jest.fn(() => Promise.resolve({ id: '123' })),
|
|
}));
|
|
|
|
// Mock react-i18next for i18n initialization
|
|
jest.mock('react-i18next', () => ({
|
|
...jest.requireActual('react-i18next'),
|
|
useTranslation: () => ({
|
|
t: (key) => key,
|
|
i18n: {
|
|
language: 'en',
|
|
changeLanguage: jest.fn(() => Promise.resolve()),
|
|
isInitialized: true,
|
|
},
|
|
}),
|
|
initReactI18next: {
|
|
type: '3rdParty',
|
|
init: jest.fn(),
|
|
},
|
|
}));
|
|
|
|
// Mock i18next
|
|
jest.mock('i18next', () => ({
|
|
...jest.requireActual('i18next'),
|
|
init: jest.fn(() => Promise.resolve()),
|
|
changeLanguage: jest.fn(() => Promise.resolve()),
|
|
use: jest.fn(function () { return this; }),
|
|
language: 'en',
|
|
isInitialized: true,
|
|
}));
|
|
|
|
// Silence console warnings in tests
|
|
global.console = {
|
|
...console,
|
|
warn: jest.fn(),
|
|
error: jest.fn(),
|
|
};
|