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"