Skip to content

Commit

Permalink
bug: checkInternetConnection only works once (#146)
Browse files Browse the repository at this point in the history
* Refactoring function and adding unit tests.
* Documentation
* Minor version bump
  • Loading branch information
rgommezz authored Jan 1, 2019
1 parent 4644a54 commit f200cd6
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 31 deletions.
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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)
Expand Down Expand Up @@ -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<boolean>
checkInternetConnection(
url?: string = 'https://www.google.com/',
pingTimeout?: number = 3000,
shouldPing?: boolean = true
): Promise<boolean>
```

##### Example
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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 <[email protected]> (https://github.com/rgommezz)",
Expand Down
36 changes: 9 additions & 27 deletions src/utils/checkInternetConnection.js
Original file line number Diff line number Diff line change
@@ -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<boolean>}
*/
export default function checkInternetConnection(
export default async function checkInternetConnection(
url: string = DEFAULT_PING_SERVER_URL,
timeout: number = DEFAULT_TIMEOUT,
shouldPing: boolean = true,
): Promise<boolean> {
let connectionChecked: Promise<boolean>;
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;
});
}
53 changes: 53 additions & 0 deletions test/checkInternetConnection.test.js
Original file line number Diff line number Diff line change
@@ -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);
});
});

0 comments on commit f200cd6

Please sign in to comment.