diff --git a/README.md b/README.md index eb36b2ec..7a8ef325 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Handful of utilities you should keep in your toolbelt to handle offline/online connectivity in React Native. It supports iOS, Android and Windows platforms. You can leverage all the functionalities provided or just the ones that suits your needs, the modules are conveniently decoupled. ## Important (Please read) -**This is the documentation for version 4.0.0. If you are migrating from v3 to v4, check the [release notes](https://github.com/rgommezz/react-native-offline/releases/tag/v4.0.0).** +**This is the documentation for version 4.x.x. If you are migrating from v3 to v4, check the [release notes](https://github.com/rgommezz/react-native-offline/releases/tag/v4.0.0).** ## Contents @@ -23,7 +23,7 @@ Handful of utilities you should keep in your toolbelt to handle offline/online c + [`Network reducer`](#network-reducer) + [`ReduxNetworkProvider`](#reduxnetworkprovider) + [`networkSaga`](#networksaga) - + [`createNetworkMiddleware()`](#createnetworkmiddleware) + + [`createNetworkMiddleware`](#createnetworkmiddleware) + [`Offline Queue`](#offline-queue) * [Other Utilities](#other-utilities) + [`checkInternetConnection`](#checkinternetconnection) @@ -426,8 +426,13 @@ fetchData.meta = { #### `checkInternetConnection()` Utility function that allows you to query for internet connectivity on demand. If you have integrated this library with redux, you can then dispatch a `CONNECTION_CHANGE` action type to inform the `network` reducer accordingly and keep it up to date. Check the example below. +**Note**: It's recommended to always set `shouldPing` to `true` (the default behaviour), in order to prevent inconsistent behaviour on iOS for RN < 0.57. ```js -checkInternetConnection(url?: string = 'https://www.google.com/', pingTimeout?: number = 3000): Promise +checkInternetConnection( + url?: string = 'https://www.google.com/', + pingTimeout?: number = 3000, + shouldPing?: boolean = true +): Promise ``` ##### Example diff --git a/package.json b/package.json index 5be9e294..843c3d4d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-offline", - "version": "4.0.0", + "version": "4.1.0", "description": "Handy toolbelt to deal with offline mode in React Native applications. Cross-platform, provides a smooth redux integration.", "main": "./src/index.js", "author": "Raul Gomez Acuña (https://github.com/rgommezz)", diff --git a/src/utils/checkInternetConnection.js b/src/utils/checkInternetConnection.js index a88abd58..715eab2c 100644 --- a/src/utils/checkInternetConnection.js +++ b/src/utils/checkInternetConnection.js @@ -1,44 +1,26 @@ /* @flow */ -import { Platform, NetInfo } from 'react-native'; +import { NetInfo } from 'react-native'; import checkInternetAccess from './checkInternetAccess'; import { DEFAULT_PING_SERVER_URL, DEFAULT_TIMEOUT } from './constants'; /** * Utility that allows to query for internet connectivity on demand - * On iOS, the listener is fired immediately after registration - * On Android, we need to use `isConnected.fetch`, that returns a promise which resolves with a boolean * @param url * @param timeout + * @param shouldPing * @returns {Promise} */ -export default function checkInternetConnection( +export default async function checkInternetConnection( url: string = DEFAULT_PING_SERVER_URL, timeout: number = DEFAULT_TIMEOUT, + shouldPing: boolean = true, ): Promise { - let connectionChecked: Promise; - if (Platform.OS === 'ios') { - connectionChecked = new Promise((resolve: Function) => { - const handleFirstConnectivityChangeIOS = (isConnected: boolean) => { - NetInfo.isConnected.removeEventListener( - 'connectionChange', - handleFirstConnectivityChangeIOS, - ); - resolve(isConnected); - }; - NetInfo.isConnected.addEventListener( - 'connectionChange', - handleFirstConnectivityChangeIOS, - ); - }); - } else { - connectionChecked = NetInfo.isConnected.fetch(); - } - - return connectionChecked.then((isConnected: boolean) => { - if (isConnected) { - return checkInternetAccess({ timeout, url }); + return NetInfo.isConnected.fetch().then(async (isConnected: boolean) => { + if (shouldPing) { + const hasInternetAccess = await checkInternetAccess({ timeout, url }); + return hasInternetAccess; } - return Promise.resolve(false); + return isConnected; }); } diff --git a/test/checkInternetConnection.test.js b/test/checkInternetConnection.test.js new file mode 100644 index 00000000..01b54f79 --- /dev/null +++ b/test/checkInternetConnection.test.js @@ -0,0 +1,53 @@ +import { NetInfo } from 'react-native'; +import checkInternetConnection from '../src/utils/checkInternetConnection'; +import checkInternetAccess from '../src/utils/checkInternetAccess'; +import { + DEFAULT_PING_SERVER_URL, + DEFAULT_TIMEOUT, +} from '../src/utils/constants'; + +jest.mock('../src/utils/checkInternetAccess'); + +checkInternetAccess.mockResolvedValue(true); + +describe('checkInternetConnection', () => { + afterEach(() => { + checkInternetAccess.mockClear(); + }); + describe('shouldPing = true', () => { + it(`calls checkInternetAccess and resolves the promise with its returned value`, async () => { + NetInfo.isConnected.fetch.mockImplementationOnce(() => + Promise.resolve(true), + ); + const isConnected = await checkInternetConnection('foo.com', 3000, true); + expect(checkInternetAccess).toHaveBeenCalledWith({ + timeout: 3000, + url: 'foo.com', + }); + expect(isConnected).toBe(true); + }); + }); + + describe('shouldPing = false', () => { + it(`does NOT call checkInternetAccess and directly resolves the promise with a boolean`, async () => { + NetInfo.isConnected.fetch.mockImplementationOnce(() => + Promise.resolve(false), + ); + const isConnected = await checkInternetConnection('foo.com', 3000, false); + expect(checkInternetAccess).not.toHaveBeenCalled(); + expect(isConnected).toBe(false); + }); + }); + + it('default parameters', async () => { + NetInfo.isConnected.fetch.mockImplementationOnce(() => + Promise.resolve(true), + ); + const isConnected = await checkInternetConnection(); + expect(checkInternetAccess).toHaveBeenCalledWith({ + timeout: DEFAULT_TIMEOUT, + url: DEFAULT_PING_SERVER_URL, + }); + expect(isConnected).toBe(true); + }); +});