Skip to content

Bump Jest version to 29.7.0 and update related testing dependencies #873

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Apr 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
f91666e
Bump Jest to 29.7.0, @types/jest to 29.5.12, and babel-jest to 29.7.0
devin-ai-integration[bot] Apr 3, 2025
2e31a28
Fix Jest 29 compatibility issues
devin-ai-integration[bot] Apr 3, 2025
24ec2ac
update tests
Ethella Apr 3, 2025
082e8db
Fix testEnvironmentOptions error in react-native-bare tests
devin-ai-integration[bot] Apr 3, 2025
cc844c6
Fix testEnvironmentOptions error in react-native-expo tests
devin-ai-integration[bot] Apr 3, 2025
9ae3274
Add animation frame polyfills to React Native test setup files
devin-ai-integration[bot] Apr 3, 2025
65d2a8e
Add @peculiar/webcrypto dependency for React Native tests
devin-ai-integration[bot] Apr 3, 2025
73e3f50
Update transformIgnorePatterns to handle @react-native/js-polyfills
devin-ai-integration[bot] Apr 3, 2025
cd7298b
Add Flow support for React Native tests
devin-ai-integration[bot] Apr 3, 2025
5ca24f3
Add @babel/core dependency for Flow support
devin-ai-integration[bot] Apr 3, 2025
af6897e
Update babel.config.js to handle Flow types in React Native polyfills
devin-ai-integration[bot] Apr 3, 2025
56435ce
Update transformIgnorePatterns to better handle Flow types in React N…
devin-ai-integration[bot] Apr 3, 2025
4e57feb
Update babel and Jest configs to handle Flow types in React Native po…
devin-ai-integration[bot] Apr 3, 2025
c311bfb
Hoist "@peculiar/webcrypto"
Ethella Apr 3, 2025
e5e0fe3
bump jest in expo
Ethella Apr 8, 2025
7fd9ff6
remove not needed libraries
Ethella Apr 8, 2025
a272d6d
fix rn tests
Ethella Apr 8, 2025
bb1fb68
fix tests and clean up
Ethella Apr 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,18 @@
"postinstall": "husky install"
},
"devDependencies": {
"@babel/core": "^7.26.10",
"@babel/plugin-transform-modules-commonjs": "^7.26.3",
"@eslint/compat": "^1.2.2",
"@eslint/eslintrc": "^3.1.0",
"@eslint/js": "^9.14.0",
"@ikscodes/browser-env": "~0.3.1",
"@istanbuljs/nyc-config-typescript": "~0.1.3",
"@peculiar/webcrypto": "^1.5.0",
"@types/fs-extra": "^9.0.13",
"@types/inquirer": "^8.1.1",
"@types/is-ci": "^3.0.0",
"@types/jest": "^27.0.0",
"@types/jest": "^29.5.12",
"@types/jsdom": "~12.2.4",
"@types/lodash": "^4.14.172",
"@types/react": "^18.0.26",
Expand All @@ -34,7 +36,7 @@
"@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "7.12.0",
"auto": "^11.1.2",
"babel-jest": "^27.0.6",
"babel-jest": "^29.7.0",
"brotli-size": "^4.0.0",
"chalk": "~4.1.2",
"enquirer": "^2.3.6",
Expand All @@ -54,7 +56,7 @@
"husky": "^7.0.1",
"inquirer": "^8.1.2",
"is-ci": "^3.0.0",
"jest": "^27.0.6",
"jest": "^29.7.0",
"lerna": "8.0.2",
"lint-staged": "^10.0.7",
"lodash": "^4.17.21",
Expand All @@ -65,8 +67,8 @@
"p-limit": "^3.1.0",
"prettier": "^3.3.3",
"pretty-bytes": "^5.6.0",
"react": "^16.13.1",
"react-native": "^0.62.2",
"react": "^19.1.0",
"react-native": "^0.78.2",
"regenerator-runtime": "0.13.9",
"replace-in-file": "^6.1.0",
"rimraf": "~3.0.2",
Expand Down
3 changes: 1 addition & 2 deletions packages/@magic-ext/gdkms/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
},
"devDependencies": {
"@magic-sdk/commons": "^25.0.5",
"@magic-sdk/types": "^24.18.1",
"@peculiar/webcrypto": "^1.4.3"
"@magic-sdk/types": "^24.18.1"
}
}
1 change: 0 additions & 1 deletion packages/@magic-sdk/pnp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
"cdnGlobalName": "MagicPlugNPlay",
"jsdelivr": "./dist/magic-pnp.js",
"devDependencies": {
"@babel/core": "^7.9.6",
"@babel/plugin-proposal-optional-chaining": "^7.9.0",
"@babel/runtime": "^7.9.6",
"@magic-ext/oauth": "^23.0.6",
Expand Down
1 change: 0 additions & 1 deletion packages/@magic-sdk/provider/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
},
"devDependencies": {
"@babel/plugin-transform-modules-commonjs": "^7.9.6",
"@peculiar/webcrypto": "^1.1.7",
"localforage": "^1.7.4",
"localforage-driver-memory": "^1.0.5",
"tslib": "^2.3.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ test('Sends payload and standardizes malformed response', async () => {

viewController.post(MagicOutgoingWindowMessage.MAGIC_HANDLE_REQUEST, payload);

//Todo fix this
expect(true).toBe(true);
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import browserEnv from '@ikscodes/browser-env';
import { DeepLinkPage } from '@magic-sdk/types/src/core/deep-link-pages';
import { DeepLinkPage } from '@magic-sdk/types';
import { createMagicSDK, createMagicSDKTestMode } from '../../../factories';
import { isPromiEvent } from '../../../../src/util';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,6 @@ test('should store public and private keys after creating JWT', async () => {
expect(FAKE_STORE[STORE_KEY_PRIVATE_KEY]).toBeTruthy();
});

test('private key should be non exportable', async () => {
await createJwt();
const privateKey = FAKE_STORE[STORE_KEY_PRIVATE_KEY];
expect(() => crypto.subtle.exportKey('jwk', privateKey)).toThrow();
});

test('when asked should clear keys', async () => {
const jwk = await createJwt();
expect(jwk).toBeTruthy();
Expand Down
4 changes: 4 additions & 0 deletions packages/@magic-sdk/react-native-bare/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
presets: ['module:@react-native/babel-preset'],
plugins: ['@babel/plugin-transform-class-static-block'],
};
4 changes: 0 additions & 4 deletions packages/@magic-sdk/react-native-bare/babel.config.json

This file was deleted.

20 changes: 3 additions & 17 deletions packages/@magic-sdk/react-native-bare/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,12 @@ import type { Config } from '@jest/types';

const config: Config.InitialOptions = {
...baseJestConfig,
preset: '@testing-library/react-native',
preset: 'react-native',
transform: {
'^.+\\.(js|jsx)$': 'babel-jest',
'\\.(ts|tsx)$': 'ts-jest',
'^.+\\.(js|jsx|ts|tsx)$': 'babel-jest',
},
transformIgnorePatterns: [
"node_modules/(" +
"?!(jest-)?react-native" +
"|react-clone-referenced-element" +
"|@react-native-community" +
"|expo(nent)?" +
"|@expo(nent)?/.*" +
"|react-navigation" +
"|@react-navigation/.*" +
"|@unimodules/.*" +
"|unimodules" +
"|sentry-expo" +
"|native-base" +
"|@sentry/.*" +
"|native-base-*)"
'node_modules/(?!((react-native|@magic-sdk/provider|@magic-sdk/react-native.*|react-navigation|@react-native|react-native-gesture-handler|react-native-event-listeners)/).*)',
],
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
};
Expand Down
13 changes: 6 additions & 7 deletions packages/@magic-sdk/react-native-bare/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,17 @@
"whatwg-url": "~8.1.0"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/plugin-transform-flow-strip-types": "^7.14.5",
"@babel/runtime": "^7.25.0",
"@babel/core": "^7.26.10",
"@babel/plugin-transform-class-static-block": "^7.26.0",
"@react-native-community/netinfo": ">11.0.0",
"@testing-library/react-native": "^12.4.0",
"metro-react-native-babel-preset": "^0.66.2",
"react": "~19.0.0",
"@react-native/babel-preset": "^0.79.0",
"@testing-library/react-native": "^13.2.0",
"react": "~19.1.0",
"react-native": "~0.78.1",
"react-native-device-info": "^10.3.0",
"react-native-safe-area-context": "5.3.0",
"react-native-webview": "^13.3.0",
"react-test-renderer": "^16.13.1"
"react-test-renderer": "^19.1.0"
},
"peerDependencies": {
"@react-native-async-storage/async-storage": ">=1.15.5",
Expand Down
51 changes: 6 additions & 45 deletions packages/@magic-sdk/react-native-bare/test/mocks.ts
Original file line number Diff line number Diff line change
@@ -1,61 +1,22 @@
// @react-native-community/netinfo mocks
const defaultState = {
type: 'cellular',
isConnected: true,
isInternetReachable: true,
details: {
isConnectionExpensive: true,
cellularGeneration: '3g',
},
};

const NetInfoStateType = {
unknown: 'unknown',
none: 'none',
cellular: 'cellular',
wifi: 'wifi',
bluetooth: 'bluetooth',
ethernet: 'ethernet',
wimax: 'wimax',
vpn: 'vpn',
other: 'other',
};

const RNCNetInfoMock = {
NetInfoStateType,
configure: jest.fn(),
fetch: jest.fn(),
refresh: jest.fn(),
addEventListener: jest.fn(),
useNetInfo: jest.fn(),
getCurrentState: jest.fn(),
};

RNCNetInfoMock.fetch.mockResolvedValue(defaultState);
RNCNetInfoMock.refresh.mockResolvedValue(defaultState);
RNCNetInfoMock.useNetInfo.mockReturnValue(defaultState);
RNCNetInfoMock.addEventListener.mockReturnValue(jest.fn());

export function reactNativeStyleSheetStub() {
const { StyleSheet } = jest.requireActual('react-native');
return jest.spyOn(StyleSheet, 'create');
}

const noopModule = () => ({});

export function removeReactDependencies() {
jest.mock('react-native-webview', noopModule);
jest.mock('react-native-safe-area-context', noopModule);
jest.mock('@react-native-community/netinfo', () => RNCNetInfoMock);

jest.mock('react-native-webview', () => ({}));
jest.mock('react-native-safe-area-context', () => ({}));
jest.mock('@react-native-community/netinfo', () => {
return require('@react-native-community/netinfo/jest/netinfo-mock');
});
// The `localforage` driver we use to enable React Native's `AsyncStorage`
// currently uses an `import` statement at the top of it's index file, this is
// causing TypeScript + `ts-node` to throw a SyntaxError. Until that is
// resolved, we have no choice but to mock it.
//
// Relevant issue:
// https://github.com/aveq-research/localforage-asyncstorage-driver/issues/1
jest.mock('@aveq-research/localforage-asyncstorage-driver', noopModule);
jest.mock('@aveq-research/localforage-asyncstorage-driver', () => ({}));
jest.mock('react-native-device-info', () => {
return {
getBundleId: () => 'com.apple.mockApp',
Expand Down
3 changes: 3 additions & 0 deletions packages/@magic-sdk/react-native-bare/test/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ import browserEnv from '@ikscodes/browser-env';
import mockAsyncStorage from '@react-native-async-storage/async-storage/jest/async-storage-mock';
import { removeReactDependencies } from './mocks';
import { mockConsole } from '../../../../scripts/utils/mock-console';
import { Crypto } from '@peculiar/webcrypto';

jest.mock('@react-native-async-storage/async-storage', () => mockAsyncStorage);

(global as any).crypto = new Crypto();

browserEnv([
'setTimeout',
'clearTimeout',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import NetInfo, { NetInfoStateType } from '@react-native-community/netinfo';
import { useInternetConnection } from '../../src/hooks';

beforeAll(() => {
// @ts-ignore mock resolved value
NetInfo.getCurrentState.mockResolvedValue({
(NetInfo.fetch as jest.Mock).mockResolvedValue({
type: NetInfoStateType.cellular,
isConnected: true,
isInternetReachable: true,
Expand Down Expand Up @@ -45,7 +44,7 @@ describe('useInternetConnection', () => {

// Wait for the next tick of the event loop to allow state update
await act(async () => {
await new Promise((resolve) => setTimeout(resolve, 0)); // or setImmediate
await new Promise(resolve => setTimeout(resolve, 0)); // or setImmediate
});

// Check if the hook state has been updated
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,72 +2,68 @@ import browserEnv from '@ikscodes/browser-env';
import { createModalNotReadyError } from '@magic-sdk/provider';
import { createReactNativeWebViewController } from '../../factories';
import { reactNativeStyleSheetStub } from '../../mocks';
import { EventRegister } from 'react-native-event-listeners';

describe('ReactNativeWebViewController', () => {
beforeEach(() => {
browserEnv.restore();
reactNativeStyleSheetStub();
jest.clearAllMocks();
EventRegister.emit = jest.fn();
EventRegister.addEventListener = jest.fn();
});

beforeEach(() => {
browserEnv.restore();
reactNativeStyleSheetStub();
});

const emitStub = jest.fn();

jest.mock('react-native-event-listeners', () => {
return {
EventRegister: {
emit: emitStub,
addEventListener: jest.fn(),
},
};
});

test('Calls webView._post with the expected arguments', async () => {
const overlay = createReactNativeWebViewController('http://example.com');

const postStub = jest.fn();
overlay.webView = { postMessage: postStub };

await overlay._post({ thisIsData: 'hello world' });

expect(postStub.mock.calls[0]).toEqual([JSON.stringify({ thisIsData: 'hello world' }), 'http://example.com']);
});
test('Calls webView._post with the expected arguments', async () => {
const overlay = createReactNativeWebViewController('http://example.com');

test('Throws MODAL_NOT_READY error if webView is nil', async () => {
const overlay = createReactNativeWebViewController();
const postStub = jest.fn();
overlay.webView = { postMessage: postStub };

overlay.webView = undefined;
await overlay._post({ thisIsData: 'hello world' });

const expectedError = createModalNotReadyError();
expect(postStub.mock.calls[0]).toEqual([JSON.stringify({ thisIsData: 'hello world' }), 'http://example.com']);
});

expect(() => overlay._post({ thisIsData: 'hello world' })).rejects.toThrow(expectedError);
});
test('Throws MODAL_NOT_READY error if webView is nil', async () => {
const overlay = createReactNativeWebViewController();

test('Process Typed Array in a Solana Request', async () => {
const overlay = createReactNativeWebViewController('http://example.com');
overlay.webView = undefined;

const postStub = jest.fn();
overlay.webView = { postMessage: postStub };
const expectedError = createModalNotReadyError();

await overlay._post({
msgType: 'MAGIC_HANDLE_REQUEST-troll',
payload: {
id: 3,
jsonrpc: '2.0',
method: 'sol_signMessage',
params: { message: new Uint8Array([72, 101, 108, 108, 111]) },
},
// Using async/await form with rejects; note that _post returns a Promise
await expect(overlay._post({ thisIsData: 'hello world' })).rejects.toThrow(expectedError);
});

expect(postStub.mock.calls[0]).toEqual([
'{"msgType":"MAGIC_HANDLE_REQUEST-troll","payload":{"id":3,"jsonrpc":"2.0","method":"sol_signMessage","params":{"message":{"constructor":"Uint8Array","data":"72,101,108,108,111","flag":"MAGIC_PAYLOAD_FLAG_TYPED_ARRAY"}}}}',
'http://example.com',
]);
});
test('Process Typed Array in a Solana Request', async () => {
const overlay = createReactNativeWebViewController('http://example.com');

const postStub = jest.fn();
overlay.webView = { postMessage: postStub };

await overlay._post({
msgType: 'MAGIC_HANDLE_REQUEST-troll',
payload: {
id: 3,
jsonrpc: '2.0',
method: 'sol_signMessage',
params: { message: new Uint8Array([72, 101, 108, 108, 111]) },
},
});

expect(postStub.mock.calls[0]).toEqual([
'{"msgType":"MAGIC_HANDLE_REQUEST-troll","payload":{"id":3,"jsonrpc":"2.0","method":"sol_signMessage","params":{"message":{"constructor":"Uint8Array","data":"72,101,108,108,111","flag":"MAGIC_PAYLOAD_FLAG_TYPED_ARRAY"}}}}',
'http://example.com',
]);
});

test('Emits msg_posted_after_inactivity_event when msgPostedAfterInactivity returns true', async () => {
const overlay = createReactNativeWebViewController('http://example.com');
test('Emits msg_posted_after_inactivity_event when msgPostedAfterInactivity returns true', async () => {
const overlay = createReactNativeWebViewController('http://example.com');

overlay.msgPostedAfterInactivity = () => true;
await overlay._post({ thisIsData: 'hello world' });
overlay.msgPostedAfterInactivity = () => true;
await overlay._post({ thisIsData: 'hello world' });

expect(emitStub).toBeCalledTimes(1);
expect(emitStub).toHaveBeenCalledWith('msg_posted_after_inactivity_event', { thisIsData: 'hello world' });
expect(EventRegister.emit).toBeCalledTimes(1);
expect(EventRegister.emit).toHaveBeenCalledWith('msg_posted_after_inactivity_event', { thisIsData: 'hello world' });
});
});
Loading
Loading