From 6bdea1416a87aabe3f38cde9341b61c3faff5cf7 Mon Sep 17 00:00:00 2001 From: romin-halltari Date: Tue, 14 Nov 2023 14:49:45 -0800 Subject: [PATCH 01/11] Add `useInternetConnection` hook to track internet connectivity changes --- .../@magic-sdk/react-native-bare/README.md | 40 ++++++++ .../@magic-sdk/react-native-bare/package.json | 2 + .../@magic-sdk/react-native-bare/src/hooks.ts | 21 +++++ .../@magic-sdk/react-native-bare/src/index.ts | 2 + .../react-native-bare/test/mocks.ts | 1 + .../@magic-sdk/react-native-expo/README.md | 28 ++++++ .../@magic-sdk/react-native-expo/package.json | 2 + .../@magic-sdk/react-native-expo/src/hooks.ts | 21 +++++ .../@magic-sdk/react-native-expo/src/index.ts | 2 + .../react-native-expo/test/mocks.ts | 1 + yarn.lock | 93 +++++++++++-------- 11 files changed, 173 insertions(+), 40 deletions(-) create mode 100644 packages/@magic-sdk/react-native-bare/src/hooks.ts create mode 100644 packages/@magic-sdk/react-native-expo/src/hooks.ts diff --git a/packages/@magic-sdk/react-native-bare/README.md b/packages/@magic-sdk/react-native-bare/README.md index 25a92ba1e..3c9e02199 100644 --- a/packages/@magic-sdk/react-native-bare/README.md +++ b/packages/@magic-sdk/react-native-bare/README.md @@ -69,4 +69,44 @@ Please note that as of **v14.0.0** our React Native package offerings wrap the ` We have also added an optional `backgroundColor` prop to the `Relayer` to fix issues with `SafeAreaView` showing the background. By default, the background will be white. If you have changed the background color as part of your [custom branding setup](https://magic.link/docs/authentication/features/login-ui#configuration), make sure to pass your custom background color to `magic.Relayer`: ```tsx +``` + +## 🙌🏾 Troubleshooting + +### Symlinking in Monorepo w/ Metro + +For React Native projects living within a **monorepo** that run into the following `TypeError: Undefined is not an object` error: + +Screenshot 2022-11-23 at 12 19 19 PM + +When attempting to import `Magic`, take note that the React Native metro bundler doesn’t work well with symlinks, which tend to be utilized by most package managers. + +For this issue consider using Microsoft's [rnx-kit](https://microsoft.github.io/rnx-kit/docs/guides/bundling) suite of tools that include a plugin for metro that fixes this symlink related error. + +### Handling internet connection problems + +When the app has internet connectivity issues, the relayer might behave in ways you don't expect. That is why it is important to use [@react-native-community/netinfo](https://www.npmjs.com/package/@react-native-community/netinfo) to track the internet connection state of the device, and refresh your UI when the connection is re-established. For your convenience, we've also added a hook that uses this library behind the scenes: + + ```tsx +import { useInternetConnection } from '@magic-sdk/react-native-expo'; + +const magic = new Magic('YOUR_API_KEY'); + +const connected = useInternetConnection() + +useEffect(() => { + if (!connected) { + // Unomount this component and show your "You're offline" screen. + } +}, [connected]) + +export default function App() { + return <> + + {/* Render the Magic iframe! */} + + {...} + + +} ``` \ No newline at end of file diff --git a/packages/@magic-sdk/react-native-bare/package.json b/packages/@magic-sdk/react-native-bare/package.json index 9e554fc7f..ad229c334 100644 --- a/packages/@magic-sdk/react-native-bare/package.json +++ b/packages/@magic-sdk/react-native-bare/package.json @@ -37,6 +37,7 @@ "@babel/plugin-transform-flow-strip-types": "^7.14.5", "@babel/runtime": "~7.10.4", "@react-native-async-storage/async-storage": "^1.15.5", + "@react-native-community/netinfo": ">11.0.0", "metro-react-native-babel-preset": "^0.66.2", "react": "^16.13.1", "react-native": "^0.62.2", @@ -46,6 +47,7 @@ }, "peerDependencies": { "@react-native-async-storage/async-storage": ">=1.15.5", + "@react-native-community/netinfo": ">11.0.0", "react": ">=16", "react-native": ">=0.60", "react-native-device-info": ">=10.3.0", diff --git a/packages/@magic-sdk/react-native-bare/src/hooks.ts b/packages/@magic-sdk/react-native-bare/src/hooks.ts new file mode 100644 index 000000000..fe3b04eff --- /dev/null +++ b/packages/@magic-sdk/react-native-bare/src/hooks.ts @@ -0,0 +1,21 @@ +import { useEffect, useState } from 'react'; +import NetInfo, { NetInfoState } from '@react-native-community/netinfo'; + +export const useInternetConnection = () => { + const [isConnected, setIsConnected] = useState(true); + useEffect(() => { + const handleConnectionChange = (connectionInfo: NetInfoState) => { + setIsConnected(!!connectionInfo.isConnected); + }; + + // Subscribe to connection changes + const unsubscribe = NetInfo.addEventListener(handleConnectionChange); + + // Cleanup on unmount + return () => { + unsubscribe(); + }; + }, []); + + return isConnected; +}; diff --git a/packages/@magic-sdk/react-native-bare/src/index.ts b/packages/@magic-sdk/react-native-bare/src/index.ts index 0fd3bf919..c8fd7b37f 100644 --- a/packages/@magic-sdk/react-native-bare/src/index.ts +++ b/packages/@magic-sdk/react-native-bare/src/index.ts @@ -69,3 +69,5 @@ export type Magic = MagicSDKExtensionsOp SDKBaseReactNative, T >; + +export { useInternetConnection } from './hooks'; diff --git a/packages/@magic-sdk/react-native-bare/test/mocks.ts b/packages/@magic-sdk/react-native-bare/test/mocks.ts index c183ae590..e914bcc56 100644 --- a/packages/@magic-sdk/react-native-bare/test/mocks.ts +++ b/packages/@magic-sdk/react-native-bare/test/mocks.ts @@ -9,6 +9,7 @@ export function removeReactDependencies() { jest.mock('react', noopModule); jest.mock('react-native-webview', noopModule); jest.mock('react-native-safe-area-context', noopModule); + jest.mock('@react-native-community/netinfo', noopModule); // 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 diff --git a/packages/@magic-sdk/react-native-expo/README.md b/packages/@magic-sdk/react-native-expo/README.md index 4436adf8a..4891da4ce 100644 --- a/packages/@magic-sdk/react-native-expo/README.md +++ b/packages/@magic-sdk/react-native-expo/README.md @@ -73,3 +73,31 @@ For React Native projects living within a **monorepo** that run into the followi When attempting to import `Magic`, take note that the React Native metro bundler doesn’t work well with symlinks, which tend to be utilized by most package managers. For this issue consider using Microsoft's [rnx-kit](https://microsoft.github.io/rnx-kit/docs/guides/bundling) suite of tools that include a plugin for metro that fixes this symlink related error. + +### Handling internet connection problems + +When the app has internet connectivity issues, the relayer might behave in ways you don't expect. That is why it is important to use [@react-native-community/netinfo](https://www.npmjs.com/package/@react-native-community/netinfo) to track the internet connection state of the device, and refresh your UI when the connection is re-established. For your convenience, we've also added a hook that uses this library behind the scenes: + + ```tsx +import { useInternetConnection } from '@magic-sdk/react-native-expo'; + +const magic = new Magic('YOUR_API_KEY'); + +const connected = useInternetConnection() + +useEffect(() => { + if (!connected) { + // Unomount this component and show your "You're offline" screen. + } +}, [connected]) + +export default function App() { + return <> + + {/* Render the Magic iframe! */} + + {...} + + +} +``` \ No newline at end of file diff --git a/packages/@magic-sdk/react-native-expo/package.json b/packages/@magic-sdk/react-native-expo/package.json index 067263671..366ef6c38 100644 --- a/packages/@magic-sdk/react-native-expo/package.json +++ b/packages/@magic-sdk/react-native-expo/package.json @@ -36,6 +36,7 @@ "@babel/core": "^7.15.0", "@babel/plugin-transform-flow-strip-types": "^7.14.5", "@babel/runtime": "~7.10.4", + "@react-native-community/netinfo": ">11.0.0", "expo-modules-core": "^1.0.4", "metro-react-native-babel-preset": "^0.66.2", "react": "^16.13.1", @@ -44,6 +45,7 @@ "react-native-webview": ">=12.4.0" }, "peerDependencies": { + "@react-native-community/netinfo": ">11.0.0", "expo": "*", "react": ">=16", "react-native": ">=0.60", diff --git a/packages/@magic-sdk/react-native-expo/src/hooks.ts b/packages/@magic-sdk/react-native-expo/src/hooks.ts new file mode 100644 index 000000000..fe3b04eff --- /dev/null +++ b/packages/@magic-sdk/react-native-expo/src/hooks.ts @@ -0,0 +1,21 @@ +import { useEffect, useState } from 'react'; +import NetInfo, { NetInfoState } from '@react-native-community/netinfo'; + +export const useInternetConnection = () => { + const [isConnected, setIsConnected] = useState(true); + useEffect(() => { + const handleConnectionChange = (connectionInfo: NetInfoState) => { + setIsConnected(!!connectionInfo.isConnected); + }; + + // Subscribe to connection changes + const unsubscribe = NetInfo.addEventListener(handleConnectionChange); + + // Cleanup on unmount + return () => { + unsubscribe(); + }; + }, []); + + return isConnected; +}; diff --git a/packages/@magic-sdk/react-native-expo/src/index.ts b/packages/@magic-sdk/react-native-expo/src/index.ts index f983181d8..5f287a4e4 100644 --- a/packages/@magic-sdk/react-native-expo/src/index.ts +++ b/packages/@magic-sdk/react-native-expo/src/index.ts @@ -69,3 +69,5 @@ export type Magic = MagicSDKExtensionsOp SDKBaseReactNative, T >; + +export { useInternetConnection } from './hooks'; diff --git a/packages/@magic-sdk/react-native-expo/test/mocks.ts b/packages/@magic-sdk/react-native-expo/test/mocks.ts index e7af0a8fc..a5d8bed2e 100644 --- a/packages/@magic-sdk/react-native-expo/test/mocks.ts +++ b/packages/@magic-sdk/react-native-expo/test/mocks.ts @@ -9,6 +9,7 @@ export function removeReactDependencies() { jest.mock('react', noopModule); jest.mock('react-native-webview', noopModule); jest.mock('react-native-safe-area-context', noopModule); + jest.mock('@react-native-community/netinfo', noopModule); // 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 diff --git a/yarn.lock b/yarn.lock index 37fef0f8b..dd2b25b7a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2826,7 +2826,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/algorand@workspace:packages/@magic-ext/algorand" dependencies: - "@magic-sdk/commons": ^17.2.0 + "@magic-sdk/commons": ^17.2.1 languageName: unknown linkType: soft @@ -2835,8 +2835,8 @@ __metadata: resolution: "@magic-ext/aptos@workspace:packages/@magic-ext/aptos" dependencies: "@aptos-labs/wallet-adapter-core": ^2.2.0 - "@magic-sdk/commons": ^17.2.0 - "@magic-sdk/provider": ^21.2.0 + "@magic-sdk/commons": ^17.2.1 + "@magic-sdk/provider": ^21.2.1 aptos: ^1.8.5 peerDependencies: "@aptos-labs/wallet-adapter-core": ^2.2.0 @@ -2848,7 +2848,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/auth@workspace:packages/@magic-ext/auth" dependencies: - "@magic-sdk/commons": ^17.2.0 + "@magic-sdk/commons": ^17.2.1 languageName: unknown linkType: soft @@ -2856,7 +2856,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/avalanche@workspace:packages/@magic-ext/avalanche" dependencies: - "@magic-sdk/commons": ^17.2.0 + "@magic-sdk/commons": ^17.2.1 languageName: unknown linkType: soft @@ -2864,7 +2864,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/bitcoin@workspace:packages/@magic-ext/bitcoin" dependencies: - "@magic-sdk/commons": ^17.2.0 + "@magic-sdk/commons": ^17.2.1 languageName: unknown linkType: soft @@ -2872,7 +2872,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/conflux@workspace:packages/@magic-ext/conflux" dependencies: - "@magic-sdk/commons": ^17.2.0 + "@magic-sdk/commons": ^17.2.1 languageName: unknown linkType: soft @@ -2880,7 +2880,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/cosmos@workspace:packages/@magic-ext/cosmos" dependencies: - "@magic-sdk/commons": ^17.2.0 + "@magic-sdk/commons": ^17.2.1 languageName: unknown linkType: soft @@ -2888,7 +2888,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/ed25519@workspace:packages/@magic-ext/ed25519" dependencies: - "@magic-sdk/commons": ^17.2.0 + "@magic-sdk/commons": ^17.2.1 languageName: unknown linkType: soft @@ -2896,7 +2896,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/flow@workspace:packages/@magic-ext/flow" dependencies: - "@magic-sdk/commons": ^17.2.0 + "@magic-sdk/commons": ^17.2.1 "@onflow/fcl": ^1.4.1 "@onflow/types": ^1.1.0 peerDependencies: @@ -2909,7 +2909,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/gdkms@workspace:packages/@magic-ext/gdkms" dependencies: - "@magic-sdk/commons": ^17.2.0 + "@magic-sdk/commons": ^17.2.1 "@magic-sdk/types": ^17.2.0 "@peculiar/webcrypto": ^1.4.3 languageName: unknown @@ -2919,7 +2919,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/harmony@workspace:packages/@magic-ext/harmony" dependencies: - "@magic-sdk/commons": ^17.2.0 + "@magic-sdk/commons": ^17.2.1 languageName: unknown linkType: soft @@ -2937,7 +2937,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/icon@workspace:packages/@magic-ext/icon" dependencies: - "@magic-sdk/commons": ^17.2.0 + "@magic-sdk/commons": ^17.2.1 languageName: unknown linkType: soft @@ -2945,15 +2945,15 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/near@workspace:packages/@magic-ext/near" dependencies: - "@magic-sdk/commons": ^17.2.0 + "@magic-sdk/commons": ^17.2.1 languageName: unknown linkType: soft -"@magic-ext/oauth@^15.2.0, @magic-ext/oauth@workspace:packages/@magic-ext/oauth": +"@magic-ext/oauth@^15.2.1, @magic-ext/oauth@workspace:packages/@magic-ext/oauth": version: 0.0.0-use.local resolution: "@magic-ext/oauth@workspace:packages/@magic-ext/oauth" dependencies: - "@magic-sdk/commons": ^17.2.0 + "@magic-sdk/commons": ^17.2.1 "@types/crypto-js": ~3.1.47 crypto-js: ^3.3.0 languageName: unknown @@ -2963,7 +2963,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/oidc@workspace:packages/@magic-ext/oidc" dependencies: - "@magic-sdk/commons": ^17.2.0 + "@magic-sdk/commons": ^17.2.1 languageName: unknown linkType: soft @@ -2971,7 +2971,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/polkadot@workspace:packages/@magic-ext/polkadot" dependencies: - "@magic-sdk/commons": ^17.2.0 + "@magic-sdk/commons": ^17.2.1 languageName: unknown linkType: soft @@ -2979,7 +2979,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/react-native-bare-oauth@workspace:packages/@magic-ext/react-native-bare-oauth" dependencies: - "@magic-sdk/react-native-bare": ^22.2.1 + "@magic-sdk/react-native-bare": ^22.2.2 "@magic-sdk/types": ^10.0.1 "@types/crypto-js": ~3.1.47 crypto-js: ^3.3.0 @@ -2995,7 +2995,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/react-native-expo-oauth@workspace:packages/@magic-ext/react-native-expo-oauth" dependencies: - "@magic-sdk/react-native-expo": ^22.2.1 + "@magic-sdk/react-native-expo": ^22.2.2 "@magic-sdk/types": ^10.0.0 "@types/crypto-js": ~3.1.47 crypto-js: ^3.3.0 @@ -3010,7 +3010,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/solana@workspace:packages/@magic-ext/solana" dependencies: - "@magic-sdk/commons": ^17.2.0 + "@magic-sdk/commons": ^17.2.1 "@solana/web3.js": ^1.87.2 peerDependencies: "@solana/web3.js": ^1.87.2 @@ -3021,7 +3021,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/taquito@workspace:packages/@magic-ext/taquito" dependencies: - "@magic-sdk/commons": ^17.2.0 + "@magic-sdk/commons": ^17.2.1 languageName: unknown linkType: soft @@ -3029,7 +3029,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/terra@workspace:packages/@magic-ext/terra" dependencies: - "@magic-sdk/commons": ^17.2.0 + "@magic-sdk/commons": ^17.2.1 languageName: unknown linkType: soft @@ -3037,7 +3037,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/tezos@workspace:packages/@magic-ext/tezos" dependencies: - "@magic-sdk/commons": ^17.2.0 + "@magic-sdk/commons": ^17.2.1 languageName: unknown linkType: soft @@ -3045,7 +3045,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/webauthn@workspace:packages/@magic-ext/webauthn" dependencies: - "@magic-sdk/commons": ^17.2.0 + "@magic-sdk/commons": ^17.2.1 languageName: unknown linkType: soft @@ -3053,15 +3053,15 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/zilliqa@workspace:packages/@magic-ext/zilliqa" dependencies: - "@magic-sdk/commons": ^17.2.0 + "@magic-sdk/commons": ^17.2.1 languageName: unknown linkType: soft -"@magic-sdk/commons@^17.2.0, @magic-sdk/commons@workspace:packages/@magic-sdk/commons": +"@magic-sdk/commons@^17.2.1, @magic-sdk/commons@workspace:packages/@magic-sdk/commons": version: 0.0.0-use.local resolution: "@magic-sdk/commons@workspace:packages/@magic-sdk/commons" dependencies: - "@magic-sdk/provider": ^21.2.0 + "@magic-sdk/provider": ^21.2.1 "@magic-sdk/types": ^17.2.0 peerDependencies: "@magic-sdk/provider": ">=18.6.0" @@ -3086,12 +3086,12 @@ __metadata: "@babel/core": ^7.9.6 "@babel/plugin-proposal-optional-chaining": ^7.9.0 "@babel/runtime": ^7.9.6 - "@magic-ext/oauth": ^15.2.0 - magic-sdk: ^21.2.0 + "@magic-ext/oauth": ^15.2.1 + magic-sdk: ^21.2.1 languageName: unknown linkType: soft -"@magic-sdk/provider@^21.2.0, @magic-sdk/provider@workspace:packages/@magic-sdk/provider": +"@magic-sdk/provider@^21.2.1, @magic-sdk/provider@workspace:packages/@magic-sdk/provider": version: 0.0.0-use.local resolution: "@magic-sdk/provider@workspace:packages/@magic-sdk/provider" dependencies: @@ -3108,7 +3108,7 @@ __metadata: languageName: unknown linkType: soft -"@magic-sdk/react-native-bare@^22.2.1, @magic-sdk/react-native-bare@workspace:packages/@magic-sdk/react-native-bare": +"@magic-sdk/react-native-bare@^22.2.2, @magic-sdk/react-native-bare@workspace:packages/@magic-sdk/react-native-bare": version: 0.0.0-use.local resolution: "@magic-sdk/react-native-bare@workspace:packages/@magic-sdk/react-native-bare" dependencies: @@ -3116,10 +3116,11 @@ __metadata: "@babel/core": ^7.15.0 "@babel/plugin-transform-flow-strip-types": ^7.14.5 "@babel/runtime": ~7.10.4 - "@magic-sdk/commons": ^17.2.0 - "@magic-sdk/provider": ^21.2.0 + "@magic-sdk/commons": ^17.2.1 + "@magic-sdk/provider": ^21.2.1 "@magic-sdk/types": ^17.2.0 "@react-native-async-storage/async-storage": ^1.15.5 + "@react-native-community/netinfo": ">11.0.0" "@types/lodash": ^4.14.158 buffer: ~5.6.0 localforage: ^1.7.4 @@ -3136,6 +3137,7 @@ __metadata: whatwg-url: ~8.1.0 peerDependencies: "@react-native-async-storage/async-storage": ">=1.15.5" + "@react-native-community/netinfo": ">11.0.0" react: ">=16" react-native: ">=0.60" react-native-device-info: ">=10.3.0" @@ -3144,7 +3146,7 @@ __metadata: languageName: unknown linkType: soft -"@magic-sdk/react-native-expo@^22.2.1, @magic-sdk/react-native-expo@workspace:packages/@magic-sdk/react-native-expo": +"@magic-sdk/react-native-expo@^22.2.2, @magic-sdk/react-native-expo@workspace:packages/@magic-sdk/react-native-expo": version: 0.0.0-use.local resolution: "@magic-sdk/react-native-expo@workspace:packages/@magic-sdk/react-native-expo" dependencies: @@ -3152,10 +3154,11 @@ __metadata: "@babel/core": ^7.15.0 "@babel/plugin-transform-flow-strip-types": ^7.14.5 "@babel/runtime": ~7.10.4 - "@magic-sdk/commons": ^17.2.0 - "@magic-sdk/provider": ^21.2.0 + "@magic-sdk/commons": ^17.2.1 + "@magic-sdk/provider": ^21.2.1 "@magic-sdk/types": ^17.2.0 "@react-native-async-storage/async-storage": ^1.15.5 + "@react-native-community/netinfo": ">11.0.0" "@types/lodash": ^4.14.158 buffer: ~5.6.0 expo-application: ^5.0.1 @@ -3172,6 +3175,7 @@ __metadata: tslib: ^2.0.3 whatwg-url: ~8.1.0 peerDependencies: + "@react-native-community/netinfo": ">11.0.0" expo: "*" react: ">=16" react-native: ">=0.60" @@ -3877,6 +3881,15 @@ __metadata: languageName: node linkType: hard +"@react-native-community/netinfo@npm:>11.0.0": + version: 11.1.0 + resolution: "@react-native-community/netinfo@npm:11.1.0" + peerDependencies: + react-native: ">=0.59" + checksum: bbfa921c7d21f4c1c8bd01789256e096eed054ca6663caaa34446f1429f8394ec630c99f524a35e1a0a5873b3bc7f135e5721a7cc53f6cea68509b8723386db8 + languageName: node + linkType: hard + "@scure/base@npm:~1.1.0": version: 1.1.1 resolution: "@scure/base@npm:1.1.1" @@ -12987,15 +13000,15 @@ fsevents@^2.3.2: languageName: unknown linkType: soft -"magic-sdk@^21.2.0, magic-sdk@workspace:packages/magic-sdk": +"magic-sdk@^21.2.1, magic-sdk@workspace:packages/magic-sdk": version: 0.0.0-use.local resolution: "magic-sdk@workspace:packages/magic-sdk" dependencies: "@babel/core": ^7.9.6 "@babel/plugin-proposal-optional-chaining": ^7.9.0 "@babel/runtime": ^7.9.6 - "@magic-sdk/commons": ^17.2.0 - "@magic-sdk/provider": ^21.2.0 + "@magic-sdk/commons": ^17.2.1 + "@magic-sdk/provider": ^21.2.1 "@magic-sdk/types": ^17.2.0 localforage: ^1.7.4 localforage-driver-memory: ^1.0.5 From 5ea18b33343171e4f1e3273c2fa23d6080681e72 Mon Sep 17 00:00:00 2001 From: romin-halltari Date: Tue, 14 Nov 2023 15:10:07 -0800 Subject: [PATCH 02/11] Update readme with installation step for @react-native-community/netinfo --- packages/@magic-sdk/react-native-bare/README.md | 4 +++- packages/@magic-sdk/react-native-expo/README.md | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/@magic-sdk/react-native-bare/README.md b/packages/@magic-sdk/react-native-bare/README.md index 3c9e02199..b9dda3552 100644 --- a/packages/@magic-sdk/react-native-bare/README.md +++ b/packages/@magic-sdk/react-native-bare/README.md @@ -27,12 +27,14 @@ npm install --save @magic-sdk/react-native-bare npm install --save react-native-device-info # Required Peer Dependency npm install --save @react-native-community/async-storage # Required Peer Dependency npm install --save react-native-safe-area-context # Required Peer Dependency +npm install --save @react-native-community/netinfo # Required Peer Dependency # Via Yarn: yarn add @magic-sdk/react-native-bare -⁠yarn add react-native-device-info # Required Peer Dependency +yarn add react-native-device-info # Required Peer Dependency yarn add @react-native-community/async-storage # Required Peer Dependency yarn add react-native-safe-area-context # Required Peer Dependency +yarn add @react-native-community/netinfo # Required Peer Dependency ``` ## ⚡️ Quick Start diff --git a/packages/@magic-sdk/react-native-expo/README.md b/packages/@magic-sdk/react-native-expo/README.md index 4891da4ce..a0034891b 100644 --- a/packages/@magic-sdk/react-native-expo/README.md +++ b/packages/@magic-sdk/react-native-expo/README.md @@ -25,11 +25,13 @@ As of `v19.0.0`, passcodes (ie. `loginWithSMS()`, `loginWithEmailOTP()`) are rep npm install --save @magic-sdk/react-native-expo npm install --save react-native-webview@^11.26.0 # Required Peer Dependency npm install --save react-native-safe-area-context # Required Peer Dependency + npm install --save @react-native-community/netinfo # Required Peer Dependency # Via Yarn: yarn add @magic-sdk/react-native-expo yarn add react-native-webview@^11.26.0 # Required Peer Dependency yarn add react-native-safe-area-context # Required Peer Dependency + yarn add @react-native-community/netinfo # Required Peer Dependency ``` ## ⚡️ Quick Start From 82341cf2aa29b312a5d13149fcc15b72720a6eee Mon Sep 17 00:00:00 2001 From: romin-halltari Date: Wed, 15 Nov 2023 10:17:44 -0800 Subject: [PATCH 03/11] Setup testing with react-test-renderer and @testing-library/react-native --- .../react-native-expo/jest.config.ts | 2 +- .../@magic-sdk/react-native-expo/package.json | 4 +- .../react-native-expo/test/mocks.ts | 41 +- yarn.lock | 471 +++++++++++++++++- 4 files changed, 508 insertions(+), 10 deletions(-) diff --git a/packages/@magic-sdk/react-native-expo/jest.config.ts b/packages/@magic-sdk/react-native-expo/jest.config.ts index 5c03b1ea8..a948d3ed2 100644 --- a/packages/@magic-sdk/react-native-expo/jest.config.ts +++ b/packages/@magic-sdk/react-native-expo/jest.config.ts @@ -3,7 +3,7 @@ import type { Config } from '@jest/types'; const config: Config.InitialOptions = { ...baseJestConfig, - preset: 'react-native', + preset: '@testing-library/react-native', transform: { '^.+\\.(js|jsx)$': 'babel-jest', '\\.(ts|tsx)$': 'ts-jest', diff --git a/packages/@magic-sdk/react-native-expo/package.json b/packages/@magic-sdk/react-native-expo/package.json index 366ef6c38..a4a5f88f7 100644 --- a/packages/@magic-sdk/react-native-expo/package.json +++ b/packages/@magic-sdk/react-native-expo/package.json @@ -37,12 +37,14 @@ "@babel/plugin-transform-flow-strip-types": "^7.14.5", "@babel/runtime": "~7.10.4", "@react-native-community/netinfo": ">11.0.0", + "@testing-library/react-native": "^12.4.0", "expo-modules-core": "^1.0.4", "metro-react-native-babel-preset": "^0.66.2", "react": "^16.13.1", "react-native": "^0.62.2", "react-native-safe-area-context": "^4.4.1", - "react-native-webview": ">=12.4.0" + "react-native-webview": ">=12.4.0", + "react-test-renderer": "^16.13.1" }, "peerDependencies": { "@react-native-community/netinfo": ">11.0.0", diff --git a/packages/@magic-sdk/react-native-expo/test/mocks.ts b/packages/@magic-sdk/react-native-expo/test/mocks.ts index a5d8bed2e..f40970904 100644 --- a/packages/@magic-sdk/react-native-expo/test/mocks.ts +++ b/packages/@magic-sdk/react-native-expo/test/mocks.ts @@ -1,3 +1,41 @@ +// @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'); @@ -6,10 +44,9 @@ export function reactNativeStyleSheetStub() { const noopModule = () => ({}); export function removeReactDependencies() { - jest.mock('react', noopModule); jest.mock('react-native-webview', noopModule); jest.mock('react-native-safe-area-context', noopModule); - jest.mock('@react-native-community/netinfo', noopModule); + jest.mock('@react-native-community/netinfo', () => RNCNetInfoMock); // 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 diff --git a/yarn.lock b/yarn.lock index dd2b25b7a..885566702 100644 --- a/yarn.lock +++ b/yarn.lock @@ -172,6 +172,16 @@ __metadata: languageName: node linkType: hard +"@babel/code-frame@npm:^7.10.4": + version: 7.22.13 + resolution: "@babel/code-frame@npm:7.22.13" + dependencies: + "@babel/highlight": ^7.22.13 + chalk: ^2.4.2 + checksum: 22e342c8077c8b77eeb11f554ecca2ba14153f707b85294fcf6070b6f6150aae88a7b7436dd88d8c9289970585f3fe5b9b941c5aa3aa26a6d5a8ef3f292da058 + languageName: node + linkType: hard + "@babel/compat-data@npm:^7.17.7, @babel/compat-data@npm:^7.20.5": version: 7.21.0 resolution: "@babel/compat-data@npm:7.21.0" @@ -448,6 +458,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-identifier@npm:^7.22.20": + version: 7.22.20 + resolution: "@babel/helper-validator-identifier@npm:7.22.20" + checksum: 136412784d9428266bcdd4d91c32bcf9ff0e8d25534a9d94b044f77fe76bc50f941a90319b05aafd1ec04f7d127cd57a179a3716009ff7f3412ef835ada95bdc + languageName: node + linkType: hard + "@babel/helper-validator-option@npm:^7.18.6": version: 7.21.0 resolution: "@babel/helper-validator-option@npm:7.21.0" @@ -489,6 +506,17 @@ __metadata: languageName: node linkType: hard +"@babel/highlight@npm:^7.22.13": + version: 7.22.20 + resolution: "@babel/highlight@npm:7.22.20" + dependencies: + "@babel/helper-validator-identifier": ^7.22.20 + chalk: ^2.4.2 + js-tokens: ^4.0.0 + checksum: 84bd034dca309a5e680083cd827a766780ca63cef37308404f17653d32366ea76262bd2364b2d38776232f2d01b649f26721417d507e8b4b6da3e4e739f6d134 + languageName: node + linkType: hard + "@babel/parser@npm:^7.0.0, @babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.21.0, @babel/parser@npm:^7.21.2, @babel/parser@npm:^7.4.3": version: 7.21.2 resolution: "@babel/parser@npm:7.21.2" @@ -1175,7 +1203,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.17.2, @babel/runtime@npm:^7.22.6": +"@babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.17.2, @babel/runtime@npm:^7.22.6": version: 7.23.2 resolution: "@babel/runtime@npm:7.23.2" dependencies: @@ -1841,6 +1869,15 @@ __metadata: languageName: node linkType: hard +"@jest/schemas@npm:^29.6.3": + version: 29.6.3 + resolution: "@jest/schemas@npm:29.6.3" + dependencies: + "@sinclair/typebox": ^0.27.8 + checksum: 910040425f0fc93cd13e68c750b7885590b8839066dfa0cd78e7def07bbb708ad869381f725945d66f2284de5663bbecf63e8fdd856e2ae6e261ba30b1687e93 + languageName: node + linkType: hard + "@jest/source-map@npm:^24.9.0": version: 24.9.0 resolution: "@jest/source-map@npm:24.9.0" @@ -3121,6 +3158,7 @@ __metadata: "@magic-sdk/types": ^17.2.0 "@react-native-async-storage/async-storage": ^1.15.5 "@react-native-community/netinfo": ">11.0.0" + "@testing-library/react": 14 "@types/lodash": ^4.14.158 buffer: ~5.6.0 localforage: ^1.7.4 @@ -3133,6 +3171,7 @@ __metadata: react-native-device-info: ^10.3.0 react-native-safe-area-context: ^4.4.1 react-native-webview: ^12.4.0 + react-test-renderer: ^16.13.1 tslib: ^2.0.3 whatwg-url: ~8.1.0 peerDependencies: @@ -3159,6 +3198,7 @@ __metadata: "@magic-sdk/types": ^17.2.0 "@react-native-async-storage/async-storage": ^1.15.5 "@react-native-community/netinfo": ">11.0.0" + "@testing-library/react-native": ^12.4.0 "@types/lodash": ^4.14.158 buffer: ~5.6.0 expo-application: ^5.0.1 @@ -3172,6 +3212,7 @@ __metadata: react-native: ^0.62.2 react-native-safe-area-context: ^4.4.1 react-native-webview: ">=12.4.0" + react-test-renderer: ^16.13.1 tslib: ^2.0.3 whatwg-url: ~8.1.0 peerDependencies: @@ -3907,6 +3948,13 @@ __metadata: languageName: node linkType: hard +"@sinclair/typebox@npm:^0.27.8": + version: 0.27.8 + resolution: "@sinclair/typebox@npm:0.27.8" + checksum: 00bd7362a3439021aa1ea51b0e0d0a0e8ca1351a3d54c606b115fdcc49b51b16db6e5f43b4fe7a28c38688523e22a94d49dd31168868b655f0d4d50f032d07a1 + languageName: node + linkType: hard + "@sinonjs/commons@npm:^1.7.0": version: 1.8.6 resolution: "@sinonjs/commons@npm:1.8.6" @@ -3957,6 +4005,55 @@ __metadata: languageName: node linkType: hard +"@testing-library/dom@npm:^9.0.0": + version: 9.3.3 + resolution: "@testing-library/dom@npm:9.3.3" + dependencies: + "@babel/code-frame": ^7.10.4 + "@babel/runtime": ^7.12.5 + "@types/aria-query": ^5.0.1 + aria-query: 5.1.3 + chalk: ^4.1.0 + dom-accessibility-api: ^0.5.9 + lz-string: ^1.5.0 + pretty-format: ^27.0.2 + checksum: 34e0a564da7beb92aa9cc44a9080221e2412b1a132eb37be3d513fe6c58027674868deb9f86195756d98d15ba969a30fe00632a4e26e25df2a5a4f6ac0686e37 + languageName: node + linkType: hard + +"@testing-library/react-native@npm:^12.4.0": + version: 12.4.0 + resolution: "@testing-library/react-native@npm:12.4.0" + dependencies: + jest-matcher-utils: ^29.7.0 + pretty-format: ^29.7.0 + redent: ^3.0.0 + peerDependencies: + jest: ">=28.0.0" + react: ">=16.8.0" + react-native: ">=0.59" + react-test-renderer: ">=16.8.0" + peerDependenciesMeta: + jest: + optional: true + checksum: 417c6deaddda3c853c23ae9db21ee817c91cdeefebf6a905bbf85ff5038863f240a8f0a6c91e48a7171030e4d7ead093d7c4e1d075fb65e48b2b266b7fa0a5f3 + languageName: node + linkType: hard + +"@testing-library/react@npm:14": + version: 14.1.0 + resolution: "@testing-library/react@npm:14.1.0" + dependencies: + "@babel/runtime": ^7.12.5 + "@testing-library/dom": ^9.0.0 + "@types/react-dom": ^18.0.0 + peerDependencies: + react: ^18.0.0 + react-dom: ^18.0.0 + checksum: e76681911947f0981a1a72802ea01abeacdc4973c62deaf19c206cb9ff8d23eff5e3888c572303614686f029ee8a2a2dad6d0f0a9fb222944dbd9e0ea573b248 + languageName: node + linkType: hard + "@tootallnate/once@npm:1": version: 1.1.2 resolution: "@tootallnate/once@npm:1.1.2" @@ -3999,6 +4096,13 @@ __metadata: languageName: node linkType: hard +"@types/aria-query@npm:^5.0.1": + version: 5.0.4 + resolution: "@types/aria-query@npm:5.0.4" + checksum: ad8b87e4ad64255db5f0a73bc2b4da9b146c38a3a8ab4d9306154334e0fc67ae64e76bfa298eebd1e71830591fb15987e5de7111bdb36a2221bdc379e3415fb0 + languageName: node + linkType: hard + "@types/babel__core@npm:^7.0.0, @types/babel__core@npm:^7.1.14": version: 7.20.0 resolution: "@types/babel__core@npm:7.20.0" @@ -4301,6 +4405,15 @@ __metadata: languageName: node linkType: hard +"@types/react-dom@npm:^18.0.0": + version: 18.2.15 + resolution: "@types/react-dom@npm:18.2.15" + dependencies: + "@types/react": "*" + checksum: 8e9631600c21ff561328e38a951d1991b3b3b20f538af4c0efbd1327c883a5573a63f50e1b945c34fa51b114b30e1ca5e62317bd54f21e063d6697b4be843a03 + languageName: node + linkType: hard + "@types/react-native@npm:^0.70.5": version: 0.70.11 resolution: "@types/react-native@npm:0.70.11" @@ -5048,6 +5161,15 @@ __metadata: languageName: node linkType: hard +"aria-query@npm:5.1.3": + version: 5.1.3 + resolution: "aria-query@npm:5.1.3" + dependencies: + deep-equal: ^2.0.5 + checksum: 929ff95f02857b650fb4cbcd2f41072eee2f46159a6605ea03bf63aa572e35ffdff43d69e815ddc462e16e07de8faba3978afc2813650b4448ee18c9895d982b + languageName: node + linkType: hard + "aria-query@npm:^4.2.2": version: 4.2.2 resolution: "aria-query@npm:4.2.2" @@ -5110,6 +5232,16 @@ __metadata: languageName: node linkType: hard +"array-buffer-byte-length@npm:^1.0.0": + version: 1.0.0 + resolution: "array-buffer-byte-length@npm:1.0.0" + dependencies: + call-bind: ^1.0.2 + is-array-buffer: ^3.0.1 + checksum: 044e101ce150f4804ad19c51d6c4d4cfa505c5b2577bd179256e4aa3f3f6a0a5e9874c78cd428ee566ac574c8a04d7ce21af9fe52e844abfdccb82b33035a7c3 + languageName: node + linkType: hard + "array-differ@npm:^2.0.3": version: 2.1.0 resolution: "array-differ@npm:2.1.0" @@ -6080,6 +6212,17 @@ __metadata: languageName: node linkType: hard +"call-bind@npm:^1.0.4, call-bind@npm:^1.0.5": + version: 1.0.5 + resolution: "call-bind@npm:1.0.5" + dependencies: + function-bind: ^1.1.2 + get-intrinsic: ^1.2.1 + set-function-length: ^1.1.1 + checksum: 449e83ecbd4ba48e7eaac5af26fea3b50f8f6072202c2dd7c5a6e7a6308f2421abe5e13a3bbd55221087f76320c5e09f25a8fdad1bab2b77c68ae74d92234ea5 + languageName: node + linkType: hard + "call-me-maybe@npm:^1.0.1": version: 1.0.2 resolution: "call-me-maybe@npm:1.0.2" @@ -7294,6 +7437,32 @@ __metadata: languageName: node linkType: hard +"deep-equal@npm:^2.0.5": + version: 2.2.3 + resolution: "deep-equal@npm:2.2.3" + dependencies: + array-buffer-byte-length: ^1.0.0 + call-bind: ^1.0.5 + es-get-iterator: ^1.1.3 + get-intrinsic: ^1.2.2 + is-arguments: ^1.1.1 + is-array-buffer: ^3.0.2 + is-date-object: ^1.0.5 + is-regex: ^1.1.4 + is-shared-array-buffer: ^1.0.2 + isarray: ^2.0.5 + object-is: ^1.1.5 + object-keys: ^1.1.1 + object.assign: ^4.1.4 + regexp.prototype.flags: ^1.5.1 + side-channel: ^1.0.4 + which-boxed-primitive: ^1.0.2 + which-collection: ^1.0.1 + which-typed-array: ^1.1.13 + checksum: ee8852f23e4d20a5626c13b02f415ba443a1b30b4b3d39eaf366d59c4a85e6545d7ec917db44d476a85ae5a86064f7e5f7af7479f38f113995ba869f3a1ddc53 + languageName: node + linkType: hard + "deep-extend@npm:^0.6.0, deep-extend@npm:~0.6.0": version: 0.6.0 resolution: "deep-extend@npm:0.6.0" @@ -7340,6 +7509,17 @@ __metadata: languageName: node linkType: hard +"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.1": + version: 1.1.1 + resolution: "define-data-property@npm:1.1.1" + dependencies: + get-intrinsic: ^1.2.1 + gopd: ^1.0.1 + has-property-descriptors: ^1.0.0 + checksum: a29855ad3f0630ea82e3c5012c812efa6ca3078d5c2aa8df06b5f597c1cde6f7254692df41945851d903e05a1668607b6d34e778f402b9ff9ffb38111f1a3f0d + languageName: node + linkType: hard + "define-properties@npm:^1.1.3, define-properties@npm:^1.1.4": version: 1.2.0 resolution: "define-properties@npm:1.2.0" @@ -7350,6 +7530,17 @@ __metadata: languageName: node linkType: hard +"define-properties@npm:^1.2.0": + version: 1.2.1 + resolution: "define-properties@npm:1.2.1" + dependencies: + define-data-property: ^1.0.1 + has-property-descriptors: ^1.0.0 + object-keys: ^1.1.1 + checksum: b4ccd00597dd46cb2d4a379398f5b19fca84a16f3374e2249201992f36b30f6835949a9429669ee6b41b6e837205a163eadd745e472069e70dfc10f03e5fcc12 + languageName: node + linkType: hard + "define-property@npm:^0.2.5": version: 0.2.5 resolution: "define-property@npm:0.2.5" @@ -7465,6 +7656,13 @@ __metadata: languageName: node linkType: hard +"diff-sequences@npm:^29.6.3": + version: 29.6.3 + resolution: "diff-sequences@npm:29.6.3" + checksum: f4914158e1f2276343d98ff5b31fc004e7304f5470bf0f1adb2ac6955d85a531a6458d33e87667f98f6ae52ebd3891bb47d420bb48a5bd8b7a27ee25b20e33aa + languageName: node + linkType: hard + "diff@npm:^4.0.1": version: 4.0.2 resolution: "diff@npm:4.0.2" @@ -7499,6 +7697,13 @@ __metadata: languageName: node linkType: hard +"dom-accessibility-api@npm:^0.5.9": + version: 0.5.16 + resolution: "dom-accessibility-api@npm:0.5.16" + checksum: 005eb283caef57fc1adec4d5df4dd49189b628f2f575af45decb210e04d634459e3f1ee64f18b41e2dcf200c844bc1d9279d80807e686a30d69a4756151ad248 + languageName: node + linkType: hard + "dom-walk@npm:^0.1.0": version: 0.1.2 resolution: "dom-walk@npm:0.1.2" @@ -7811,6 +8016,23 @@ __metadata: languageName: node linkType: hard +"es-get-iterator@npm:^1.1.3": + version: 1.1.3 + resolution: "es-get-iterator@npm:1.1.3" + dependencies: + call-bind: ^1.0.2 + get-intrinsic: ^1.1.3 + has-symbols: ^1.0.3 + is-arguments: ^1.1.1 + is-map: ^2.0.2 + is-set: ^2.0.2 + is-string: ^1.0.7 + isarray: ^2.0.5 + stop-iteration-iterator: ^1.0.0 + checksum: 8fa118da42667a01a7c7529f8a8cca514feeff243feec1ce0bb73baaa3514560bd09d2b3438873cf8a5aaec5d52da248131de153b28e2638a061b6e4df13267d + languageName: node + linkType: hard + "es-set-tostringtag@npm:^2.0.1": version: 2.0.1 resolution: "es-set-tostringtag@npm:2.0.1" @@ -9562,6 +9784,13 @@ fsevents@^2.3.2: languageName: node linkType: hard +"function-bind@npm:^1.1.2": + version: 1.1.2 + resolution: "function-bind@npm:1.1.2" + checksum: 2b0ff4ce708d99715ad14a6d1f894e2a83242e4a52ccfcefaee5e40050562e5f6dafc1adbb4ce2d4ab47279a45dc736ab91ea5042d843c3c092820dfe032efb1 + languageName: node + linkType: hard + "function.prototype.name@npm:^1.1.5": version: 1.1.5 resolution: "function.prototype.name@npm:1.1.5" @@ -9581,7 +9810,7 @@ fsevents@^2.3.2: languageName: node linkType: hard -"functions-have-names@npm:^1.2.2": +"functions-have-names@npm:^1.2.2, functions-have-names@npm:^1.2.3": version: 1.2.3 resolution: "functions-have-names@npm:1.2.3" checksum: c3f1f5ba20f4e962efb71344ce0a40722163e85bee2101ce25f88214e78182d2d2476aa85ef37950c579eb6cf6ee811c17b3101bb84004bb75655f3e33f3fdb5 @@ -9659,6 +9888,18 @@ fsevents@^2.3.2: languageName: node linkType: hard +"get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.2": + version: 1.2.2 + resolution: "get-intrinsic@npm:1.2.2" + dependencies: + function-bind: ^1.1.2 + has-proto: ^1.0.1 + has-symbols: ^1.0.3 + hasown: ^2.0.0 + checksum: 447ff0724df26829908dc033b62732359596fcf66027bc131ab37984afb33842d9cd458fd6cecadfe7eac22fd8a54b349799ed334cf2726025c921c7250e7417 + languageName: node + linkType: hard + "get-monorepo-packages@npm:^1.1.0": version: 1.2.0 resolution: "get-monorepo-packages@npm:1.2.0" @@ -10214,6 +10455,15 @@ fsevents@^2.3.2: languageName: node linkType: hard +"hasown@npm:^2.0.0": + version: 2.0.0 + resolution: "hasown@npm:2.0.0" + dependencies: + function-bind: ^1.1.2 + checksum: 6151c75ca12554565098641c98a40f4cc86b85b0fd5b6fe92360967e4605a4f9610f7757260b4e8098dd1c2ce7f4b095f2006fe72a570e3b6d2d28de0298c176 + languageName: node + linkType: hard + "hermes-engine@npm:~0.4.0": version: 0.4.3 resolution: "hermes-engine@npm:0.4.3" @@ -10776,7 +11026,7 @@ fsevents@^2.3.2: languageName: node linkType: hard -"is-arguments@npm:^1.0.4": +"is-arguments@npm:^1.0.4, is-arguments@npm:^1.1.1": version: 1.1.1 resolution: "is-arguments@npm:1.1.1" dependencies: @@ -10797,6 +11047,17 @@ fsevents@^2.3.2: languageName: node linkType: hard +"is-array-buffer@npm:^3.0.2": + version: 3.0.2 + resolution: "is-array-buffer@npm:3.0.2" + dependencies: + call-bind: ^1.0.2 + get-intrinsic: ^1.2.0 + is-typed-array: ^1.1.10 + checksum: dcac9dda66ff17df9cabdc58214172bf41082f956eab30bb0d86bc0fab1e44b690fc8e1f855cf2481245caf4e8a5a006a982a71ddccec84032ed41f9d8da8c14 + languageName: node + linkType: hard + "is-arrayish@npm:^0.2.1": version: 0.2.1 resolution: "is-arrayish@npm:0.2.1" @@ -10886,7 +11147,7 @@ fsevents@^2.3.2: languageName: node linkType: hard -"is-date-object@npm:^1.0.1": +"is-date-object@npm:^1.0.1, is-date-object@npm:^1.0.5": version: 1.0.5 resolution: "is-date-object@npm:1.0.5" dependencies: @@ -11039,6 +11300,13 @@ fsevents@^2.3.2: languageName: node linkType: hard +"is-map@npm:^2.0.1, is-map@npm:^2.0.2": + version: 2.0.2 + resolution: "is-map@npm:2.0.2" + checksum: ace3d0ecd667bbdefdb1852de601268f67f2db725624b1958f279316e13fecb8fa7df91fd60f690d7417b4ec180712f5a7ee967008e27c65cfd475cc84337728 + languageName: node + linkType: hard + "is-negative-zero@npm:^2.0.2": version: 2.0.2 resolution: "is-negative-zero@npm:2.0.2" @@ -11146,6 +11414,13 @@ fsevents@^2.3.2: languageName: node linkType: hard +"is-set@npm:^2.0.1, is-set@npm:^2.0.2": + version: 2.0.2 + resolution: "is-set@npm:2.0.2" + checksum: b64343faf45e9387b97a6fd32be632ee7b269bd8183701f3b3f5b71a7cf00d04450ed8669d0bd08753e08b968beda96fca73a10fd0ff56a32603f64deba55a57 + languageName: node + linkType: hard + "is-shared-array-buffer@npm:^1.0.2": version: 1.0.2 resolution: "is-shared-array-buffer@npm:1.0.2" @@ -11239,6 +11514,13 @@ fsevents@^2.3.2: languageName: node linkType: hard +"is-weakmap@npm:^2.0.1": + version: 2.0.1 + resolution: "is-weakmap@npm:2.0.1" + checksum: 1222bb7e90c32bdb949226e66d26cb7bce12e1e28e3e1b40bfa6b390ba3e08192a8664a703dff2a00a84825f4e022f9cd58c4599ff9981ab72b1d69479f4f7f6 + languageName: node + linkType: hard + "is-weakref@npm:^1.0.2": version: 1.0.2 resolution: "is-weakref@npm:1.0.2" @@ -11248,6 +11530,16 @@ fsevents@^2.3.2: languageName: node linkType: hard +"is-weakset@npm:^2.0.1": + version: 2.0.2 + resolution: "is-weakset@npm:2.0.2" + dependencies: + call-bind: ^1.0.2 + get-intrinsic: ^1.1.1 + checksum: 5d8698d1fa599a0635d7ca85be9c26d547b317ed8fd83fc75f03efbe75d50001b5eececb1e9971de85fcde84f69ae6f8346bc92d20d55d46201d328e4c74a367 + languageName: node + linkType: hard + "is-windows@npm:^1.0.0, is-windows@npm:^1.0.2": version: 1.0.2 resolution: "is-windows@npm:1.0.2" @@ -11269,6 +11561,13 @@ fsevents@^2.3.2: languageName: node linkType: hard +"isarray@npm:^2.0.5": + version: 2.0.5 + resolution: "isarray@npm:2.0.5" + checksum: bd5bbe4104438c4196ba58a54650116007fa0262eccef13a4c55b2e09a5b36b59f1e75b9fcc49883dd9d4953892e6fc007eef9e9155648ceea036e184b0f930a + languageName: node + linkType: hard + "isexe@npm:^2.0.0": version: 2.0.0 resolution: "isexe@npm:2.0.0" @@ -11595,6 +11894,18 @@ fsevents@^2.3.2: languageName: node linkType: hard +"jest-diff@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-diff@npm:29.7.0" + dependencies: + chalk: ^4.0.0 + diff-sequences: ^29.6.3 + jest-get-type: ^29.6.3 + pretty-format: ^29.7.0 + checksum: 08e24a9dd43bfba1ef07a6374e5af138f53137b79ec3d5cc71a2303515335898888fa5409959172e1e05de966c9e714368d15e8994b0af7441f0721ee8e1bb77 + languageName: node + linkType: hard + "jest-docblock@npm:^27.5.1": version: 27.5.1 resolution: "jest-docblock@npm:27.5.1" @@ -11660,6 +11971,13 @@ fsevents@^2.3.2: languageName: node linkType: hard +"jest-get-type@npm:^29.6.3": + version: 29.6.3 + resolution: "jest-get-type@npm:29.6.3" + checksum: 88ac9102d4679d768accae29f1e75f592b760b44277df288ad76ce5bf038c3f5ce3719dea8aa0f035dac30e9eb034b848ce716b9183ad7cc222d029f03e92205 + languageName: node + linkType: hard + "jest-haste-map@npm:^24.9.0": version: 24.9.0 resolution: "jest-haste-map@npm:24.9.0" @@ -11754,6 +12072,18 @@ fsevents@^2.3.2: languageName: node linkType: hard +"jest-matcher-utils@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-matcher-utils@npm:29.7.0" + dependencies: + chalk: ^4.0.0 + jest-diff: ^29.7.0 + jest-get-type: ^29.6.3 + pretty-format: ^29.7.0 + checksum: d7259e5f995d915e8a37a8fd494cb7d6af24cd2a287b200f831717ba0d015190375f9f5dc35393b8ba2aae9b2ebd60984635269c7f8cff7d85b077543b7744cd + languageName: node + linkType: hard + "jest-message-util@npm:^24.9.0": version: 24.9.0 resolution: "jest-message-util@npm:24.9.0" @@ -12928,6 +13258,15 @@ fsevents@^2.3.2: languageName: node linkType: hard +"lz-string@npm:^1.5.0": + version: 1.5.0 + resolution: "lz-string@npm:1.5.0" + bin: + lz-string: bin/bin.js + checksum: 1ee98b4580246fd90dd54da6e346fb1caefcf05f677c686d9af237a157fdea3fd7c83a4bc58f858cd5b10a34d27afe0fdcbd0505a47e0590726a873dc8b8f65d + languageName: node + linkType: hard + "macos-release@npm:^2.2.0": version: 2.5.1 resolution: "macos-release@npm:2.5.1" @@ -14712,6 +15051,16 @@ fsevents@^2.3.2: languageName: node linkType: hard +"object-is@npm:^1.1.5": + version: 1.1.5 + resolution: "object-is@npm:1.1.5" + dependencies: + call-bind: ^1.0.2 + define-properties: ^1.1.3 + checksum: 989b18c4cba258a6b74dc1d74a41805c1a1425bce29f6cabb50dcb1a6a651ea9104a1b07046739a49a5bb1bc49727bcb00efd5c55f932f6ea04ec8927a7901fe + languageName: node + linkType: hard + "object-keys@npm:^1.1.1": version: 1.1.1 resolution: "object-keys@npm:1.1.1" @@ -15646,7 +15995,7 @@ fsevents@^2.3.2: languageName: node linkType: hard -"pretty-format@npm:^27.0.0, pretty-format@npm:^27.5.1": +"pretty-format@npm:^27.0.0, pretty-format@npm:^27.0.2, pretty-format@npm:^27.5.1": version: 27.5.1 resolution: "pretty-format@npm:27.5.1" dependencies: @@ -15657,6 +16006,17 @@ fsevents@^2.3.2: languageName: node linkType: hard +"pretty-format@npm:^29.7.0": + version: 29.7.0 + resolution: "pretty-format@npm:29.7.0" + dependencies: + "@jest/schemas": ^29.6.3 + ansi-styles: ^5.0.0 + react-is: ^18.0.0 + checksum: 032c1602383e71e9c0c02a01bbd25d6759d60e9c7cf21937dde8357aa753da348fcec5def5d1002c9678a8524d5fe099ad98861286550ef44de8808cc61e43b6 + languageName: node + linkType: hard + "pretty-ms@npm:^7.0.0": version: 7.0.1 resolution: "pretty-ms@npm:7.0.1" @@ -15997,7 +16357,7 @@ fsevents@^2.3.2: languageName: node linkType: hard -"react-is@npm:^16.12.0, react-is@npm:^16.13.1, react-is@npm:^16.8.4": +"react-is@npm:^16.12.0, react-is@npm:^16.13.1, react-is@npm:^16.8.4, react-is@npm:^16.8.6": version: 16.13.1 resolution: "react-is@npm:16.13.1" checksum: f7a19ac3496de32ca9ae12aa030f00f14a3d45374f1ceca0af707c831b2a6098ef0d6bdae51bd437b0a306d7f01d4677fcc8de7c0d331eb47ad0f46130e53c5f @@ -16011,6 +16371,13 @@ fsevents@^2.3.2: languageName: node linkType: hard +"react-is@npm:^18.0.0": + version: 18.2.0 + resolution: "react-is@npm:18.2.0" + checksum: e72d0ba81b5922759e4aff17e0252bd29988f9642ed817f56b25a3e217e13eea8a7f2322af99a06edb779da12d5d636e9fda473d620df9a3da0df2a74141d53e + languageName: node + linkType: hard + "react-native-device-info@npm:^10.3.0": version: 10.4.0 resolution: "react-native-device-info@npm:10.4.0" @@ -16127,6 +16494,20 @@ fsevents@^2.3.2: languageName: node linkType: hard +"react-test-renderer@npm:^16.13.1": + version: 16.14.0 + resolution: "react-test-renderer@npm:16.14.0" + dependencies: + object-assign: ^4.1.1 + prop-types: ^15.6.2 + react-is: ^16.8.6 + scheduler: ^0.19.1 + peerDependencies: + react: ^16.14.0 + checksum: 96eb8a2566e67ebd246ef6e1b36d8c8498c68ebfdb94ca8399c19b4e3b73368caf0ffbe44767593e3499f2f58b4b5e57ba0565a47628048d2ab01b23a422724e + languageName: node + linkType: hard + "react@npm:^16.13.1": version: 16.14.0 resolution: "react@npm:16.14.0" @@ -16396,6 +16777,17 @@ fsevents@^2.3.2: languageName: node linkType: hard +"regexp.prototype.flags@npm:^1.5.1": + version: 1.5.1 + resolution: "regexp.prototype.flags@npm:1.5.1" + dependencies: + call-bind: ^1.0.2 + define-properties: ^1.2.0 + set-function-name: ^2.0.0 + checksum: 869edff00288442f8d7fa4c9327f91d85f3b3acf8cbbef9ea7a220345cf23e9241b6def9263d2c1ebcf3a316b0aa52ad26a43a84aa02baca3381717b3e307f47 + languageName: node + linkType: hard + "regexpp@npm:^3.0.0, regexpp@npm:^3.1.0": version: 3.2.0 resolution: "regexpp@npm:3.2.0" @@ -16982,6 +17374,16 @@ resolve@~1.7.1: languageName: node linkType: hard +"scheduler@npm:^0.19.1": + version: 0.19.1 + resolution: "scheduler@npm:0.19.1" + dependencies: + loose-envify: ^1.1.0 + object-assign: ^4.1.1 + checksum: 73e185a59e2ff5aa3609f5b9cb97ddd376f89e1610579d29939d952411ca6eb7a24907a4ea4556569dacb931467a1a4a56d94fe809ef713aa76748642cd96a6c + languageName: node + linkType: hard + "scrypt-js@npm:^3.0.0": version: 3.0.1 resolution: "scrypt-js@npm:3.0.1" @@ -17091,6 +17493,29 @@ resolve@~1.7.1: languageName: node linkType: hard +"set-function-length@npm:^1.1.1": + version: 1.1.1 + resolution: "set-function-length@npm:1.1.1" + dependencies: + define-data-property: ^1.1.1 + get-intrinsic: ^1.2.1 + gopd: ^1.0.1 + has-property-descriptors: ^1.0.0 + checksum: c131d7569cd7e110cafdfbfbb0557249b538477624dfac4fc18c376d879672fa52563b74029ca01f8f4583a8acb35bb1e873d573a24edb80d978a7ee607c6e06 + languageName: node + linkType: hard + +"set-function-name@npm:^2.0.0": + version: 2.0.1 + resolution: "set-function-name@npm:2.0.1" + dependencies: + define-data-property: ^1.0.1 + functions-have-names: ^1.2.3 + has-property-descriptors: ^1.0.0 + checksum: 4975d17d90c40168eee2c7c9c59d023429f0a1690a89d75656306481ece0c3c1fb1ebcc0150ea546d1913e35fbd037bace91372c69e543e51fc5d1f31a9fa126 + languageName: node + linkType: hard + "set-value@npm:^2.0.0, set-value@npm:^2.0.1": version: 2.0.1 resolution: "set-value@npm:2.0.1" @@ -17679,6 +18104,15 @@ resolve@~1.7.1: languageName: node linkType: hard +"stop-iteration-iterator@npm:^1.0.0": + version: 1.0.0 + resolution: "stop-iteration-iterator@npm:1.0.0" + dependencies: + internal-slot: ^1.0.4 + checksum: d04173690b2efa40e24ab70e5e51a3ff31d56d699550cfad084104ab3381390daccb36652b25755e420245f3b0737de66c1879eaa2a8d4fc0a78f9bf892fcb42 + languageName: node + linkType: hard + "stream-buffers@npm:2.2.x": version: 2.2.0 resolution: "stream-buffers@npm:2.2.0" @@ -19589,6 +20023,18 @@ typescript@~4.4.2: languageName: node linkType: hard +"which-collection@npm:^1.0.1": + version: 1.0.1 + resolution: "which-collection@npm:1.0.1" + dependencies: + is-map: ^2.0.1 + is-set: ^2.0.1 + is-weakmap: ^2.0.1 + is-weakset: ^2.0.1 + checksum: c815bbd163107ef9cb84f135e6f34453eaf4cca994e7ba85ddb0d27cea724c623fae2a473ceccfd5549c53cc65a5d82692de418166df3f858e1e5dc60818581c + languageName: node + linkType: hard + "which-module@npm:^2.0.0": version: 2.0.0 resolution: "which-module@npm:2.0.0" @@ -19596,6 +20042,19 @@ typescript@~4.4.2: languageName: node linkType: hard +"which-typed-array@npm:^1.1.13": + version: 1.1.13 + resolution: "which-typed-array@npm:1.1.13" + dependencies: + available-typed-arrays: ^1.0.5 + call-bind: ^1.0.4 + for-each: ^0.3.3 + gopd: ^1.0.1 + has-tostringtag: ^1.0.0 + checksum: 3828a0d5d72c800e369d447e54c7620742a4cc0c9baf1b5e8c17e9b6ff90d8d861a3a6dd4800f1953dbf80e5e5cec954a289e5b4a223e3bee4aeb1f8c5f33309 + languageName: node + linkType: hard + "which-typed-array@npm:^1.1.2, which-typed-array@npm:^1.1.9": version: 1.1.9 resolution: "which-typed-array@npm:1.1.9" From 7e38eba0c32fe6d9b0e7ed3774ffbe417570e639 Mon Sep 17 00:00:00 2001 From: romin-halltari Date: Wed, 15 Nov 2023 10:18:21 -0800 Subject: [PATCH 04/11] add tests for useInternetConnection hook --- .../@magic-sdk/react-native-expo/src/hooks.ts | 7 +-- .../react-native-expo/test/spec/hooks.spec.ts | 55 +++++++++++++++++++ 2 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 packages/@magic-sdk/react-native-expo/test/spec/hooks.spec.ts diff --git a/packages/@magic-sdk/react-native-expo/src/hooks.ts b/packages/@magic-sdk/react-native-expo/src/hooks.ts index fe3b04eff..8178bfa35 100644 --- a/packages/@magic-sdk/react-native-expo/src/hooks.ts +++ b/packages/@magic-sdk/react-native-expo/src/hooks.ts @@ -9,12 +9,7 @@ export const useInternetConnection = () => { }; // Subscribe to connection changes - const unsubscribe = NetInfo.addEventListener(handleConnectionChange); - - // Cleanup on unmount - return () => { - unsubscribe(); - }; + return NetInfo.addEventListener(handleConnectionChange); }, []); return isConnected; diff --git a/packages/@magic-sdk/react-native-expo/test/spec/hooks.spec.ts b/packages/@magic-sdk/react-native-expo/test/spec/hooks.spec.ts new file mode 100644 index 000000000..eded37cf0 --- /dev/null +++ b/packages/@magic-sdk/react-native-expo/test/spec/hooks.spec.ts @@ -0,0 +1,55 @@ +import { act, renderHook } from '@testing-library/react-native'; +import NetInfo, { NetInfoStateType } from '@react-native-community/netinfo'; +import { useInternetConnection } from '../../src/hooks'; + +beforeAll(() => { + // @ts-ignore mock resolved value + NetInfo.getCurrentState.mockResolvedValue({ + type: NetInfoStateType.cellular, + isConnected: true, + isInternetReachable: true, + details: { + isConnectionExpensive: true, + cellularGeneration: '4g', + }, + }); +}); + +describe('useInternetConnection', () => { + it('should initialize with true when connected', async () => { + const { result } = renderHook(() => useInternetConnection()); + + expect(result.current).toBe(true); + }); + + it('should call the listener when the connection changes', async () => { + NetInfo.addEventListener = jest.fn(); + + const { result } = renderHook(() => useInternetConnection()); + + // Initial render, assuming it's connected + expect(result.current).toBe(true); + + // Simulate a change in connection status + act(() => { + // @ts-ignore mock calls + NetInfo.addEventListener.mock.calls[0][0]({ + type: 'cellular', // Replace with your desired type + isConnected: false, + isInternetReachable: true, + details: { + isConnectionExpensive: true, + // Add other details as needed for your hook + }, + }); + }); + + // 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 + }); + + // Check if the hook state has been updated + expect(result.current).toBe(false); + }); +}); From e7ab328946259baa518e43ddf4e010b11df1da08 Mon Sep 17 00:00:00 2001 From: romin-halltari Date: Wed, 15 Nov 2023 10:35:11 -0800 Subject: [PATCH 05/11] Setup hook testing on @magic/sdk/react-native-bare --- .../react-native-bare/jest.config.ts | 2 +- .../@magic-sdk/react-native-bare/package.json | 4 +- .../@magic-sdk/react-native-bare/src/hooks.ts | 9 +- .../react-native-bare/test/mocks.ts | 41 +- .../react-native-bare/test/spec/hooks.spec.ts | 55 +++ yarn.lock | 352 +----------------- 6 files changed, 106 insertions(+), 357 deletions(-) create mode 100644 packages/@magic-sdk/react-native-bare/test/spec/hooks.spec.ts diff --git a/packages/@magic-sdk/react-native-bare/jest.config.ts b/packages/@magic-sdk/react-native-bare/jest.config.ts index 5c03b1ea8..a948d3ed2 100644 --- a/packages/@magic-sdk/react-native-bare/jest.config.ts +++ b/packages/@magic-sdk/react-native-bare/jest.config.ts @@ -3,7 +3,7 @@ import type { Config } from '@jest/types'; const config: Config.InitialOptions = { ...baseJestConfig, - preset: 'react-native', + preset: '@testing-library/react-native', transform: { '^.+\\.(js|jsx)$': 'babel-jest', '\\.(ts|tsx)$': 'ts-jest', diff --git a/packages/@magic-sdk/react-native-bare/package.json b/packages/@magic-sdk/react-native-bare/package.json index ad229c334..9569ead82 100644 --- a/packages/@magic-sdk/react-native-bare/package.json +++ b/packages/@magic-sdk/react-native-bare/package.json @@ -38,12 +38,14 @@ "@babel/runtime": "~7.10.4", "@react-native-async-storage/async-storage": "^1.15.5", "@react-native-community/netinfo": ">11.0.0", + "@testing-library/react-native": "^12.4.0", "metro-react-native-babel-preset": "^0.66.2", "react": "^16.13.1", "react-native": "^0.62.2", "react-native-device-info": "^10.3.0", "react-native-safe-area-context": "^4.4.1", - "react-native-webview": "^12.4.0" + "react-native-webview": "^12.4.0", + "react-test-renderer": "^16.13.1" }, "peerDependencies": { "@react-native-async-storage/async-storage": ">=1.15.5", diff --git a/packages/@magic-sdk/react-native-bare/src/hooks.ts b/packages/@magic-sdk/react-native-bare/src/hooks.ts index fe3b04eff..fb68bcece 100644 --- a/packages/@magic-sdk/react-native-bare/src/hooks.ts +++ b/packages/@magic-sdk/react-native-bare/src/hooks.ts @@ -8,13 +8,8 @@ export const useInternetConnection = () => { setIsConnected(!!connectionInfo.isConnected); }; - // Subscribe to connection changes - const unsubscribe = NetInfo.addEventListener(handleConnectionChange); - - // Cleanup on unmount - return () => { - unsubscribe(); - }; + // Subscribe to connection changes and cleanup on unmount + return NetInfo.addEventListener(handleConnectionChange); }, []); return isConnected; diff --git a/packages/@magic-sdk/react-native-bare/test/mocks.ts b/packages/@magic-sdk/react-native-bare/test/mocks.ts index e914bcc56..2656ebedc 100644 --- a/packages/@magic-sdk/react-native-bare/test/mocks.ts +++ b/packages/@magic-sdk/react-native-bare/test/mocks.ts @@ -1,3 +1,41 @@ +// @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'); @@ -6,10 +44,9 @@ export function reactNativeStyleSheetStub() { const noopModule = () => ({}); export function removeReactDependencies() { - jest.mock('react', noopModule); jest.mock('react-native-webview', noopModule); jest.mock('react-native-safe-area-context', noopModule); - jest.mock('@react-native-community/netinfo', noopModule); + jest.mock('@react-native-community/netinfo', () => RNCNetInfoMock); // 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 diff --git a/packages/@magic-sdk/react-native-bare/test/spec/hooks.spec.ts b/packages/@magic-sdk/react-native-bare/test/spec/hooks.spec.ts new file mode 100644 index 000000000..eded37cf0 --- /dev/null +++ b/packages/@magic-sdk/react-native-bare/test/spec/hooks.spec.ts @@ -0,0 +1,55 @@ +import { act, renderHook } from '@testing-library/react-native'; +import NetInfo, { NetInfoStateType } from '@react-native-community/netinfo'; +import { useInternetConnection } from '../../src/hooks'; + +beforeAll(() => { + // @ts-ignore mock resolved value + NetInfo.getCurrentState.mockResolvedValue({ + type: NetInfoStateType.cellular, + isConnected: true, + isInternetReachable: true, + details: { + isConnectionExpensive: true, + cellularGeneration: '4g', + }, + }); +}); + +describe('useInternetConnection', () => { + it('should initialize with true when connected', async () => { + const { result } = renderHook(() => useInternetConnection()); + + expect(result.current).toBe(true); + }); + + it('should call the listener when the connection changes', async () => { + NetInfo.addEventListener = jest.fn(); + + const { result } = renderHook(() => useInternetConnection()); + + // Initial render, assuming it's connected + expect(result.current).toBe(true); + + // Simulate a change in connection status + act(() => { + // @ts-ignore mock calls + NetInfo.addEventListener.mock.calls[0][0]({ + type: 'cellular', // Replace with your desired type + isConnected: false, + isInternetReachable: true, + details: { + isConnectionExpensive: true, + // Add other details as needed for your hook + }, + }); + }); + + // 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 + }); + + // Check if the hook state has been updated + expect(result.current).toBe(false); + }); +}); diff --git a/yarn.lock b/yarn.lock index 885566702..73e3d8de1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -172,16 +172,6 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.10.4": - version: 7.22.13 - resolution: "@babel/code-frame@npm:7.22.13" - dependencies: - "@babel/highlight": ^7.22.13 - chalk: ^2.4.2 - checksum: 22e342c8077c8b77eeb11f554ecca2ba14153f707b85294fcf6070b6f6150aae88a7b7436dd88d8c9289970585f3fe5b9b941c5aa3aa26a6d5a8ef3f292da058 - languageName: node - linkType: hard - "@babel/compat-data@npm:^7.17.7, @babel/compat-data@npm:^7.20.5": version: 7.21.0 resolution: "@babel/compat-data@npm:7.21.0" @@ -458,13 +448,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.22.20": - version: 7.22.20 - resolution: "@babel/helper-validator-identifier@npm:7.22.20" - checksum: 136412784d9428266bcdd4d91c32bcf9ff0e8d25534a9d94b044f77fe76bc50f941a90319b05aafd1ec04f7d127cd57a179a3716009ff7f3412ef835ada95bdc - languageName: node - linkType: hard - "@babel/helper-validator-option@npm:^7.18.6": version: 7.21.0 resolution: "@babel/helper-validator-option@npm:7.21.0" @@ -506,17 +489,6 @@ __metadata: languageName: node linkType: hard -"@babel/highlight@npm:^7.22.13": - version: 7.22.20 - resolution: "@babel/highlight@npm:7.22.20" - dependencies: - "@babel/helper-validator-identifier": ^7.22.20 - chalk: ^2.4.2 - js-tokens: ^4.0.0 - checksum: 84bd034dca309a5e680083cd827a766780ca63cef37308404f17653d32366ea76262bd2364b2d38776232f2d01b649f26721417d507e8b4b6da3e4e739f6d134 - languageName: node - linkType: hard - "@babel/parser@npm:^7.0.0, @babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.21.0, @babel/parser@npm:^7.21.2, @babel/parser@npm:^7.4.3": version: 7.21.2 resolution: "@babel/parser@npm:7.21.2" @@ -1203,7 +1175,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.17.2, @babel/runtime@npm:^7.22.6": +"@babel/runtime@npm:^7.17.2, @babel/runtime@npm:^7.22.6": version: 7.23.2 resolution: "@babel/runtime@npm:7.23.2" dependencies: @@ -3158,7 +3130,7 @@ __metadata: "@magic-sdk/types": ^17.2.0 "@react-native-async-storage/async-storage": ^1.15.5 "@react-native-community/netinfo": ">11.0.0" - "@testing-library/react": 14 + "@testing-library/react-native": ^12.4.0 "@types/lodash": ^4.14.158 buffer: ~5.6.0 localforage: ^1.7.4 @@ -4005,22 +3977,6 @@ __metadata: languageName: node linkType: hard -"@testing-library/dom@npm:^9.0.0": - version: 9.3.3 - resolution: "@testing-library/dom@npm:9.3.3" - dependencies: - "@babel/code-frame": ^7.10.4 - "@babel/runtime": ^7.12.5 - "@types/aria-query": ^5.0.1 - aria-query: 5.1.3 - chalk: ^4.1.0 - dom-accessibility-api: ^0.5.9 - lz-string: ^1.5.0 - pretty-format: ^27.0.2 - checksum: 34e0a564da7beb92aa9cc44a9080221e2412b1a132eb37be3d513fe6c58027674868deb9f86195756d98d15ba969a30fe00632a4e26e25df2a5a4f6ac0686e37 - languageName: node - linkType: hard - "@testing-library/react-native@npm:^12.4.0": version: 12.4.0 resolution: "@testing-library/react-native@npm:12.4.0" @@ -4040,20 +3996,6 @@ __metadata: languageName: node linkType: hard -"@testing-library/react@npm:14": - version: 14.1.0 - resolution: "@testing-library/react@npm:14.1.0" - dependencies: - "@babel/runtime": ^7.12.5 - "@testing-library/dom": ^9.0.0 - "@types/react-dom": ^18.0.0 - peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 - checksum: e76681911947f0981a1a72802ea01abeacdc4973c62deaf19c206cb9ff8d23eff5e3888c572303614686f029ee8a2a2dad6d0f0a9fb222944dbd9e0ea573b248 - languageName: node - linkType: hard - "@tootallnate/once@npm:1": version: 1.1.2 resolution: "@tootallnate/once@npm:1.1.2" @@ -4096,13 +4038,6 @@ __metadata: languageName: node linkType: hard -"@types/aria-query@npm:^5.0.1": - version: 5.0.4 - resolution: "@types/aria-query@npm:5.0.4" - checksum: ad8b87e4ad64255db5f0a73bc2b4da9b146c38a3a8ab4d9306154334e0fc67ae64e76bfa298eebd1e71830591fb15987e5de7111bdb36a2221bdc379e3415fb0 - languageName: node - linkType: hard - "@types/babel__core@npm:^7.0.0, @types/babel__core@npm:^7.1.14": version: 7.20.0 resolution: "@types/babel__core@npm:7.20.0" @@ -4405,15 +4340,6 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:^18.0.0": - version: 18.2.15 - resolution: "@types/react-dom@npm:18.2.15" - dependencies: - "@types/react": "*" - checksum: 8e9631600c21ff561328e38a951d1991b3b3b20f538af4c0efbd1327c883a5573a63f50e1b945c34fa51b114b30e1ca5e62317bd54f21e063d6697b4be843a03 - languageName: node - linkType: hard - "@types/react-native@npm:^0.70.5": version: 0.70.11 resolution: "@types/react-native@npm:0.70.11" @@ -5161,15 +5087,6 @@ __metadata: languageName: node linkType: hard -"aria-query@npm:5.1.3": - version: 5.1.3 - resolution: "aria-query@npm:5.1.3" - dependencies: - deep-equal: ^2.0.5 - checksum: 929ff95f02857b650fb4cbcd2f41072eee2f46159a6605ea03bf63aa572e35ffdff43d69e815ddc462e16e07de8faba3978afc2813650b4448ee18c9895d982b - languageName: node - linkType: hard - "aria-query@npm:^4.2.2": version: 4.2.2 resolution: "aria-query@npm:4.2.2" @@ -5232,16 +5149,6 @@ __metadata: languageName: node linkType: hard -"array-buffer-byte-length@npm:^1.0.0": - version: 1.0.0 - resolution: "array-buffer-byte-length@npm:1.0.0" - dependencies: - call-bind: ^1.0.2 - is-array-buffer: ^3.0.1 - checksum: 044e101ce150f4804ad19c51d6c4d4cfa505c5b2577bd179256e4aa3f3f6a0a5e9874c78cd428ee566ac574c8a04d7ce21af9fe52e844abfdccb82b33035a7c3 - languageName: node - linkType: hard - "array-differ@npm:^2.0.3": version: 2.1.0 resolution: "array-differ@npm:2.1.0" @@ -6212,17 +6119,6 @@ __metadata: languageName: node linkType: hard -"call-bind@npm:^1.0.4, call-bind@npm:^1.0.5": - version: 1.0.5 - resolution: "call-bind@npm:1.0.5" - dependencies: - function-bind: ^1.1.2 - get-intrinsic: ^1.2.1 - set-function-length: ^1.1.1 - checksum: 449e83ecbd4ba48e7eaac5af26fea3b50f8f6072202c2dd7c5a6e7a6308f2421abe5e13a3bbd55221087f76320c5e09f25a8fdad1bab2b77c68ae74d92234ea5 - languageName: node - linkType: hard - "call-me-maybe@npm:^1.0.1": version: 1.0.2 resolution: "call-me-maybe@npm:1.0.2" @@ -7437,32 +7333,6 @@ __metadata: languageName: node linkType: hard -"deep-equal@npm:^2.0.5": - version: 2.2.3 - resolution: "deep-equal@npm:2.2.3" - dependencies: - array-buffer-byte-length: ^1.0.0 - call-bind: ^1.0.5 - es-get-iterator: ^1.1.3 - get-intrinsic: ^1.2.2 - is-arguments: ^1.1.1 - is-array-buffer: ^3.0.2 - is-date-object: ^1.0.5 - is-regex: ^1.1.4 - is-shared-array-buffer: ^1.0.2 - isarray: ^2.0.5 - object-is: ^1.1.5 - object-keys: ^1.1.1 - object.assign: ^4.1.4 - regexp.prototype.flags: ^1.5.1 - side-channel: ^1.0.4 - which-boxed-primitive: ^1.0.2 - which-collection: ^1.0.1 - which-typed-array: ^1.1.13 - checksum: ee8852f23e4d20a5626c13b02f415ba443a1b30b4b3d39eaf366d59c4a85e6545d7ec917db44d476a85ae5a86064f7e5f7af7479f38f113995ba869f3a1ddc53 - languageName: node - linkType: hard - "deep-extend@npm:^0.6.0, deep-extend@npm:~0.6.0": version: 0.6.0 resolution: "deep-extend@npm:0.6.0" @@ -7509,17 +7379,6 @@ __metadata: languageName: node linkType: hard -"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.1": - version: 1.1.1 - resolution: "define-data-property@npm:1.1.1" - dependencies: - get-intrinsic: ^1.2.1 - gopd: ^1.0.1 - has-property-descriptors: ^1.0.0 - checksum: a29855ad3f0630ea82e3c5012c812efa6ca3078d5c2aa8df06b5f597c1cde6f7254692df41945851d903e05a1668607b6d34e778f402b9ff9ffb38111f1a3f0d - languageName: node - linkType: hard - "define-properties@npm:^1.1.3, define-properties@npm:^1.1.4": version: 1.2.0 resolution: "define-properties@npm:1.2.0" @@ -7530,17 +7389,6 @@ __metadata: languageName: node linkType: hard -"define-properties@npm:^1.2.0": - version: 1.2.1 - resolution: "define-properties@npm:1.2.1" - dependencies: - define-data-property: ^1.0.1 - has-property-descriptors: ^1.0.0 - object-keys: ^1.1.1 - checksum: b4ccd00597dd46cb2d4a379398f5b19fca84a16f3374e2249201992f36b30f6835949a9429669ee6b41b6e837205a163eadd745e472069e70dfc10f03e5fcc12 - languageName: node - linkType: hard - "define-property@npm:^0.2.5": version: 0.2.5 resolution: "define-property@npm:0.2.5" @@ -7697,13 +7545,6 @@ __metadata: languageName: node linkType: hard -"dom-accessibility-api@npm:^0.5.9": - version: 0.5.16 - resolution: "dom-accessibility-api@npm:0.5.16" - checksum: 005eb283caef57fc1adec4d5df4dd49189b628f2f575af45decb210e04d634459e3f1ee64f18b41e2dcf200c844bc1d9279d80807e686a30d69a4756151ad248 - languageName: node - linkType: hard - "dom-walk@npm:^0.1.0": version: 0.1.2 resolution: "dom-walk@npm:0.1.2" @@ -8016,23 +7857,6 @@ __metadata: languageName: node linkType: hard -"es-get-iterator@npm:^1.1.3": - version: 1.1.3 - resolution: "es-get-iterator@npm:1.1.3" - dependencies: - call-bind: ^1.0.2 - get-intrinsic: ^1.1.3 - has-symbols: ^1.0.3 - is-arguments: ^1.1.1 - is-map: ^2.0.2 - is-set: ^2.0.2 - is-string: ^1.0.7 - isarray: ^2.0.5 - stop-iteration-iterator: ^1.0.0 - checksum: 8fa118da42667a01a7c7529f8a8cca514feeff243feec1ce0bb73baaa3514560bd09d2b3438873cf8a5aaec5d52da248131de153b28e2638a061b6e4df13267d - languageName: node - linkType: hard - "es-set-tostringtag@npm:^2.0.1": version: 2.0.1 resolution: "es-set-tostringtag@npm:2.0.1" @@ -9784,13 +9608,6 @@ fsevents@^2.3.2: languageName: node linkType: hard -"function-bind@npm:^1.1.2": - version: 1.1.2 - resolution: "function-bind@npm:1.1.2" - checksum: 2b0ff4ce708d99715ad14a6d1f894e2a83242e4a52ccfcefaee5e40050562e5f6dafc1adbb4ce2d4ab47279a45dc736ab91ea5042d843c3c092820dfe032efb1 - languageName: node - linkType: hard - "function.prototype.name@npm:^1.1.5": version: 1.1.5 resolution: "function.prototype.name@npm:1.1.5" @@ -9810,7 +9627,7 @@ fsevents@^2.3.2: languageName: node linkType: hard -"functions-have-names@npm:^1.2.2, functions-have-names@npm:^1.2.3": +"functions-have-names@npm:^1.2.2": version: 1.2.3 resolution: "functions-have-names@npm:1.2.3" checksum: c3f1f5ba20f4e962efb71344ce0a40722163e85bee2101ce25f88214e78182d2d2476aa85ef37950c579eb6cf6ee811c17b3101bb84004bb75655f3e33f3fdb5 @@ -9888,18 +9705,6 @@ fsevents@^2.3.2: languageName: node linkType: hard -"get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.2": - version: 1.2.2 - resolution: "get-intrinsic@npm:1.2.2" - dependencies: - function-bind: ^1.1.2 - has-proto: ^1.0.1 - has-symbols: ^1.0.3 - hasown: ^2.0.0 - checksum: 447ff0724df26829908dc033b62732359596fcf66027bc131ab37984afb33842d9cd458fd6cecadfe7eac22fd8a54b349799ed334cf2726025c921c7250e7417 - languageName: node - linkType: hard - "get-monorepo-packages@npm:^1.1.0": version: 1.2.0 resolution: "get-monorepo-packages@npm:1.2.0" @@ -10455,15 +10260,6 @@ fsevents@^2.3.2: languageName: node linkType: hard -"hasown@npm:^2.0.0": - version: 2.0.0 - resolution: "hasown@npm:2.0.0" - dependencies: - function-bind: ^1.1.2 - checksum: 6151c75ca12554565098641c98a40f4cc86b85b0fd5b6fe92360967e4605a4f9610f7757260b4e8098dd1c2ce7f4b095f2006fe72a570e3b6d2d28de0298c176 - languageName: node - linkType: hard - "hermes-engine@npm:~0.4.0": version: 0.4.3 resolution: "hermes-engine@npm:0.4.3" @@ -11026,7 +10822,7 @@ fsevents@^2.3.2: languageName: node linkType: hard -"is-arguments@npm:^1.0.4, is-arguments@npm:^1.1.1": +"is-arguments@npm:^1.0.4": version: 1.1.1 resolution: "is-arguments@npm:1.1.1" dependencies: @@ -11047,17 +10843,6 @@ fsevents@^2.3.2: languageName: node linkType: hard -"is-array-buffer@npm:^3.0.2": - version: 3.0.2 - resolution: "is-array-buffer@npm:3.0.2" - dependencies: - call-bind: ^1.0.2 - get-intrinsic: ^1.2.0 - is-typed-array: ^1.1.10 - checksum: dcac9dda66ff17df9cabdc58214172bf41082f956eab30bb0d86bc0fab1e44b690fc8e1f855cf2481245caf4e8a5a006a982a71ddccec84032ed41f9d8da8c14 - languageName: node - linkType: hard - "is-arrayish@npm:^0.2.1": version: 0.2.1 resolution: "is-arrayish@npm:0.2.1" @@ -11147,7 +10932,7 @@ fsevents@^2.3.2: languageName: node linkType: hard -"is-date-object@npm:^1.0.1, is-date-object@npm:^1.0.5": +"is-date-object@npm:^1.0.1": version: 1.0.5 resolution: "is-date-object@npm:1.0.5" dependencies: @@ -11300,13 +11085,6 @@ fsevents@^2.3.2: languageName: node linkType: hard -"is-map@npm:^2.0.1, is-map@npm:^2.0.2": - version: 2.0.2 - resolution: "is-map@npm:2.0.2" - checksum: ace3d0ecd667bbdefdb1852de601268f67f2db725624b1958f279316e13fecb8fa7df91fd60f690d7417b4ec180712f5a7ee967008e27c65cfd475cc84337728 - languageName: node - linkType: hard - "is-negative-zero@npm:^2.0.2": version: 2.0.2 resolution: "is-negative-zero@npm:2.0.2" @@ -11414,13 +11192,6 @@ fsevents@^2.3.2: languageName: node linkType: hard -"is-set@npm:^2.0.1, is-set@npm:^2.0.2": - version: 2.0.2 - resolution: "is-set@npm:2.0.2" - checksum: b64343faf45e9387b97a6fd32be632ee7b269bd8183701f3b3f5b71a7cf00d04450ed8669d0bd08753e08b968beda96fca73a10fd0ff56a32603f64deba55a57 - languageName: node - linkType: hard - "is-shared-array-buffer@npm:^1.0.2": version: 1.0.2 resolution: "is-shared-array-buffer@npm:1.0.2" @@ -11514,13 +11285,6 @@ fsevents@^2.3.2: languageName: node linkType: hard -"is-weakmap@npm:^2.0.1": - version: 2.0.1 - resolution: "is-weakmap@npm:2.0.1" - checksum: 1222bb7e90c32bdb949226e66d26cb7bce12e1e28e3e1b40bfa6b390ba3e08192a8664a703dff2a00a84825f4e022f9cd58c4599ff9981ab72b1d69479f4f7f6 - languageName: node - linkType: hard - "is-weakref@npm:^1.0.2": version: 1.0.2 resolution: "is-weakref@npm:1.0.2" @@ -11530,16 +11294,6 @@ fsevents@^2.3.2: languageName: node linkType: hard -"is-weakset@npm:^2.0.1": - version: 2.0.2 - resolution: "is-weakset@npm:2.0.2" - dependencies: - call-bind: ^1.0.2 - get-intrinsic: ^1.1.1 - checksum: 5d8698d1fa599a0635d7ca85be9c26d547b317ed8fd83fc75f03efbe75d50001b5eececb1e9971de85fcde84f69ae6f8346bc92d20d55d46201d328e4c74a367 - languageName: node - linkType: hard - "is-windows@npm:^1.0.0, is-windows@npm:^1.0.2": version: 1.0.2 resolution: "is-windows@npm:1.0.2" @@ -11561,13 +11315,6 @@ fsevents@^2.3.2: languageName: node linkType: hard -"isarray@npm:^2.0.5": - version: 2.0.5 - resolution: "isarray@npm:2.0.5" - checksum: bd5bbe4104438c4196ba58a54650116007fa0262eccef13a4c55b2e09a5b36b59f1e75b9fcc49883dd9d4953892e6fc007eef9e9155648ceea036e184b0f930a - languageName: node - linkType: hard - "isexe@npm:^2.0.0": version: 2.0.0 resolution: "isexe@npm:2.0.0" @@ -13258,15 +13005,6 @@ fsevents@^2.3.2: languageName: node linkType: hard -"lz-string@npm:^1.5.0": - version: 1.5.0 - resolution: "lz-string@npm:1.5.0" - bin: - lz-string: bin/bin.js - checksum: 1ee98b4580246fd90dd54da6e346fb1caefcf05f677c686d9af237a157fdea3fd7c83a4bc58f858cd5b10a34d27afe0fdcbd0505a47e0590726a873dc8b8f65d - languageName: node - linkType: hard - "macos-release@npm:^2.2.0": version: 2.5.1 resolution: "macos-release@npm:2.5.1" @@ -15051,16 +14789,6 @@ fsevents@^2.3.2: languageName: node linkType: hard -"object-is@npm:^1.1.5": - version: 1.1.5 - resolution: "object-is@npm:1.1.5" - dependencies: - call-bind: ^1.0.2 - define-properties: ^1.1.3 - checksum: 989b18c4cba258a6b74dc1d74a41805c1a1425bce29f6cabb50dcb1a6a651ea9104a1b07046739a49a5bb1bc49727bcb00efd5c55f932f6ea04ec8927a7901fe - languageName: node - linkType: hard - "object-keys@npm:^1.1.1": version: 1.1.1 resolution: "object-keys@npm:1.1.1" @@ -15995,7 +15723,7 @@ fsevents@^2.3.2: languageName: node linkType: hard -"pretty-format@npm:^27.0.0, pretty-format@npm:^27.0.2, pretty-format@npm:^27.5.1": +"pretty-format@npm:^27.0.0, pretty-format@npm:^27.5.1": version: 27.5.1 resolution: "pretty-format@npm:27.5.1" dependencies: @@ -16777,17 +16505,6 @@ fsevents@^2.3.2: languageName: node linkType: hard -"regexp.prototype.flags@npm:^1.5.1": - version: 1.5.1 - resolution: "regexp.prototype.flags@npm:1.5.1" - dependencies: - call-bind: ^1.0.2 - define-properties: ^1.2.0 - set-function-name: ^2.0.0 - checksum: 869edff00288442f8d7fa4c9327f91d85f3b3acf8cbbef9ea7a220345cf23e9241b6def9263d2c1ebcf3a316b0aa52ad26a43a84aa02baca3381717b3e307f47 - languageName: node - linkType: hard - "regexpp@npm:^3.0.0, regexpp@npm:^3.1.0": version: 3.2.0 resolution: "regexpp@npm:3.2.0" @@ -17493,29 +17210,6 @@ resolve@~1.7.1: languageName: node linkType: hard -"set-function-length@npm:^1.1.1": - version: 1.1.1 - resolution: "set-function-length@npm:1.1.1" - dependencies: - define-data-property: ^1.1.1 - get-intrinsic: ^1.2.1 - gopd: ^1.0.1 - has-property-descriptors: ^1.0.0 - checksum: c131d7569cd7e110cafdfbfbb0557249b538477624dfac4fc18c376d879672fa52563b74029ca01f8f4583a8acb35bb1e873d573a24edb80d978a7ee607c6e06 - languageName: node - linkType: hard - -"set-function-name@npm:^2.0.0": - version: 2.0.1 - resolution: "set-function-name@npm:2.0.1" - dependencies: - define-data-property: ^1.0.1 - functions-have-names: ^1.2.3 - has-property-descriptors: ^1.0.0 - checksum: 4975d17d90c40168eee2c7c9c59d023429f0a1690a89d75656306481ece0c3c1fb1ebcc0150ea546d1913e35fbd037bace91372c69e543e51fc5d1f31a9fa126 - languageName: node - linkType: hard - "set-value@npm:^2.0.0, set-value@npm:^2.0.1": version: 2.0.1 resolution: "set-value@npm:2.0.1" @@ -18104,15 +17798,6 @@ resolve@~1.7.1: languageName: node linkType: hard -"stop-iteration-iterator@npm:^1.0.0": - version: 1.0.0 - resolution: "stop-iteration-iterator@npm:1.0.0" - dependencies: - internal-slot: ^1.0.4 - checksum: d04173690b2efa40e24ab70e5e51a3ff31d56d699550cfad084104ab3381390daccb36652b25755e420245f3b0737de66c1879eaa2a8d4fc0a78f9bf892fcb42 - languageName: node - linkType: hard - "stream-buffers@npm:2.2.x": version: 2.2.0 resolution: "stream-buffers@npm:2.2.0" @@ -20023,18 +19708,6 @@ typescript@~4.4.2: languageName: node linkType: hard -"which-collection@npm:^1.0.1": - version: 1.0.1 - resolution: "which-collection@npm:1.0.1" - dependencies: - is-map: ^2.0.1 - is-set: ^2.0.1 - is-weakmap: ^2.0.1 - is-weakset: ^2.0.1 - checksum: c815bbd163107ef9cb84f135e6f34453eaf4cca994e7ba85ddb0d27cea724c623fae2a473ceccfd5549c53cc65a5d82692de418166df3f858e1e5dc60818581c - languageName: node - linkType: hard - "which-module@npm:^2.0.0": version: 2.0.0 resolution: "which-module@npm:2.0.0" @@ -20042,19 +19715,6 @@ typescript@~4.4.2: languageName: node linkType: hard -"which-typed-array@npm:^1.1.13": - version: 1.1.13 - resolution: "which-typed-array@npm:1.1.13" - dependencies: - available-typed-arrays: ^1.0.5 - call-bind: ^1.0.4 - for-each: ^0.3.3 - gopd: ^1.0.1 - has-tostringtag: ^1.0.0 - checksum: 3828a0d5d72c800e369d447e54c7620742a4cc0c9baf1b5e8c17e9b6ff90d8d861a3a6dd4800f1953dbf80e5e5cec954a289e5b4a223e3bee4aeb1f8c5f33309 - languageName: node - linkType: hard - "which-typed-array@npm:^1.1.2, which-typed-array@npm:^1.1.9": version: 1.1.9 resolution: "which-typed-array@npm:1.1.9" From 6e5d0e60e65ee94140320fe80b9c30597cad236d Mon Sep 17 00:00:00 2001 From: romin-halltari Date: Wed, 15 Nov 2023 13:01:22 -0800 Subject: [PATCH 06/11] Remove unnecessary comments --- packages/@magic-sdk/react-native-bare/test/spec/hooks.spec.ts | 3 +-- packages/@magic-sdk/react-native-expo/test/spec/hooks.spec.ts | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/@magic-sdk/react-native-bare/test/spec/hooks.spec.ts b/packages/@magic-sdk/react-native-bare/test/spec/hooks.spec.ts index eded37cf0..e665eb525 100644 --- a/packages/@magic-sdk/react-native-bare/test/spec/hooks.spec.ts +++ b/packages/@magic-sdk/react-native-bare/test/spec/hooks.spec.ts @@ -34,12 +34,11 @@ describe('useInternetConnection', () => { act(() => { // @ts-ignore mock calls NetInfo.addEventListener.mock.calls[0][0]({ - type: 'cellular', // Replace with your desired type + type: 'cellular', isConnected: false, isInternetReachable: true, details: { isConnectionExpensive: true, - // Add other details as needed for your hook }, }); }); diff --git a/packages/@magic-sdk/react-native-expo/test/spec/hooks.spec.ts b/packages/@magic-sdk/react-native-expo/test/spec/hooks.spec.ts index eded37cf0..e665eb525 100644 --- a/packages/@magic-sdk/react-native-expo/test/spec/hooks.spec.ts +++ b/packages/@magic-sdk/react-native-expo/test/spec/hooks.spec.ts @@ -34,12 +34,11 @@ describe('useInternetConnection', () => { act(() => { // @ts-ignore mock calls NetInfo.addEventListener.mock.calls[0][0]({ - type: 'cellular', // Replace with your desired type + type: 'cellular', isConnected: false, isInternetReachable: true, details: { isConnectionExpensive: true, - // Add other details as needed for your hook }, }); }); From 1ccf3edaa61c9413ae5fad0ed1c56f9fb7376f88 Mon Sep 17 00:00:00 2001 From: romin-halltari Date: Thu, 16 Nov 2023 16:22:28 -0800 Subject: [PATCH 07/11] Do now wait for ready promise on a react native environment, as it never resolves when there's no internet connection --- .../provider/src/core/view-controller.ts | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/packages/@magic-sdk/provider/src/core/view-controller.ts b/packages/@magic-sdk/provider/src/core/view-controller.ts index 442926c22..dbeac1538 100644 --- a/packages/@magic-sdk/provider/src/core/view-controller.ts +++ b/packages/@magic-sdk/provider/src/core/view-controller.ts @@ -4,6 +4,8 @@ import { JsonRpcRequestPayload, MagicMessageEvent, MagicMessageRequest, + RPCErrorCode, + JsonRpcError, } from '@magic-sdk/types'; import { JsonRpcResponse } from './json-rpc'; import { createPromise } from '../util/promise-tools'; @@ -88,6 +90,7 @@ async function persistMagicEventRefreshToken(event: MagicMessageEvent) { } export abstract class ViewController { + private isReady = false; public ready: Promise; protected readonly messageHandlers = new Set<(event: MagicMessageEvent) => any>(); @@ -129,8 +132,20 @@ export abstract class ViewController { msgType: MagicOutgoingWindowMessage, payload: JsonRpcRequestPayload | JsonRpcRequestPayload[], ): Promise | JsonRpcResponse[]> { - return createPromise(async (resolve) => { - await this.ready; + return createPromise(async (resolve, reject) => { + if (SDKEnvironment.platform !== 'react-native') { + await this.ready; + } else if (!this.isReady) { + // On a mobile environment, `this.ready` never resolves if the app was + // initially opened without internet connection. That is why we reject + // the promise without waiting and just let them call it again when + // internet connection is re-established. + const error: JsonRpcError = { + code: RPCErrorCode.InternalError, + message: 'Connection to Magic SDK not ready. Please check your internet connection.', + }; + reject(error); + } const batchData: JsonRpcResponse[] = []; const batchIds = Array.isArray(payload) ? payload.map((p) => p.id) : []; @@ -194,7 +209,10 @@ export abstract class ViewController { private waitForReady() { return new Promise((resolve) => { - this.on(MagicIncomingWindowMessage.MAGIC_OVERLAY_READY, () => resolve()); + this.on(MagicIncomingWindowMessage.MAGIC_OVERLAY_READY, () => { + resolve(); + this.isReady = true; + }); }); } From 2c4687413cb77a389eaaf9fa5d05c72b244cb43b Mon Sep 17 00:00:00 2001 From: romin-halltari Date: Thu, 16 Nov 2023 16:48:40 -0800 Subject: [PATCH 08/11] add tests --- .../spec/core/view-controller/post.spec.ts | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/packages/@magic-sdk/provider/test/spec/core/view-controller/post.spec.ts b/packages/@magic-sdk/provider/test/spec/core/view-controller/post.spec.ts index 47813eb61..30f330521 100644 --- a/packages/@magic-sdk/provider/test/spec/core/view-controller/post.spec.ts +++ b/packages/@magic-sdk/provider/test/spec/core/view-controller/post.spec.ts @@ -2,7 +2,12 @@ /* eslint-disable prefer-spread */ import browserEnv from '@ikscodes/browser-env'; -import { MagicIncomingWindowMessage, MagicOutgoingWindowMessage, JsonRpcRequestPayload } from '@magic-sdk/types'; +import { + MagicIncomingWindowMessage, + MagicOutgoingWindowMessage, + JsonRpcRequestPayload, + RPCErrorCode, +} from '@magic-sdk/types'; import _ from 'lodash'; import { createViewController } from '../../../factories'; import { JsonRpcResponse } from '../../../../src/core/json-rpc'; @@ -201,6 +206,30 @@ test('Sends payload and stores rt if response event contains rt', async () => { expect(FAKE_STORE.rt).toEqual(FAKE_RT); }); +test('does not wait for ready and throws error when platform is react-native', async () => { + SDKEnvironment.platform = 'react-native'; + const eventWithRt = { data: { ...responseEvent().data } }; + const viewController = createViewController('asdf'); + const { handlerSpy, onSpy } = stubViewController(viewController, [ + [MagicIncomingWindowMessage.MAGIC_HANDLE_RESPONSE, eventWithRt], + ]); + viewController.ready = new Promise(() => null); + + const payload = requestPayload(); + + try { + await viewController.post(MagicOutgoingWindowMessage.MAGIC_HANDLE_REQUEST, payload); + } catch (e) { + expect(e).toEqual({ + code: RPCErrorCode.InternalError, + message: 'Connection to Magic SDK not ready. Please check your internet connection.', + }); + } + expect(createJwtStub).not.toHaveBeenCalledWith(); + expect(onSpy.mock.calls[0][0]).toEqual(MagicIncomingWindowMessage.MAGIC_HANDLE_RESPONSE); + expect(handlerSpy).not.toHaveBeenCalled(); +}); + test('does not call web crypto api if platform is not web', async () => { SDKEnvironment.platform = 'react-native'; const eventWithRt = { data: { ...responseEvent().data } }; @@ -210,6 +239,9 @@ test('does not call web crypto api if platform is not web', async () => { ]); const payload = requestPayload(); + // @ts-ignore isReady is private + viewController.isReady = true; + const response = await viewController.post(MagicOutgoingWindowMessage.MAGIC_HANDLE_REQUEST, payload); expect(createJwtStub).not.toHaveBeenCalledWith(); From 170b74bce67d9ab7ea7b3242747c67713efd8dd6 Mon Sep 17 00:00:00 2001 From: romin-halltari Date: Fri, 17 Nov 2023 12:23:21 -0800 Subject: [PATCH 09/11] Update readme --- packages/@magic-sdk/react-native-bare/README.md | 11 ++++++++++- packages/@magic-sdk/react-native-expo/README.md | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/packages/@magic-sdk/react-native-bare/README.md b/packages/@magic-sdk/react-native-bare/README.md index b9dda3552..b69716222 100644 --- a/packages/@magic-sdk/react-native-bare/README.md +++ b/packages/@magic-sdk/react-native-bare/README.md @@ -86,8 +86,17 @@ When attempting to import `Magic`, take note that the React Native metro bundler For this issue consider using Microsoft's [rnx-kit](https://microsoft.github.io/rnx-kit/docs/guides/bundling) suite of tools that include a plugin for metro that fixes this symlink related error. ### Handling internet connection problems +When an app is opened without internet connection, any request to the Magic SDK will result in a rejection with the following error: + +```json +{ + "code": -32603, + "message": "Connection to Magic SDK not ready. Please check your internet connection." +} +``` + +It is good practice to use [@react-native-community/netinfo](https://www.npmjs.com/package/@react-native-community/netinfo) to track the internet connection state of the device. For your convenience, we've also added a hook that uses this library behind the scenes: -When the app has internet connectivity issues, the relayer might behave in ways you don't expect. That is why it is important to use [@react-native-community/netinfo](https://www.npmjs.com/package/@react-native-community/netinfo) to track the internet connection state of the device, and refresh your UI when the connection is re-established. For your convenience, we've also added a hook that uses this library behind the scenes: ```tsx import { useInternetConnection } from '@magic-sdk/react-native-expo'; diff --git a/packages/@magic-sdk/react-native-expo/README.md b/packages/@magic-sdk/react-native-expo/README.md index a0034891b..d681e8e0a 100644 --- a/packages/@magic-sdk/react-native-expo/README.md +++ b/packages/@magic-sdk/react-native-expo/README.md @@ -77,8 +77,17 @@ When attempting to import `Magic`, take note that the React Native metro bundler For this issue consider using Microsoft's [rnx-kit](https://microsoft.github.io/rnx-kit/docs/guides/bundling) suite of tools that include a plugin for metro that fixes this symlink related error. ### Handling internet connection problems +When an app is opened without internet connection, any request to the Magic SDK will result in a rejection with the following error: + +```json +{ + "code": -32603, + "message": "Connection to Magic SDK not ready. Please check your internet connection." +} +``` + +It is good practice to use [@react-native-community/netinfo](https://www.npmjs.com/package/@react-native-community/netinfo) to track the internet connection state of the device. For your convenience, we've also added a hook that uses this library behind the scenes: -When the app has internet connectivity issues, the relayer might behave in ways you don't expect. That is why it is important to use [@react-native-community/netinfo](https://www.npmjs.com/package/@react-native-community/netinfo) to track the internet connection state of the device, and refresh your UI when the connection is re-established. For your convenience, we've also added a hook that uses this library behind the scenes: ```tsx import { useInternetConnection } from '@magic-sdk/react-native-expo'; From 09ec3931ec9d207abeeb6e1ab3725817a1a45fd8 Mon Sep 17 00:00:00 2001 From: romin-halltari Date: Fri, 17 Nov 2023 13:14:53 -0800 Subject: [PATCH 10/11] Rename: ready -> checkIsReadyForRequest and isReady -> isReadyForRequest --- packages/@magic-sdk/provider/src/core/sdk.ts | 2 +- .../provider/src/core/view-controller.ts | 20 +++++++++---------- .../spec/core/view-controller/post.spec.ts | 8 ++++---- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/@magic-sdk/provider/src/core/sdk.ts b/packages/@magic-sdk/provider/src/core/sdk.ts index 3c5201d09..971cc97cb 100644 --- a/packages/@magic-sdk/provider/src/core/sdk.ts +++ b/packages/@magic-sdk/provider/src/core/sdk.ts @@ -196,6 +196,6 @@ export class SDKBase { * has completed loading and is ready for requests. */ public async preload() { - await this.overlay.ready; + await this.overlay.checkIsReadyForRequest; } } diff --git a/packages/@magic-sdk/provider/src/core/view-controller.ts b/packages/@magic-sdk/provider/src/core/view-controller.ts index dbeac1538..e0da4c2a3 100644 --- a/packages/@magic-sdk/provider/src/core/view-controller.ts +++ b/packages/@magic-sdk/provider/src/core/view-controller.ts @@ -90,8 +90,8 @@ async function persistMagicEventRefreshToken(event: MagicMessageEvent) { } export abstract class ViewController { - private isReady = false; - public ready: Promise; + private isReadyForRequest = false; + public checkIsReadyForRequest: Promise; protected readonly messageHandlers = new Set<(event: MagicMessageEvent) => any>(); /** @@ -102,7 +102,7 @@ export abstract class ViewController { * relevant iframe context. */ constructor(protected readonly endpoint: string, protected readonly parameters: string) { - this.ready = this.waitForReady(); + this.checkIsReadyForRequest = this.waitForReady(); this.listen(); } @@ -134,12 +134,12 @@ export abstract class ViewController { ): Promise | JsonRpcResponse[]> { return createPromise(async (resolve, reject) => { if (SDKEnvironment.platform !== 'react-native') { - await this.ready; - } else if (!this.isReady) { - // On a mobile environment, `this.ready` never resolves if the app was - // initially opened without internet connection. That is why we reject - // the promise without waiting and just let them call it again when - // internet connection is re-established. + await this.checkIsReadyForRequest; + } else if (!this.isReadyForRequest) { + // On a mobile environment, `this.checkIsReadyForRequest` never resolves + // if the app was initially opened without internet connection. That is + // why we reject the promise without waiting and just let them call it + // again when internet connection is re-established. const error: JsonRpcError = { code: RPCErrorCode.InternalError, message: 'Connection to Magic SDK not ready. Please check your internet connection.', @@ -211,7 +211,7 @@ export abstract class ViewController { return new Promise((resolve) => { this.on(MagicIncomingWindowMessage.MAGIC_OVERLAY_READY, () => { resolve(); - this.isReady = true; + this.isReadyForRequest = true; }); }); } diff --git a/packages/@magic-sdk/provider/test/spec/core/view-controller/post.spec.ts b/packages/@magic-sdk/provider/test/spec/core/view-controller/post.spec.ts index 30f330521..3431c4324 100644 --- a/packages/@magic-sdk/provider/test/spec/core/view-controller/post.spec.ts +++ b/packages/@magic-sdk/provider/test/spec/core/view-controller/post.spec.ts @@ -61,7 +61,7 @@ function stubViewController(viewController: any, events: [MagicIncomingWindowMes const postSpy = jest.fn(); viewController.on = onSpy; - viewController.ready = Promise.resolve(); + viewController.checkIsReadyForRequest = Promise.resolve(); viewController._post = postSpy; return { handlerSpy, onSpy, postSpy }; @@ -213,7 +213,7 @@ test('does not wait for ready and throws error when platform is react-native', a const { handlerSpy, onSpy } = stubViewController(viewController, [ [MagicIncomingWindowMessage.MAGIC_HANDLE_RESPONSE, eventWithRt], ]); - viewController.ready = new Promise(() => null); + viewController.checkIsReadyForRequest = new Promise(() => null); const payload = requestPayload(); @@ -239,8 +239,8 @@ test('does not call web crypto api if platform is not web', async () => { ]); const payload = requestPayload(); - // @ts-ignore isReady is private - viewController.isReady = true; + // @ts-ignore isReadyForRequest is private + viewController.isReadyForRequest = true; const response = await viewController.post(MagicOutgoingWindowMessage.MAGIC_HANDLE_REQUEST, payload); From 846912f82b65faf7a0e1bbae93e7eff47ab11326 Mon Sep 17 00:00:00 2001 From: romin-halltari Date: Mon, 20 Nov 2023 10:15:52 -0800 Subject: [PATCH 11/11] Use createModalNotReadyError() when modal is not ready on react native --- .../provider/src/core/view-controller.ts | 8 ++------ .../test/spec/core/view-controller/post.spec.ts | 14 +++----------- packages/@magic-sdk/react-native-bare/README.md | 7 ++++--- packages/@magic-sdk/react-native-expo/README.md | 6 +++--- 4 files changed, 12 insertions(+), 23 deletions(-) diff --git a/packages/@magic-sdk/provider/src/core/view-controller.ts b/packages/@magic-sdk/provider/src/core/view-controller.ts index e0da4c2a3..6e575c577 100644 --- a/packages/@magic-sdk/provider/src/core/view-controller.ts +++ b/packages/@magic-sdk/provider/src/core/view-controller.ts @@ -4,14 +4,13 @@ import { JsonRpcRequestPayload, MagicMessageEvent, MagicMessageRequest, - RPCErrorCode, - JsonRpcError, } from '@magic-sdk/types'; import { JsonRpcResponse } from './json-rpc'; import { createPromise } from '../util/promise-tools'; import { getItem, setItem } from '../util/storage'; import { createJwt } from '../util/web-crypto'; import { SDKEnvironment } from './sdk-environment'; +import { createModalNotReadyError } from './sdk-exceptions'; interface RemoveEventListenerFunction { (): void; @@ -140,10 +139,7 @@ export abstract class ViewController { // if the app was initially opened without internet connection. That is // why we reject the promise without waiting and just let them call it // again when internet connection is re-established. - const error: JsonRpcError = { - code: RPCErrorCode.InternalError, - message: 'Connection to Magic SDK not ready. Please check your internet connection.', - }; + const error = createModalNotReadyError(); reject(error); } diff --git a/packages/@magic-sdk/provider/test/spec/core/view-controller/post.spec.ts b/packages/@magic-sdk/provider/test/spec/core/view-controller/post.spec.ts index 3431c4324..f03975cb6 100644 --- a/packages/@magic-sdk/provider/test/spec/core/view-controller/post.spec.ts +++ b/packages/@magic-sdk/provider/test/spec/core/view-controller/post.spec.ts @@ -2,18 +2,13 @@ /* eslint-disable prefer-spread */ import browserEnv from '@ikscodes/browser-env'; -import { - MagicIncomingWindowMessage, - MagicOutgoingWindowMessage, - JsonRpcRequestPayload, - RPCErrorCode, -} from '@magic-sdk/types'; -import _ from 'lodash'; +import { MagicIncomingWindowMessage, MagicOutgoingWindowMessage, JsonRpcRequestPayload } from '@magic-sdk/types'; import { createViewController } from '../../../factories'; import { JsonRpcResponse } from '../../../../src/core/json-rpc'; import * as storage from '../../../../src/util/storage'; import * as webCryptoUtils from '../../../../src/util/web-crypto'; import { SDKEnvironment } from '../../../../src/core/sdk-environment'; +import { createModalNotReadyError } from '../../../../src/core/sdk-exceptions'; /** * Create a dummy request payload. @@ -220,10 +215,7 @@ test('does not wait for ready and throws error when platform is react-native', a try { await viewController.post(MagicOutgoingWindowMessage.MAGIC_HANDLE_REQUEST, payload); } catch (e) { - expect(e).toEqual({ - code: RPCErrorCode.InternalError, - message: 'Connection to Magic SDK not ready. Please check your internet connection.', - }); + expect(e).toEqual(createModalNotReadyError()); } expect(createJwtStub).not.toHaveBeenCalledWith(); expect(onSpy.mock.calls[0][0]).toEqual(MagicIncomingWindowMessage.MAGIC_HANDLE_RESPONSE); diff --git a/packages/@magic-sdk/react-native-bare/README.md b/packages/@magic-sdk/react-native-bare/README.md index b69716222..98b9f7d1c 100644 --- a/packages/@magic-sdk/react-native-bare/README.md +++ b/packages/@magic-sdk/react-native-bare/README.md @@ -86,15 +86,16 @@ When attempting to import `Magic`, take note that the React Native metro bundler For this issue consider using Microsoft's [rnx-kit](https://microsoft.github.io/rnx-kit/docs/guides/bundling) suite of tools that include a plugin for metro that fixes this symlink related error. ### Handling internet connection problems -When an app is opened without internet connection, any request to the Magic SDK will result in a rejection with the following error: +When an app is opened without internet connection, any request to the Magic SDK will result in a rejection with a `MagicSDKError`: ```json { - "code": -32603, - "message": "Connection to Magic SDK not ready. Please check your internet connection." + "code": "MODAL_NOT_READY", + "rawMessage": "Modal is not ready." } ``` + It is good practice to use [@react-native-community/netinfo](https://www.npmjs.com/package/@react-native-community/netinfo) to track the internet connection state of the device. For your convenience, we've also added a hook that uses this library behind the scenes: diff --git a/packages/@magic-sdk/react-native-expo/README.md b/packages/@magic-sdk/react-native-expo/README.md index d681e8e0a..9f9aa6018 100644 --- a/packages/@magic-sdk/react-native-expo/README.md +++ b/packages/@magic-sdk/react-native-expo/README.md @@ -77,12 +77,12 @@ When attempting to import `Magic`, take note that the React Native metro bundler For this issue consider using Microsoft's [rnx-kit](https://microsoft.github.io/rnx-kit/docs/guides/bundling) suite of tools that include a plugin for metro that fixes this symlink related error. ### Handling internet connection problems -When an app is opened without internet connection, any request to the Magic SDK will result in a rejection with the following error: +When an app is opened without internet connection, any request to the Magic SDK will result in a rejection with a `MagicSDKError`: ```json { - "code": -32603, - "message": "Connection to Magic SDK not ready. Please check your internet connection." + "code": "MODAL_NOT_READY", + "rawMessage": "Modal is not ready." } ```