diff --git a/App/stores/api.test.ts b/App/stores/api.test.ts
new file mode 100644
index 00000000..33846549
--- /dev/null
+++ b/App/stores/api.test.ts
@@ -0,0 +1,33 @@
+// Sh**t! I Smoke
+// Copyright (C) 2018-2020 Marcelo S. Coelho, Amaury Martiny
+
+// Sh**t! I Smoke is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Sh**t! I Smoke is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Sh**t! I Smoke. If not, see .
+
+import { withTimeout } from './api';
+
+describe('withTimeout', () => {
+ it('should correct time out', async (done) => {
+ jest.setTimeout(5000);
+
+ const p = new Promise((resolve) => setTimeout(resolve, 2000));
+
+ try {
+ await withTimeout(p, 2000);
+
+ done.fail();
+ } catch (e) {
+ done();
+ }
+ });
+});
diff --git a/App/stores/api.tsx b/App/stores/api.tsx
index 3288c796..f0adfc33 100644
--- a/App/stores/api.tsx
+++ b/App/stores/api.tsx
@@ -41,6 +41,23 @@ interface ApiContextProviderProps {
// Timeout, in ms, after which we abandon the api request.
const API_TIMEOUT = 5000;
+/**
+ * withTimeout wraps another promise, and rejects if the inner promise
+ * time outs after `timeout`.
+ * @param p - Promise to add timeout to.
+ */
+export function withTimeout(p: Promise, timeout: number): Promise {
+ return Promise.race([
+ new Promise((_resolve, reject) => {
+ setTimeout(
+ () => reject('Request to fetch API data timed out.'),
+ timeout
+ );
+ }),
+ p,
+ ]);
+}
+
export function ApiContextProvider({
children,
}: ApiContextProviderProps): React.ReactElement {
@@ -67,20 +84,12 @@ export function ApiContextProvider({
// raceApiPromise will fetch the API data from different
// sources, and return the first result. We also add a
// timeout on these requests.
- Promise.race([
- new Promise((_resolve, reject) => {
- setTimeout(
- () =>
- reject(
- 'Request to fetch API data timed out.'
- ),
- API_TIMEOUT
- );
- }),
+ withTimeout(
raceApiPromise(currentLocation, {
aqicnToken: Constants.manifest.extra.aqicnToken,
}),
- ]),
+ API_TIMEOUT
+ ),
'ApiContext'
),
TE.fold(
diff --git a/package.json b/package.json
index 2eaa86d9..bc8985e8 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
"scripts": {
"lint": "tsc --noEmit && eslint --ext .js,.ts,.tsx .",
"start": "expo start",
+ "test:unit": "jest App",
"test:e2e": "detox test --configuration ios.sim --record-videos all"
},
"detox": {
@@ -47,7 +48,7 @@
"graphql": "^14.7.0",
"i18n-js": "^3.7.1",
"react": "16.11.0",
- "react-native": "https://github.com/expo/react-native/archive/sdk-38.0.0.tar.gz",
+ "react-native": "https://github.com/expo/react-native/archive/sdk-38.0.2.tar.gz",
"react-native-gesture-handler": "~1.6.0",
"react-native-maps": "0.27.1",
"react-native-reanimated": "~1.9.0",
diff --git a/yarn.lock b/yarn.lock
index 9b1eaded..1540cd7d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7460,11 +7460,6 @@ jsbn@~0.1.0:
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
-jsc-android@^245459.0.0:
- version "245459.0.0"
- resolved "https://registry.yarnpkg.com/jsc-android/-/jsc-android-245459.0.0.tgz#e584258dd0b04c9159a27fb104cd5d491fd202c9"
- integrity sha512-wkjURqwaB1daNkDi2OYYbsLnIdC/lUM2nPXQKRs5pqEU9chDg435bjvo+LSaHotDENygHQDHe+ntUkkw2gwMtg==
-
jsdom@^11.5.1:
version "11.12.0"
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8"
@@ -9711,9 +9706,9 @@ react-native-web@^0.12.2:
prop-types "^15.6.0"
react-timer-mixin "^0.13.4"
-"react-native@https://github.com/expo/react-native/archive/sdk-38.0.0.tar.gz":
+"react-native@https://github.com/expo/react-native/archive/sdk-38.0.2.tar.gz":
version "0.62.2"
- resolved "https://github.com/expo/react-native/archive/sdk-38.0.0.tar.gz#d90b8dce01dc4fcabd209372ac7da23ce2da3de8"
+ resolved "https://github.com/expo/react-native/archive/sdk-38.0.2.tar.gz#7f1e02c79dbbfa4f9fa37946046952763e9a9888"
dependencies:
"@babel/runtime" "^7.0.0"
"@react-native-community/cli" "^4.5.1"
@@ -9731,7 +9726,6 @@ react-native-web@^0.12.2:
fbjs-scripts "^1.1.0"
hermes-engine "0.0.0"
invariant "^2.2.4"
- jsc-android "^245459.0.0"
metro-babel-register "0.58.0"
metro-react-native-babel-transformer "0.58.0"
metro-source-map "0.58.0"