mirror of
https://github.com/selfxyz/self.git
synced 2026-01-09 22:58:20 -05:00
dev fixes for release 2.9.1 (#1428)
* update lock * fix types * bump version * fix nested react requires * fix heavy tests * address fake mocks * fix test * remove last borked react test
This commit is contained in:
@@ -118,26 +118,83 @@ vi.mock('react-native', () => ({
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Always use ES6 `import` statements** - Never use `require('react-native')` in test files
|
||||
1. **Always use ES6 `import` statements** - Never use `require('react')` or `require('react-native')` in test files
|
||||
2. **Put all imports at the top of the file** - No dynamic imports in hooks
|
||||
3. **Avoid `jest.resetModules()`** - Only use when absolutely necessary for module initialization tests
|
||||
4. **Use setup file mocks** - React Native is already mocked in `jest.setup.js` (Jest) or `tests/setup.ts` (Vitest)
|
||||
|
||||
## Automated Enforcement
|
||||
|
||||
The project has multiple layers of protection against nested require() patterns:
|
||||
|
||||
### 1. ESLint Rule (app/.eslintrc.cjs)
|
||||
|
||||
ESLint will fail on `require('react')` and `require('react-native')` in test files:
|
||||
|
||||
```javascript
|
||||
'no-restricted-syntax': [
|
||||
'error',
|
||||
{
|
||||
selector: "CallExpression[callee.name='require'][arguments.0.value='react']",
|
||||
message: "Do not use require('react') in tests..."
|
||||
},
|
||||
{
|
||||
selector: "CallExpression[callee.name='require'][arguments.0.value='react-native']",
|
||||
message: "Do not use require('react-native') in tests..."
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
Run `yarn lint` to check for violations.
|
||||
|
||||
### 2. Validation Script (app/scripts/check-test-requires.cjs)
|
||||
|
||||
Automated script to detect nested require patterns:
|
||||
|
||||
```bash
|
||||
node scripts/check-test-requires.cjs
|
||||
```
|
||||
|
||||
This script:
|
||||
- Scans all test files for `require('react')` and `require('react-native')`
|
||||
- Reports exact file locations and line numbers
|
||||
- Exits with error code 1 if issues found
|
||||
|
||||
### 3. CI Fast-Fail Check
|
||||
|
||||
GitHub Actions runs the validation script before tests:
|
||||
|
||||
```yaml
|
||||
- name: Check for nested require() in tests
|
||||
run: node scripts/check-test-requires.cjs
|
||||
working-directory: ./app
|
||||
```
|
||||
|
||||
This prevents wasting CI time on tests that will OOM.
|
||||
|
||||
## Quick Checklist
|
||||
|
||||
Before committing test changes:
|
||||
- [ ] No `require('react-native')` calls in test files (use `import` instead)
|
||||
- [ ] All imports at top of file (not in hooks)
|
||||
- [ ] Search for nested patterns: `grep -r "require('react-native')" app/tests/`
|
||||
- [ ] No `require('react')` calls in test files (use `import React from 'react'` instead)
|
||||
- [ ] No `require('react-native')` calls in test files (use `import { ... } from 'react-native'` instead)
|
||||
- [ ] All imports at top of file (not in hooks or jest.mock() factories)
|
||||
- [ ] Run validation: `node scripts/check-test-requires.cjs`
|
||||
- [ ] Run lint: `yarn lint`
|
||||
|
||||
## Detection
|
||||
|
||||
**Signs of nested require issues**: CI OOM errors, test timeouts, memory spikes, "Call stack size exceeded" errors
|
||||
**Signs of nested require issues**: CI OOM errors, test timeouts, memory spikes, "Call stack size exceeded" errors, tests hiding actual failures
|
||||
|
||||
**Fix**: Search for `require('react-native')` in tests → Replace with `import` statements
|
||||
**Fix**:
|
||||
1. Search for `require('react')` and `require('react-native')` in tests
|
||||
2. Replace with `import` statements at the top of the file
|
||||
3. Run `node scripts/check-test-requires.cjs` to verify
|
||||
|
||||
## Related Files
|
||||
|
||||
- `app/.eslintrc.cjs` - ESLint rules blocking nested requires
|
||||
- `app/scripts/check-test-requires.cjs` - Validation script
|
||||
- `.github/workflows/mobile-ci.yml` - CI enforcement
|
||||
- `app/jest.setup.js` - Jest setup with React Native mocks
|
||||
- `packages/mobile-sdk-alpha/tests/setup.ts` - Vitest setup with React Native mocks
|
||||
- `app/jest.config.cjs` - Jest configuration
|
||||
|
||||
3
.github/workflows/mobile-ci.yml
vendored
3
.github/workflows/mobile-ci.yml
vendored
@@ -183,6 +183,9 @@ jobs:
|
||||
else
|
||||
echo "✅ All required dependency files exist"
|
||||
fi
|
||||
- name: Check for nested require() in tests
|
||||
run: node scripts/check-test-requires.cjs
|
||||
working-directory: ./app
|
||||
- name: App Tests
|
||||
env:
|
||||
# Increase Node.js memory to prevent hermes-parser WASM memory errors
|
||||
|
||||
@@ -213,12 +213,54 @@ module.exports = {
|
||||
rules: {
|
||||
// Allow console logging and relaxed typing in tests
|
||||
'no-console': 'off',
|
||||
// Allow require() imports in tests for mocking
|
||||
// Allow require() imports in tests for mocking, but block react/react-native
|
||||
'@typescript-eslint/no-require-imports': 'off',
|
||||
// Block require('react') and require('react-native') to prevent OOM issues
|
||||
'no-restricted-syntax': [
|
||||
'error',
|
||||
{
|
||||
selector:
|
||||
"CallExpression[callee.name='require'][arguments.0.value='react']",
|
||||
message:
|
||||
"Do not use require('react') in tests. Use 'import React from \"react\"' at the top of the file to avoid out-of-memory issues in CI.",
|
||||
},
|
||||
{
|
||||
selector:
|
||||
"CallExpression[callee.name='require'][arguments.0.value='react-native']",
|
||||
message:
|
||||
"Do not use require('react-native') in tests. Use 'import { ... } from \"react-native\"' at the top of the file to avoid out-of-memory issues in CI.",
|
||||
},
|
||||
],
|
||||
// Allow any types in tests for mocking
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['tests/**/*.js'],
|
||||
env: {
|
||||
jest: true,
|
||||
},
|
||||
rules: {
|
||||
// Allow console logging in test JS files
|
||||
'no-console': 'off',
|
||||
// Block require('react') and require('react-native') to prevent OOM issues
|
||||
'no-restricted-syntax': [
|
||||
'error',
|
||||
{
|
||||
selector:
|
||||
"CallExpression[callee.name='require'][arguments.0.value='react']",
|
||||
message:
|
||||
"Do not use require('react') in tests. Use 'import React from \"react\"' at the top of the file to avoid out-of-memory issues in CI.",
|
||||
},
|
||||
{
|
||||
selector:
|
||||
"CallExpression[callee.name='require'][arguments.0.value='react-native']",
|
||||
message:
|
||||
"Do not use require('react-native') in tests. Use 'import { ... } from \"react-native\"' at the top of the file to avoid out-of-memory issues in CI.",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
// Allow console logging in scripts
|
||||
files: ['scripts/**/*.cjs', 'scripts/*.cjs'],
|
||||
|
||||
@@ -209,22 +209,32 @@ yarn mobile-local-deploy
|
||||
|
||||
## Test Memory Optimization
|
||||
|
||||
**CRITICAL**: Never create nested `require('react-native')` calls in tests. This causes out-of-memory (OOM) errors in CI/CD pipelines.
|
||||
**CRITICAL**: Never create nested `require('react')` or `require('react-native')` calls in tests. This causes out-of-memory (OOM) errors in CI/CD pipelines that hide actual test failures.
|
||||
|
||||
### Automated Enforcement
|
||||
|
||||
The project has multiple layers of protection:
|
||||
|
||||
1. **ESLint Rule**: Blocks `require('react')` and `require('react-native')` in test files
|
||||
2. **Pre-commit Script**: Run `node scripts/check-test-requires.cjs` to validate
|
||||
3. **CI Fast-Fail**: GitHub Actions checks for nested requires before running tests
|
||||
|
||||
### Quick Check
|
||||
Before committing, verify no nested requires:
|
||||
```bash
|
||||
# Check for require('react-native') in test files
|
||||
grep -r "require('react-native')" app/tests/
|
||||
# Automated check (recommended)
|
||||
node scripts/check-test-requires.cjs
|
||||
|
||||
# Review results - ensure no nested patterns (require inside beforeEach/afterEach or inside modules that are required in tests)
|
||||
# Manual check
|
||||
grep -r "require('react')" app/tests/
|
||||
grep -r "require('react-native')" app/tests/
|
||||
```
|
||||
|
||||
### Best Practices
|
||||
- Use ES6 `import` statements instead of `require()` when possible
|
||||
- Avoid dynamic `require()` calls in `beforeEach`/`afterEach` hooks
|
||||
- Prefer top-level imports over nested requires
|
||||
- React Native is already mocked in `jest.setup.js` - use imports in test files
|
||||
- **Always use ES6 `import` statements** - Never use `require('react')` or `require('react-native')` in test files
|
||||
- Put all imports at the top of the file - No dynamic imports in hooks
|
||||
- Avoid `require()` calls in `beforeEach`/`afterEach` hooks
|
||||
- React and React Native are already mocked in `jest.setup.js` - use imports in test files
|
||||
|
||||
### Detailed Guidelines
|
||||
See `.cursor/rules/test-memory-optimization.mdc` for comprehensive guidelines, examples, and anti-patterns.
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
CFPropertyList (3.0.7)
|
||||
base64
|
||||
nkf
|
||||
rexml
|
||||
CFPropertyList (3.0.8)
|
||||
activesupport (7.2.3)
|
||||
base64
|
||||
benchmark (>= 0.3)
|
||||
@@ -25,7 +22,7 @@ GEM
|
||||
artifactory (3.0.17)
|
||||
atomos (0.1.3)
|
||||
aws-eventstream (1.4.0)
|
||||
aws-partitions (1.1181.0)
|
||||
aws-partitions (1.1183.0)
|
||||
aws-sdk-core (3.237.0)
|
||||
aws-eventstream (~> 1, >= 1.3.0)
|
||||
aws-partitions (~> 1, >= 1.992.0)
|
||||
@@ -232,7 +229,7 @@ GEM
|
||||
mini_magick (4.13.2)
|
||||
mini_mime (1.1.5)
|
||||
mini_portile2 (2.8.9)
|
||||
minitest (5.26.1)
|
||||
minitest (5.26.2)
|
||||
molinillo (0.8.0)
|
||||
multi_json (1.17.0)
|
||||
multipart-post (2.4.1)
|
||||
@@ -241,7 +238,6 @@ GEM
|
||||
nap (1.1.0)
|
||||
naturally (2.3.0)
|
||||
netrc (0.11.0)
|
||||
nkf (0.2.0)
|
||||
nokogiri (1.18.10)
|
||||
mini_portile2 (~> 2.8.2)
|
||||
racc (~> 1.4)
|
||||
@@ -315,4 +311,4 @@ RUBY VERSION
|
||||
ruby 3.2.7p253
|
||||
|
||||
BUNDLED WITH
|
||||
2.6.9
|
||||
2.4.19
|
||||
|
||||
@@ -135,7 +135,7 @@ android {
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 121
|
||||
versionName "2.9.0"
|
||||
versionName "2.9.1"
|
||||
manifestPlaceholders = [appAuthRedirectScheme: 'com.proofofpassportapp']
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.9.0</string>
|
||||
<string>2.9.1</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
|
||||
@@ -546,7 +546,7 @@
|
||||
"$(PROJECT_DIR)",
|
||||
"$(PROJECT_DIR)/MoproKit/Libs",
|
||||
);
|
||||
MARKETING_VERSION = 2.9.0;
|
||||
MARKETING_VERSION = 2.9.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -686,7 +686,7 @@
|
||||
"$(PROJECT_DIR)",
|
||||
"$(PROJECT_DIR)/MoproKit/Libs",
|
||||
);
|
||||
MARKETING_VERSION = 2.9.0;
|
||||
MARKETING_VERSION = 2.9.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@selfxyz/mobile-app",
|
||||
"version": "2.9.0",
|
||||
"version": "2.9.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
145
app/scripts/check-test-requires.cjs
Normal file
145
app/scripts/check-test-requires.cjs
Normal file
@@ -0,0 +1,145 @@
|
||||
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
|
||||
|
||||
/**
|
||||
* Check for nested require('react') and require('react-native') in test files
|
||||
* These patterns cause out-of-memory errors in CI/CD pipelines
|
||||
*
|
||||
* Usage: node scripts/check-test-requires.cjs
|
||||
* Exit code: 0 if no issues found, 1 if issues found
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const TESTS_DIR = path.join(__dirname, '..', 'tests');
|
||||
const FORBIDDEN_PATTERNS = [
|
||||
{
|
||||
pattern: /require\(['"]react['"]\)/g,
|
||||
name: "require('react')",
|
||||
fix: 'Use \'import React from "react"\' at the top of the file instead',
|
||||
},
|
||||
{
|
||||
pattern: /require\(['"]react-native['"]\)/g,
|
||||
name: "require('react-native')",
|
||||
fix: 'Use \'import { ... } from "react-native"\' at the top of the file instead',
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Recursively find all test files in directory
|
||||
*/
|
||||
function findTestFiles(dir, files = []) {
|
||||
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
||||
|
||||
for (const entry of entries) {
|
||||
const fullPath = path.join(dir, entry.name);
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
// Skip node_modules and other common directories
|
||||
if (
|
||||
!['node_modules', '.git', 'coverage', 'dist', 'build'].includes(
|
||||
entry.name,
|
||||
)
|
||||
) {
|
||||
findTestFiles(fullPath, files);
|
||||
}
|
||||
} else if (
|
||||
entry.isFile() &&
|
||||
(entry.name.endsWith('.ts') ||
|
||||
entry.name.endsWith('.tsx') ||
|
||||
entry.name.endsWith('.js') ||
|
||||
entry.name.endsWith('.jsx'))
|
||||
) {
|
||||
files.push(fullPath);
|
||||
}
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check a file for forbidden require patterns
|
||||
*/
|
||||
function checkFile(filePath) {
|
||||
const content = fs.readFileSync(filePath, 'utf-8');
|
||||
const issues = [];
|
||||
|
||||
for (const { pattern, name, fix } of FORBIDDEN_PATTERNS) {
|
||||
const matches = content.matchAll(pattern);
|
||||
for (const match of matches) {
|
||||
const lines = content.substring(0, match.index).split('\n');
|
||||
const lineNumber = lines.length;
|
||||
const columnNumber = lines[lines.length - 1].length + 1;
|
||||
|
||||
issues.push({
|
||||
file: path.relative(process.cwd(), filePath),
|
||||
line: lineNumber,
|
||||
column: columnNumber,
|
||||
pattern: name,
|
||||
fix: fix,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return issues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main execution
|
||||
*/
|
||||
function main() {
|
||||
console.log('🔍 Checking for nested require() in test files...\n');
|
||||
|
||||
if (!fs.existsSync(TESTS_DIR)) {
|
||||
console.error(`❌ Tests directory not found: ${TESTS_DIR}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const testFiles = findTestFiles(TESTS_DIR);
|
||||
console.log(`Found ${testFiles.length} test files to check\n`);
|
||||
|
||||
let totalIssues = 0;
|
||||
const issuesByFile = new Map();
|
||||
|
||||
for (const file of testFiles) {
|
||||
const issues = checkFile(file);
|
||||
if (issues.length > 0) {
|
||||
issuesByFile.set(file, issues);
|
||||
totalIssues += issues.length;
|
||||
}
|
||||
}
|
||||
|
||||
if (totalIssues === 0) {
|
||||
console.log('✅ No nested require() patterns found in test files!');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Report issues
|
||||
console.error(
|
||||
`❌ Found ${totalIssues} nested require() pattern(s) that cause OOM in CI:\n`,
|
||||
);
|
||||
|
||||
for (const [file, issues] of issuesByFile.entries()) {
|
||||
console.error(`\n${path.relative(process.cwd(), file)}:`);
|
||||
for (const issue of issues) {
|
||||
console.error(` Line ${issue.line}:${issue.column} - ${issue.pattern}`);
|
||||
console.error(` Fix: ${issue.fix}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.error(
|
||||
'\n⚠️ These patterns cause out-of-memory errors in CI/CD pipelines.',
|
||||
);
|
||||
console.error(
|
||||
' Use ES6 imports at the top of files instead of require() calls.',
|
||||
);
|
||||
console.error(
|
||||
' See .cursor/rules/test-memory-optimization.mdc for details.\n',
|
||||
);
|
||||
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -110,7 +110,7 @@ const CloudBackupScreen: React.FC<CloudBackupScreenProps> = ({
|
||||
onButtonPress: () => {
|
||||
// setTimeout to ensure modal closes before navigation to prevent navigation conflicts when the modal tries to goBack()
|
||||
setTimeout(() => {
|
||||
navigation.navigate({ name: 'CountryPicker', params: {} });
|
||||
navigation.navigate('CountryPicker');
|
||||
}, 100);
|
||||
},
|
||||
onModalDismiss: () => {},
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
|
||||
|
||||
// Minimal JS mock for @selfxyz/mobile-sdk-alpha/components used in tests
|
||||
const React = require('react');
|
||||
// CRITICAL: Do NOT import React to avoid OOM issues in CI
|
||||
|
||||
const getTextFromChildren = ch => {
|
||||
if (typeof ch === 'string') return ch;
|
||||
@@ -13,41 +13,50 @@ const getTextFromChildren = ch => {
|
||||
return '';
|
||||
};
|
||||
|
||||
const Caption = ({ children }) =>
|
||||
React.createElement(React.Fragment, null, children);
|
||||
const Description = ({ children }) =>
|
||||
React.createElement(React.Fragment, null, children);
|
||||
const Title = ({ children }) =>
|
||||
React.createElement(React.Fragment, null, children);
|
||||
// Simple mock components that return plain objects instead of using React.createElement
|
||||
export const Caption = ({ children }) => ({
|
||||
type: 'Caption',
|
||||
props: { children },
|
||||
});
|
||||
|
||||
// Use React.createElement directly instead of requiring react-native to avoid memory issues
|
||||
const PrimaryButton = ({ children, onPress, disabled, testID }) => {
|
||||
export const Description = ({ children }) => ({
|
||||
type: 'Description',
|
||||
props: { children },
|
||||
});
|
||||
|
||||
export const PrimaryButton = ({ children, onPress, disabled, testID }) => {
|
||||
const buttonText = getTextFromChildren(children);
|
||||
const id =
|
||||
testID || `button-${buttonText.toLowerCase().replace(/\s+/g, '-')}`;
|
||||
return React.createElement(
|
||||
'View',
|
||||
{ onPress, disabled, testID: id, accessibilityRole: 'button' },
|
||||
children,
|
||||
);
|
||||
return {
|
||||
type: 'PrimaryButton',
|
||||
props: {
|
||||
children,
|
||||
onPress,
|
||||
disabled,
|
||||
testID: id,
|
||||
accessibilityRole: 'button',
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const SecondaryButton = ({ children, onPress, disabled, testID }) => {
|
||||
export const SecondaryButton = ({ children, onPress, disabled, testID }) => {
|
||||
const buttonText = getTextFromChildren(children);
|
||||
const id =
|
||||
testID || `button-${buttonText.toLowerCase().replace(/\s+/g, '-')}`;
|
||||
return React.createElement(
|
||||
'View',
|
||||
{ onPress, disabled, testID: id, accessibilityRole: 'button' },
|
||||
children,
|
||||
);
|
||||
return {
|
||||
type: 'SecondaryButton',
|
||||
props: {
|
||||
children,
|
||||
onPress,
|
||||
disabled,
|
||||
testID: id,
|
||||
accessibilityRole: 'button',
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
__esModule: true,
|
||||
Caption,
|
||||
Description,
|
||||
Title,
|
||||
PrimaryButton,
|
||||
SecondaryButton,
|
||||
};
|
||||
export const Title = ({ children }) => ({
|
||||
type: 'Title',
|
||||
props: { children },
|
||||
});
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
|
||||
|
||||
import React from 'react';
|
||||
import { Text } from 'react-native';
|
||||
import { render } from '@testing-library/react-native';
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
|
||||
|
||||
import React from 'react';
|
||||
import { act, render } from '@testing-library/react-native';
|
||||
|
||||
import { PassportCamera as NativePassportCamera } from '@/components/native/PassportCamera';
|
||||
|
||||
@@ -39,13 +39,7 @@ jest.mock('@/utils/points', () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock('@/stores/userStore', () => {
|
||||
const actual = jest.requireActual('@/stores/userStore');
|
||||
return {
|
||||
__esModule: true,
|
||||
default: actual.default,
|
||||
};
|
||||
});
|
||||
// userStore is used as-is, no mock needed
|
||||
|
||||
const mockNavigate = jest.fn();
|
||||
const mockUseNavigation = useNavigation as jest.MockedFunction<
|
||||
|
||||
@@ -13,13 +13,7 @@ jest.mock('@react-navigation/native', () => ({
|
||||
useNavigation: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('@/stores/userStore', () => {
|
||||
const actual = jest.requireActual('@/stores/userStore');
|
||||
return {
|
||||
__esModule: true,
|
||||
default: actual.default,
|
||||
};
|
||||
});
|
||||
// userStore is used as-is, no mock needed
|
||||
|
||||
const mockNavigate = jest.fn();
|
||||
const mockUseNavigation = useNavigation as jest.MockedFunction<
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @jest-environment node
|
||||
*/
|
||||
|
||||
import React, { useEffect } from 'react';
|
||||
import { useEffect } from 'react';
|
||||
import { Text } from 'react-native';
|
||||
import { render, screen } from '@testing-library/react-native';
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Text } from 'react-native';
|
||||
import { render, waitFor } from '@testing-library/react-native';
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
|
||||
|
||||
import React from 'react';
|
||||
import { Text } from 'react-native';
|
||||
import { render, waitFor } from '@testing-library/react-native';
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
|
||||
|
||||
// Mock ConfirmIdentificationScreen to avoid PixelRatio issues
|
||||
import React, { type ReactNode } from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
import { renderHook } from '@testing-library/react-native';
|
||||
|
||||
import { useSelfClient } from '@selfxyz/mobile-sdk-alpha';
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
|
||||
|
||||
import React from 'react';
|
||||
import { useNavigation, useRoute } from '@react-navigation/native';
|
||||
import { render, waitFor } from '@testing-library/react-native';
|
||||
|
||||
@@ -15,24 +14,31 @@ jest.mock('@react-navigation/native', () => ({
|
||||
|
||||
// Mock Tamagui components to avoid theme provider requirement
|
||||
jest.mock('tamagui', () => {
|
||||
const ReactMock = require('react');
|
||||
// Use React.createElement directly instead of requiring react-native to avoid memory issues
|
||||
const YStack = ReactMock.forwardRef(({ children, ...props }: any, ref: any) =>
|
||||
ReactMock.createElement('View', { ref, ...props }, children),
|
||||
const View: any = 'View';
|
||||
const Text: any = 'Text';
|
||||
const createViewComponent = (displayName: string) => {
|
||||
const MockComponent = ({ children, ...props }: any) => (
|
||||
<View {...props} testID={displayName}>
|
||||
{children}
|
||||
</View>
|
||||
);
|
||||
MockComponent.displayName = displayName;
|
||||
return MockComponent;
|
||||
};
|
||||
|
||||
const MockYStack = createViewComponent('YStack');
|
||||
const MockView = createViewComponent('View');
|
||||
|
||||
const MockText = ({ children, ...props }: any) => (
|
||||
<Text {...props}>{children}</Text>
|
||||
);
|
||||
YStack.displayName = 'YStack';
|
||||
const Text = ReactMock.forwardRef(({ children, ...props }: any, ref: any) =>
|
||||
ReactMock.createElement('Text', { ref, ...props }, children),
|
||||
);
|
||||
Text.displayName = 'Text';
|
||||
const View = ReactMock.forwardRef(({ children, ...props }: any, ref: any) =>
|
||||
ReactMock.createElement('View', { ref, ...props }, children),
|
||||
);
|
||||
View.displayName = 'View';
|
||||
MockText.displayName = 'Text';
|
||||
|
||||
return {
|
||||
YStack,
|
||||
Text,
|
||||
View,
|
||||
__esModule: true,
|
||||
YStack: MockYStack,
|
||||
View: MockView,
|
||||
Text: MockText,
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
|
||||
|
||||
import React from 'react';
|
||||
import { Linking } from 'react-native';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import {
|
||||
@@ -15,17 +14,15 @@ import {
|
||||
import { WebViewScreen } from '@/screens/shared/WebViewScreen';
|
||||
|
||||
jest.mock('@react-navigation/native', () => ({
|
||||
...jest.requireActual('@react-navigation/native'),
|
||||
useNavigation: jest.fn(),
|
||||
useFocusEffect: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('react-native-webview', () => {
|
||||
const ReactMock = require('react');
|
||||
// Use React.createElement directly instead of requiring react-native to avoid memory issues
|
||||
const MockWebView = ReactMock.forwardRef((props: any, _ref) => {
|
||||
return ReactMock.createElement('View', { testID: 'webview', ...props });
|
||||
});
|
||||
// Lightweight host component so React can render while keeping props inspectable
|
||||
const MockWebView = ({ testID = 'webview', ...props }: any) => (
|
||||
<mock-webview testID={testID} {...props} />
|
||||
);
|
||||
MockWebView.displayName = 'MockWebView';
|
||||
return {
|
||||
__esModule: true,
|
||||
|
||||
@@ -23,20 +23,15 @@ jest.mock('@/providers/authProvider', () => ({
|
||||
jest.mock('@/utils/points/utils', () => ({
|
||||
getPointsAddress: jest.fn(),
|
||||
}));
|
||||
jest.mock('ethers', () => {
|
||||
const actualEthers = jest.requireActual('ethers');
|
||||
return {
|
||||
...actualEthers,
|
||||
ethers: {
|
||||
...actualEthers.ethers,
|
||||
Wallet: jest.fn(),
|
||||
Signature: {
|
||||
from: jest.fn(),
|
||||
},
|
||||
getBytes: jest.fn(),
|
||||
jest.mock('ethers', () => ({
|
||||
ethers: {
|
||||
Wallet: jest.fn(),
|
||||
Signature: {
|
||||
from: jest.fn(),
|
||||
},
|
||||
};
|
||||
});
|
||||
getBytes: jest.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
const mockAxios = axios as jest.Mocked<typeof axios>;
|
||||
const mockUnsafeGetPrivateKey = unsafe_getPrivateKey as jest.MockedFunction<
|
||||
|
||||
@@ -37,13 +37,9 @@ jest.mock('@robinbobin/react-native-google-drive-api-wrapper', () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock('@/utils/cloudBackup/google', () => {
|
||||
const originalModule = jest.requireActual('@/utils/cloudBackup/google');
|
||||
return {
|
||||
...originalModule,
|
||||
createGDrive: jest.fn(),
|
||||
};
|
||||
});
|
||||
jest.mock('@/utils/cloudBackup/google', () => ({
|
||||
createGDrive: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('ethers', () => ({
|
||||
ethers: {
|
||||
|
||||
Reference in New Issue
Block a user