Skip to content

Commit f200cd6

Browse files
authored
bug: checkInternetConnection only works once (#146)
* Refactoring function and adding unit tests. * Documentation * Minor version bump
1 parent 4644a54 commit f200cd6

File tree

4 files changed

+71
-31
lines changed

4 files changed

+71
-31
lines changed

README.md

+8-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
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.
77

88
## Important (Please read)
9-
**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).**
9+
**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).**
1010

1111
## Contents
1212

@@ -23,7 +23,7 @@ Handful of utilities you should keep in your toolbelt to handle offline/online c
2323
+ [`Network reducer`](#network-reducer)
2424
+ [`ReduxNetworkProvider`](#reduxnetworkprovider)
2525
+ [`networkSaga`](#networksaga)
26-
+ [`createNetworkMiddleware()`](#createnetworkmiddleware)
26+
+ [`createNetworkMiddleware`](#createnetworkmiddleware)
2727
+ [`Offline Queue`](#offline-queue)
2828
* [Other Utilities](#other-utilities)
2929
+ [`checkInternetConnection`](#checkinternetconnection)
@@ -426,8 +426,13 @@ fetchData.meta = {
426426
#### `checkInternetConnection()`
427427
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.
428428

429+
**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.
429430
```js
430-
checkInternetConnection(url?: string = 'https://www.google.com/', pingTimeout?: number = 3000): Promise<boolean>
431+
checkInternetConnection(
432+
url?: string = 'https://www.google.com/',
433+
pingTimeout?: number = 3000,
434+
shouldPing?: boolean = true
435+
): Promise<boolean>
431436
```
432437

433438
##### Example

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-offline",
3-
"version": "4.0.0",
3+
"version": "4.1.0",
44
"description": "Handy toolbelt to deal with offline mode in React Native applications. Cross-platform, provides a smooth redux integration.",
55
"main": "./src/index.js",
66
"author": "Raul Gomez Acuña <[email protected]> (https://github.com/rgommezz)",

src/utils/checkInternetConnection.js

+9-27
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,26 @@
11
/* @flow */
22

3-
import { Platform, NetInfo } from 'react-native';
3+
import { NetInfo } from 'react-native';
44
import checkInternetAccess from './checkInternetAccess';
55
import { DEFAULT_PING_SERVER_URL, DEFAULT_TIMEOUT } from './constants';
66

77
/**
88
* Utility that allows to query for internet connectivity on demand
9-
* On iOS, the listener is fired immediately after registration
10-
* On Android, we need to use `isConnected.fetch`, that returns a promise which resolves with a boolean
119
* @param url
1210
* @param timeout
11+
* @param shouldPing
1312
* @returns {Promise<boolean>}
1413
*/
15-
export default function checkInternetConnection(
14+
export default async function checkInternetConnection(
1615
url: string = DEFAULT_PING_SERVER_URL,
1716
timeout: number = DEFAULT_TIMEOUT,
17+
shouldPing: boolean = true,
1818
): Promise<boolean> {
19-
let connectionChecked: Promise<boolean>;
20-
if (Platform.OS === 'ios') {
21-
connectionChecked = new Promise((resolve: Function) => {
22-
const handleFirstConnectivityChangeIOS = (isConnected: boolean) => {
23-
NetInfo.isConnected.removeEventListener(
24-
'connectionChange',
25-
handleFirstConnectivityChangeIOS,
26-
);
27-
resolve(isConnected);
28-
};
29-
NetInfo.isConnected.addEventListener(
30-
'connectionChange',
31-
handleFirstConnectivityChangeIOS,
32-
);
33-
});
34-
} else {
35-
connectionChecked = NetInfo.isConnected.fetch();
36-
}
37-
38-
return connectionChecked.then((isConnected: boolean) => {
39-
if (isConnected) {
40-
return checkInternetAccess({ timeout, url });
19+
return NetInfo.isConnected.fetch().then(async (isConnected: boolean) => {
20+
if (shouldPing) {
21+
const hasInternetAccess = await checkInternetAccess({ timeout, url });
22+
return hasInternetAccess;
4123
}
42-
return Promise.resolve(false);
24+
return isConnected;
4325
});
4426
}

test/checkInternetConnection.test.js

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { NetInfo } from 'react-native';
2+
import checkInternetConnection from '../src/utils/checkInternetConnection';
3+
import checkInternetAccess from '../src/utils/checkInternetAccess';
4+
import {
5+
DEFAULT_PING_SERVER_URL,
6+
DEFAULT_TIMEOUT,
7+
} from '../src/utils/constants';
8+
9+
jest.mock('../src/utils/checkInternetAccess');
10+
11+
checkInternetAccess.mockResolvedValue(true);
12+
13+
describe('checkInternetConnection', () => {
14+
afterEach(() => {
15+
checkInternetAccess.mockClear();
16+
});
17+
describe('shouldPing = true', () => {
18+
it(`calls checkInternetAccess and resolves the promise with its returned value`, async () => {
19+
NetInfo.isConnected.fetch.mockImplementationOnce(() =>
20+
Promise.resolve(true),
21+
);
22+
const isConnected = await checkInternetConnection('foo.com', 3000, true);
23+
expect(checkInternetAccess).toHaveBeenCalledWith({
24+
timeout: 3000,
25+
url: 'foo.com',
26+
});
27+
expect(isConnected).toBe(true);
28+
});
29+
});
30+
31+
describe('shouldPing = false', () => {
32+
it(`does NOT call checkInternetAccess and directly resolves the promise with a boolean`, async () => {
33+
NetInfo.isConnected.fetch.mockImplementationOnce(() =>
34+
Promise.resolve(false),
35+
);
36+
const isConnected = await checkInternetConnection('foo.com', 3000, false);
37+
expect(checkInternetAccess).not.toHaveBeenCalled();
38+
expect(isConnected).toBe(false);
39+
});
40+
});
41+
42+
it('default parameters', async () => {
43+
NetInfo.isConnected.fetch.mockImplementationOnce(() =>
44+
Promise.resolve(true),
45+
);
46+
const isConnected = await checkInternetConnection();
47+
expect(checkInternetAccess).toHaveBeenCalledWith({
48+
timeout: DEFAULT_TIMEOUT,
49+
url: DEFAULT_PING_SERVER_URL,
50+
});
51+
expect(isConnected).toBe(true);
52+
});
53+
});

0 commit comments

Comments
 (0)