diff --git a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java index 76b77d89c0..f293dd03a3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java @@ -116,10 +116,14 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule @Override public void initialize() { - ReactApplicationContext reactCtx = getReactApplicationContext(); - UIManagerModule uiManager = reactCtx.getNativeModule(UIManagerModule.class); - reactCtx.addLifecycleEventListener(this); - uiManager.addUIManagerListener(this); + ReactApplicationContext reactApplicationContext = + getReactApplicationContextIfActiveOrWarn(NAME, "initialize"); + + if (reactApplicationContext != null) { + UIManagerModule uiManager = reactApplicationContext.getNativeModule(UIManagerModule.class); + reactApplicationContext.addLifecycleEventListener(this); + uiManager.addUIManagerListener(this); + } } @Override @@ -175,9 +179,13 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule private NativeAnimatedNodesManager getNodesManager() { if (mNodesManager == null) { - UIManagerModule uiManager = - getReactApplicationContext().getNativeModule(UIManagerModule.class); - mNodesManager = new NativeAnimatedNodesManager(uiManager); + ReactApplicationContext reactApplicationContext = + getReactApplicationContextIfActiveOrWarn(NAME, "getNodesManager"); + + if (reactApplicationContext != null) { + UIManagerModule uiManager = reactApplicationContext.getNativeModule(UIManagerModule.class); + mNodesManager = new NativeAnimatedNodesManager(uiManager); + } } return mNodesManager; @@ -219,9 +227,15 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule WritableMap onAnimatedValueData = Arguments.createMap(); onAnimatedValueData.putInt("tag", tag); onAnimatedValueData.putDouble("value", value); - getReactApplicationContext() - .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) - .emit("onAnimatedValueUpdate", onAnimatedValueData); + + ReactApplicationContext reactApplicationContext = + getReactApplicationContextIfActiveOrWarn( + NAME, "startListeningToAnimatedNodeValue.onValueUpdate"); + if (reactApplicationContext != null) { + reactApplicationContext + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit("onAnimatedValueUpdate", onAnimatedValueData); + } } }; diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/JSCHeapCapture.java b/ReactAndroid/src/main/java/com/facebook/react/devsupport/JSCHeapCapture.java index 1951c3fb46..147fae4ce9 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/JSCHeapCapture.java +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/JSCHeapCapture.java @@ -19,6 +19,8 @@ import java.io.File; // requires it to already be initialized, thus we eagerly initialize this module @ReactModule(name = "JSCHeapCapture", needsEagerInit = true) public class JSCHeapCapture extends ReactContextBaseJavaModule { + public static final String TAG = JSCHeapCapture.class.getSimpleName(); + public interface HeapCapture extends JavaScriptModule { void captureHeap(String path); } @@ -54,13 +56,18 @@ public class JSCHeapCapture extends ReactContextBaseJavaModule { File f = new File(path + "/capture.json"); f.delete(); - HeapCapture heapCapture = getReactApplicationContext().getJSModule(HeapCapture.class); - if (heapCapture == null) { - callback.onFailure(new CaptureException("Heap capture js module not registered.")); - return; + ReactApplicationContext reactApplicationContext = + getReactApplicationContextIfActiveOrWarn(TAG, "captureHeap"); + + if (reactApplicationContext != null) { + HeapCapture heapCapture = reactApplicationContext.getJSModule(HeapCapture.class); + if (heapCapture == null) { + callback.onFailure(new CaptureException("Heap capture js module not registered.")); + return; + } + mCaptureInProgress = callback; + heapCapture.captureHeap(f.getPath()); } - mCaptureInProgress = callback; - heapCapture.captureHeap(f.getPath()); } @ReactMethod diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/JSDevSupport.java b/ReactAndroid/src/main/java/com/facebook/react/devsupport/JSDevSupport.java index e56b8b066f..f44e686751 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/JSDevSupport.java +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/JSDevSupport.java @@ -20,7 +20,6 @@ import java.util.Map; @ReactModule(name = JSDevSupport.MODULE_NAME) public class JSDevSupport extends ReactContextBaseJavaModule { - public static final String MODULE_NAME = "JSDevSupport"; public static final int ERROR_CODE_EXCEPTION = 0; @@ -55,8 +54,14 @@ public class JSDevSupport extends ReactContextBaseJavaModule { } public synchronized void getJSHierarchy(int reactTag, DevSupportCallback callback) { - JSDevSupportModule jsDevSupportModule = - getReactApplicationContext().getJSModule(JSDevSupportModule.class); + ReactApplicationContext reactApplicationContext = + getReactApplicationContextIfActiveOrWarn(MODULE_NAME, "getJSHierarchy"); + + JSDevSupportModule jsDevSupportModule = null; + if (reactApplicationContext != null) { + jsDevSupportModule = reactApplicationContext.getJSModule(JSDevSupportModule.class); + } + if (jsDevSupportModule == null) { callback.onFailure( ERROR_CODE_EXCEPTION, diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/AccessibilityInfoModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/AccessibilityInfoModule.java index e6cda9fa74..9ff400bb32 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/AccessibilityInfoModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/AccessibilityInfoModule.java @@ -116,18 +116,29 @@ public class AccessibilityInfoModule extends ReactContextBaseJavaModule if (mReduceMotionEnabled != isReduceMotionEnabled) { mReduceMotionEnabled = isReduceMotionEnabled; - getReactApplicationContext() - .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) - .emit(REDUCE_MOTION_EVENT_NAME, mReduceMotionEnabled); + + ReactApplicationContext reactApplicationContext = + getReactApplicationContextIfActiveOrWarn(NAME, "updateAndSendReduceMotionChangeEvent"); + if (reactApplicationContext != null) { + reactApplicationContext + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit(REDUCE_MOTION_EVENT_NAME, mReduceMotionEnabled); + } } } private void updateAndSendTouchExplorationChangeEvent(boolean enabled) { if (mTouchExplorationEnabled != enabled) { mTouchExplorationEnabled = enabled; - getReactApplicationContext() - .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) - .emit(TOUCH_EXPLORATION_EVENT_NAME, mTouchExplorationEnabled); + + ReactApplicationContext reactApplicationContext = + getReactApplicationContextIfActiveOrWarn( + NAME, "updateAndSendTouchExplorationChangeEvent"); + if (reactApplicationContext != null) { + getReactApplicationContext() + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit(TOUCH_EXPLORATION_EVENT_NAME, mTouchExplorationEnabled); + } } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/appearance/AppearanceModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/appearance/AppearanceModule.java index e8c3efc50a..321f732779 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/appearance/AppearanceModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/appearance/AppearanceModule.java @@ -21,6 +21,7 @@ import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEm /** Module that exposes the user's preferred color scheme. For API >= 29. */ @ReactModule(name = AppearanceModule.NAME) public class AppearanceModule extends ReactContextBaseJavaModule { + public static final String NAME = "Appearance"; private static final String APPEARANCE_CHANGED_EVENT_NAME = "appearanceChanged"; @@ -85,8 +86,13 @@ public class AppearanceModule extends ReactContextBaseJavaModule { WritableMap appearancePreferences = Arguments.createMap(); appearancePreferences.putString("colorScheme", colorScheme); - getReactApplicationContext() - .getJSModule(RCTDeviceEventEmitter.class) - .emit(APPEARANCE_CHANGED_EVENT_NAME, appearancePreferences); + ReactApplicationContext reactApplicationContext = + getReactApplicationContextIfActiveOrWarn(NAME, "emitAppearanceChanged"); + + if (reactApplicationContext != null) { + reactApplicationContext + .getJSModule(RCTDeviceEventEmitter.class) + .emit(APPEARANCE_CHANGED_EVENT_NAME, appearancePreferences); + } } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/blob/BlobModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/blob/BlobModule.java index d7b2afd43d..e9ac538778 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/blob/BlobModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/blob/BlobModule.java @@ -286,37 +286,61 @@ public class BlobModule extends ReactContextBaseJavaModule { return type; } - private WebSocketModule getWebSocketModule() { - return getReactApplicationContext().getNativeModule(WebSocketModule.class); + private WebSocketModule getWebSocketModule(String reason) { + ReactApplicationContext reactApplicationContext = + getReactApplicationContextIfActiveOrWarn(NAME, reason); + + if (reactApplicationContext != null) { + return reactApplicationContext.getNativeModule(WebSocketModule.class); + } + + return null; } @ReactMethod public void addNetworkingHandler() { - NetworkingModule networkingModule = - getReactApplicationContext().getNativeModule(NetworkingModule.class); - networkingModule.addUriHandler(mNetworkingUriHandler); - networkingModule.addRequestBodyHandler(mNetworkingRequestBodyHandler); - networkingModule.addResponseHandler(mNetworkingResponseHandler); + ReactApplicationContext reactApplicationContext = + getReactApplicationContextIfActiveOrWarn(NAME, "addNetworkingHandler"); + + if (reactApplicationContext != null) { + NetworkingModule networkingModule = + reactApplicationContext.getNativeModule(NetworkingModule.class); + networkingModule.addUriHandler(mNetworkingUriHandler); + networkingModule.addRequestBodyHandler(mNetworkingRequestBodyHandler); + networkingModule.addResponseHandler(mNetworkingResponseHandler); + } } @ReactMethod public void addWebSocketHandler(final int id) { - getWebSocketModule().setContentHandler(id, mWebSocketContentHandler); + WebSocketModule webSocketModule = getWebSocketModule("addWebSocketHandler"); + + if (webSocketModule != null) { + webSocketModule.setContentHandler(id, mWebSocketContentHandler); + } } @ReactMethod public void removeWebSocketHandler(final int id) { - getWebSocketModule().setContentHandler(id, null); + WebSocketModule webSocketModule = getWebSocketModule("removeWebSocketHandler"); + + if (webSocketModule != null) { + webSocketModule.setContentHandler(id, null); + } } @ReactMethod public void sendOverSocket(ReadableMap blob, int id) { - byte[] data = resolve(blob.getString("blobId"), blob.getInt("offset"), blob.getInt("size")); + WebSocketModule webSocketModule = getWebSocketModule("sendOverSocket"); - if (data != null) { - getWebSocketModule().sendBinary(ByteString.of(data), id); - } else { - getWebSocketModule().sendBinary((ByteString) null, id); + if (webSocketModule != null) { + byte[] data = resolve(blob.getString("blobId"), blob.getInt("offset"), blob.getInt("size")); + + if (data != null) { + webSocketModule.sendBinary(ByteString.of(data), id); + } else { + webSocketModule.sendBinary((ByteString) null, id); + } } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/blob/FileReaderModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/blob/FileReaderModule.java index a61e3d5f37..e86d37db5e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/blob/FileReaderModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/blob/FileReaderModule.java @@ -30,16 +30,29 @@ public class FileReaderModule extends ReactContextBaseJavaModule { return NAME; } - private BlobModule getBlobModule() { - return getReactApplicationContext().getNativeModule(BlobModule.class); + private BlobModule getBlobModule(String reason) { + ReactApplicationContext reactApplicationContext = + getReactApplicationContextIfActiveOrWarn(NAME, reason); + + if (reactApplicationContext != null) { + return reactApplicationContext.getNativeModule(BlobModule.class); + } + + return null; } @ReactMethod public void readAsText(ReadableMap blob, String encoding, Promise promise) { + BlobModule blobModule = getBlobModule("readAsText"); + + if (blobModule == null) { + promise.reject( + new IllegalStateException("Could not get BlobModule from ReactApplicationContext")); + return; + } byte[] bytes = - getBlobModule() - .resolve(blob.getString("blobId"), blob.getInt("offset"), blob.getInt("size")); + blobModule.resolve(blob.getString("blobId"), blob.getInt("offset"), blob.getInt("size")); if (bytes == null) { promise.reject(ERROR_INVALID_BLOB, "The specified blob is invalid"); @@ -55,9 +68,16 @@ public class FileReaderModule extends ReactContextBaseJavaModule { @ReactMethod public void readAsDataURL(ReadableMap blob, Promise promise) { + BlobModule blobModule = getBlobModule("readAsDataURL"); + + if (blobModule == null) { + promise.reject( + new IllegalStateException("Could not get BlobModule from ReactApplicationContext")); + return; + } + byte[] bytes = - getBlobModule() - .resolve(blob.getString("blobId"), blob.getInt("offset"), blob.getInt("size")); + blobModule.resolve(blob.getString("blobId"), blob.getInt("offset"), blob.getInt("size")); if (bytes == null) { promise.reject(ERROR_INVALID_BLOB, "The specified blob is invalid"); diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/core/DeviceEventManagerModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/core/DeviceEventManagerModule.java index a1d5d2917d..45a016c575 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/core/DeviceEventManagerModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/core/DeviceEventManagerModule.java @@ -47,16 +47,26 @@ public class DeviceEventManagerModule extends ReactContextBaseJavaModule { /** Sends an event to the JS instance that the hardware back has been pressed. */ public void emitHardwareBackPressed() { - getReactApplicationContext() - .getJSModule(RCTDeviceEventEmitter.class) - .emit("hardwareBackPress", null); + ReactApplicationContext reactApplicationContext = + getReactApplicationContextIfActiveOrWarn(NAME, "emitHardwareBackPressed"); + + if (reactApplicationContext != null) { + reactApplicationContext + .getJSModule(RCTDeviceEventEmitter.class) + .emit("hardwareBackPress", null); + } } /** Sends an event to the JS instance that a new intent was received. */ public void emitNewIntentReceived(Uri uri) { - WritableMap map = Arguments.createMap(); - map.putString("url", uri.toString()); - getReactApplicationContext().getJSModule(RCTDeviceEventEmitter.class).emit("url", map); + ReactApplicationContext reactApplicationContext = + getReactApplicationContextIfActiveOrWarn(NAME, "emitHardwareBackPressed"); + + if (reactApplicationContext != null) { + WritableMap map = Arguments.createMap(); + map.putString("url", uri.toString()); + reactApplicationContext.getJSModule(RCTDeviceEventEmitter.class).emit("url", map); + } } /** @@ -65,6 +75,9 @@ public class DeviceEventManagerModule extends ReactContextBaseJavaModule { */ @ReactMethod public void invokeDefaultBackPressHandler() { + // There should be no need to check if the catalyst instance is alive. After initialization + // the thread instances cannot be null, and scheduling on a thread after ReactApplicationContext + // teardown is a noop. getReactApplicationContext().runOnUiQueueThread(mInvokeDefaultBackPressRunnable); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.java index 86185a5376..9220e3b9c9 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.java @@ -25,17 +25,32 @@ public final class TimingModule extends ReactContextBaseJavaModule public class BridgeTimerManager implements JavaScriptTimerManager { @Override public void callTimers(WritableArray timerIDs) { - getReactApplicationContext().getJSModule(JSTimers.class).callTimers(timerIDs); + ReactApplicationContext reactApplicationContext = + getReactApplicationContextIfActiveOrWarn(NAME, "callTimers"); + + if (reactApplicationContext != null) { + reactApplicationContext.getJSModule(JSTimers.class).callTimers(timerIDs); + } } @Override public void callIdleCallbacks(double frameTime) { - getReactApplicationContext().getJSModule(JSTimers.class).callIdleCallbacks(frameTime); + ReactApplicationContext reactApplicationContext = + getReactApplicationContextIfActiveOrWarn(NAME, "callIdleCallbacks"); + + if (reactApplicationContext != null) { + reactApplicationContext.getJSModule(JSTimers.class).callIdleCallbacks(frameTime); + } } @Override public void emitTimeDriftWarning(String warningMessage) { - getReactApplicationContext().getJSModule(JSTimers.class).emitTimeDriftWarning(warningMessage); + ReactApplicationContext reactApplicationContext = + getReactApplicationContextIfActiveOrWarn(NAME, "emitTimeDriftWarning"); + + if (reactApplicationContext != null) { + reactApplicationContext.getJSModule(JSTimers.class).emitTimeDriftWarning(warningMessage); + } } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/debug/DevSettingsModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/debug/DevSettingsModule.java index 6ea959d03f..ea6feb19b5 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/debug/DevSettingsModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/debug/DevSettingsModule.java @@ -92,9 +92,15 @@ public class DevSettingsModule extends ReactContextBaseJavaModule { public void onOptionSelected() { WritableMap data = Arguments.createMap(); data.putString("title", title); - getReactApplicationContext() - .getJSModule(RCTDeviceEventEmitter.class) - .emit("didPressMenuItem", data); + + ReactApplicationContext reactApplicationContext = + getReactApplicationContextIfActiveOrWarn(NAME, "onOptionSelected"); + + if (reactApplicationContext != null) { + reactApplicationContext + .getJSModule(RCTDeviceEventEmitter.class) + .emit("didPressMenuItem", data); + } } }); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java index c380100dc2..91e1a2588b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java @@ -249,7 +249,10 @@ public final class NetworkingModule extends ReactContextBaseJavaModule { withCredentials); } catch (Throwable th) { FLog.e(TAG, "Failed to send url request: " + url, th); - ResponseUtil.onRequestError(getEventEmitter(), requestId, th.getMessage(), th); + final RCTDeviceEventEmitter eventEmitter = getEventEmitter("sendRequest error"); + if (eventEmitter != null) { + ResponseUtil.onRequestError(eventEmitter, requestId, th.getMessage(), th); + } } } @@ -264,7 +267,7 @@ public final class NetworkingModule extends ReactContextBaseJavaModule { final boolean useIncrementalUpdates, int timeout, boolean withCredentials) { - final RCTDeviceEventEmitter eventEmitter = getEventEmitter(); + final RCTDeviceEventEmitter eventEmitter = getEventEmitter("sendRequestInternal"); try { Uri uri = Uri.parse(url); @@ -664,7 +667,7 @@ public final class NetworkingModule extends ReactContextBaseJavaModule { private @Nullable MultipartBody.Builder constructMultipartBody( ReadableArray body, String contentType, int requestId) { - RCTDeviceEventEmitter eventEmitter = getEventEmitter(); + RCTDeviceEventEmitter eventEmitter = getEventEmitter("constructMultipartBody"); MultipartBody.Builder multipartBuilder = new MultipartBody.Builder(); multipartBuilder.setType(MediaType.parse(contentType)); @@ -750,7 +753,14 @@ public final class NetworkingModule extends ReactContextBaseJavaModule { return headersBuilder.build(); } - private RCTDeviceEventEmitter getEventEmitter() { - return getReactApplicationContext().getJSModule(RCTDeviceEventEmitter.class); + private RCTDeviceEventEmitter getEventEmitter(String reason) { + ReactApplicationContext reactApplicationContext = + getReactApplicationContextIfActiveOrWarn(TAG, reason); + + if (reactApplicationContext != null) { + return getReactApplicationContext().getJSModule(RCTDeviceEventEmitter.class); + } + + return null; } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/network/ResponseUtil.java b/ReactAndroid/src/main/java/com/facebook/react/modules/network/ResponseUtil.java index 3b65b5cd0d..75015efb36 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/network/ResponseUtil.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/network/ResponseUtil.java @@ -7,6 +7,7 @@ package com.facebook.react.modules.network; +import androidx.annotation.Nullable; import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.WritableArray; import com.facebook.react.bridge.WritableMap; @@ -16,55 +17,69 @@ import java.net.SocketTimeoutException; /** Util methods to send network responses to JS. */ public class ResponseUtil { public static void onDataSend( - RCTDeviceEventEmitter eventEmitter, int requestId, long progress, long total) { + @Nullable RCTDeviceEventEmitter eventEmitter, int requestId, long progress, long total) { WritableArray args = Arguments.createArray(); args.pushInt(requestId); args.pushInt((int) progress); args.pushInt((int) total); - eventEmitter.emit("didSendNetworkData", args); + if (eventEmitter != null) { + eventEmitter.emit("didSendNetworkData", args); + } } public static void onIncrementalDataReceived( - RCTDeviceEventEmitter eventEmitter, int requestId, String data, long progress, long total) { + @Nullable RCTDeviceEventEmitter eventEmitter, + int requestId, + String data, + long progress, + long total) { WritableArray args = Arguments.createArray(); args.pushInt(requestId); args.pushString(data); args.pushInt((int) progress); args.pushInt((int) total); - eventEmitter.emit("didReceiveNetworkIncrementalData", args); + if (eventEmitter != null) { + eventEmitter.emit("didReceiveNetworkIncrementalData", args); + } } public static void onDataReceivedProgress( - RCTDeviceEventEmitter eventEmitter, int requestId, long progress, long total) { + @Nullable RCTDeviceEventEmitter eventEmitter, int requestId, long progress, long total) { WritableArray args = Arguments.createArray(); args.pushInt(requestId); args.pushInt((int) progress); args.pushInt((int) total); - eventEmitter.emit("didReceiveNetworkDataProgress", args); + if (eventEmitter != null) { + eventEmitter.emit("didReceiveNetworkDataProgress", args); + } } public static void onDataReceived( - RCTDeviceEventEmitter eventEmitter, int requestId, String data) { + @Nullable RCTDeviceEventEmitter eventEmitter, int requestId, String data) { WritableArray args = Arguments.createArray(); args.pushInt(requestId); args.pushString(data); - eventEmitter.emit("didReceiveNetworkData", args); + if (eventEmitter != null) { + eventEmitter.emit("didReceiveNetworkData", args); + } } public static void onDataReceived( - RCTDeviceEventEmitter eventEmitter, int requestId, WritableMap data) { + @Nullable RCTDeviceEventEmitter eventEmitter, int requestId, WritableMap data) { WritableArray args = Arguments.createArray(); args.pushInt(requestId); args.pushMap(data); - eventEmitter.emit("didReceiveNetworkData", args); + if (eventEmitter != null) { + eventEmitter.emit("didReceiveNetworkData", args); + } } public static void onRequestError( - RCTDeviceEventEmitter eventEmitter, int requestId, String error, Throwable e) { + @Nullable RCTDeviceEventEmitter eventEmitter, int requestId, String error, Throwable e) { WritableArray args = Arguments.createArray(); args.pushInt(requestId); args.pushString(error); @@ -73,19 +88,23 @@ public class ResponseUtil { args.pushBoolean(true); // last argument is a time out boolean } - eventEmitter.emit("didCompleteNetworkResponse", args); + if (eventEmitter != null) { + eventEmitter.emit("didCompleteNetworkResponse", args); + } } - public static void onRequestSuccess(RCTDeviceEventEmitter eventEmitter, int requestId) { + public static void onRequestSuccess(@Nullable RCTDeviceEventEmitter eventEmitter, int requestId) { WritableArray args = Arguments.createArray(); args.pushInt(requestId); args.pushNull(); - eventEmitter.emit("didCompleteNetworkResponse", args); + if (eventEmitter != null) { + eventEmitter.emit("didCompleteNetworkResponse", args); + } } public static void onResponseReceived( - RCTDeviceEventEmitter eventEmitter, + @Nullable RCTDeviceEventEmitter eventEmitter, int requestId, int statusCode, WritableMap headers, @@ -96,6 +115,8 @@ public class ResponseUtil { args.pushMap(headers); args.pushString(url); - eventEmitter.emit("didReceiveNetworkResponse", args); + if (eventEmitter != null) { + eventEmitter.emit("didReceiveNetworkResponse", args); + } } } diff --git a/ReactAndroid/src/test/java/com/facebook/react/modules/network/NetworkingModuleTest.java b/ReactAndroid/src/test/java/com/facebook/react/modules/network/NetworkingModuleTest.java index 2ad5a98056..36104c1e28 100644 --- a/ReactAndroid/src/test/java/com/facebook/react/modules/network/NetworkingModuleTest.java +++ b/ReactAndroid/src/test/java/com/facebook/react/modules/network/NetworkingModuleTest.java @@ -16,6 +16,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.CatalystInstance; import com.facebook.react.bridge.JavaOnlyArray; import com.facebook.react.bridge.JavaOnlyMap; import com.facebook.react.bridge.ReactApplicationContext; @@ -36,6 +37,7 @@ import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okio.Buffer; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -66,13 +68,17 @@ import org.robolectric.RobolectricTestRunner; @RunWith(RobolectricTestRunner.class) @PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "androidx.*", "android.*"}) public class NetworkingModuleTest { + private NetworkingModule mNetworkingModule; + private OkHttpClient mHttpClient; + private RCTDeviceEventEmitter mEmitter; @Rule public PowerMockRule rule = new PowerMockRule(); - @Test - public void testGetWithoutHeaders() throws Exception { - OkHttpClient httpClient = mock(OkHttpClient.class); - when(httpClient.newCall(any(Request.class))) + @Before + public void prepareModules() { + mHttpClient = mock(OkHttpClient.class); + when(mHttpClient.cookieJar()).thenReturn(mock(CookieJarContainer.class)); + when(mHttpClient.newCall(any(Request.class))) .thenAnswer( new Answer() { @Override @@ -82,12 +88,22 @@ public class NetworkingModuleTest { } }); OkHttpClient.Builder clientBuilder = mock(OkHttpClient.Builder.class); - when(clientBuilder.build()).thenReturn(httpClient); - when(httpClient.newBuilder()).thenReturn(clientBuilder); - NetworkingModule networkingModule = - new NetworkingModule(mock(ReactApplicationContext.class), "", httpClient); + when(clientBuilder.build()).thenReturn(mHttpClient); + when(mHttpClient.newBuilder()).thenReturn(clientBuilder); - networkingModule.sendRequest( + mEmitter = mock(RCTDeviceEventEmitter.class); + + CatalystInstance reactInstance = mock(CatalystInstance.class); + ReactApplicationContext reactContext = mock(ReactApplicationContext.class); + when(reactContext.getCatalystInstance()).thenReturn(reactInstance); + when(reactContext.hasActiveCatalystInstance()).thenReturn(true); + when(reactContext.getJSModule(any(Class.class))).thenReturn(mEmitter); + mNetworkingModule = new NetworkingModule(reactContext, "", mHttpClient); + } + + @Test + public void testGetWithoutHeaders() throws Exception { + mNetworkingModule.sendRequest( "GET", "http://somedomain/foo", /* requestId */ 0, @@ -99,7 +115,7 @@ public class NetworkingModuleTest { /* withCredentials */ false); ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Request.class); - verify(httpClient).newCall(argumentCaptor.capture()); + verify(mHttpClient).newCall(argumentCaptor.capture()); assertThat(argumentCaptor.getValue().url().toString()).isEqualTo("http://somedomain/foo"); // We set the User-Agent header by default assertThat(argumentCaptor.getValue().headers().size()).isEqualTo(1); @@ -108,21 +124,11 @@ public class NetworkingModuleTest { @Test public void testFailGetWithInvalidHeadersStruct() throws Exception { - RCTDeviceEventEmitter emitter = mock(RCTDeviceEventEmitter.class); - ReactApplicationContext context = mock(ReactApplicationContext.class); - when(context.getJSModule(any(Class.class))).thenReturn(emitter); - - OkHttpClient httpClient = mock(OkHttpClient.class); - OkHttpClient.Builder clientBuilder = mock(OkHttpClient.Builder.class); - when(clientBuilder.build()).thenReturn(httpClient); - when(httpClient.newBuilder()).thenReturn(clientBuilder); - NetworkingModule networkingModule = new NetworkingModule(context, "", httpClient); - List invalidHeaders = Arrays.asList(JavaOnlyArray.of("foo")); mockEvents(); - networkingModule.sendRequest( + mNetworkingModule.sendRequest( "GET", "http://somedoman/foo", /* requestId */ 0, @@ -133,27 +139,17 @@ public class NetworkingModuleTest { /* timeout */ 0, /* withCredentials */ false); - verifyErrorEmit(emitter, 0); + verifyErrorEmit(mEmitter, 0); } @Test public void testFailPostWithoutContentType() throws Exception { - RCTDeviceEventEmitter emitter = mock(RCTDeviceEventEmitter.class); - ReactApplicationContext context = mock(ReactApplicationContext.class); - when(context.getJSModule(any(Class.class))).thenReturn(emitter); - - OkHttpClient httpClient = mock(OkHttpClient.class); - OkHttpClient.Builder clientBuilder = mock(OkHttpClient.Builder.class); - when(clientBuilder.build()).thenReturn(httpClient); - when(httpClient.newBuilder()).thenReturn(clientBuilder); - NetworkingModule networkingModule = new NetworkingModule(context, "", httpClient); - JavaOnlyMap body = new JavaOnlyMap(); body.putString("string", "This is request body"); mockEvents(); - networkingModule.sendRequest( + mNetworkingModule.sendRequest( "POST", "http://somedomain/bar", 0, @@ -164,24 +160,14 @@ public class NetworkingModuleTest { /* timeout */ 0, /* withCredentials */ false); - verifyErrorEmit(emitter, 0); + verifyErrorEmit(mEmitter, 0); } @Test public void testFailInvalidUrl() throws Exception { - RCTDeviceEventEmitter emitter = mock(RCTDeviceEventEmitter.class); - ReactApplicationContext context = mock(ReactApplicationContext.class); - when(context.getJSModule(any(Class.class))).thenReturn(emitter); - - OkHttpClient httpClient = mock(OkHttpClient.class); - OkHttpClient.Builder clientBuilder = mock(OkHttpClient.Builder.class); - when(clientBuilder.build()).thenReturn(httpClient); - when(httpClient.newBuilder()).thenReturn(clientBuilder); - NetworkingModule networkingModule = new NetworkingModule(context, "", httpClient); - mockEvents(); - networkingModule.sendRequest( + mNetworkingModule.sendRequest( "GET", "aaa", /* requestId */ 0, @@ -192,7 +178,7 @@ public class NetworkingModuleTest { /* timeout */ 0, /* withCredentials */ false); - verifyErrorEmit(emitter, 0); + verifyErrorEmit(mEmitter, 0); } private static void verifyErrorEmit(RCTDeviceEventEmitter emitter, int requestId) { @@ -227,31 +213,12 @@ public class NetworkingModuleTest { @Test public void testSuccessfulPostRequest() throws Exception { - RCTDeviceEventEmitter emitter = mock(RCTDeviceEventEmitter.class); - ReactApplicationContext context = mock(ReactApplicationContext.class); - when(context.getJSModule(any(Class.class))).thenReturn(emitter); - - OkHttpClient httpClient = mock(OkHttpClient.class); - when(httpClient.newCall(any(Request.class))) - .thenAnswer( - new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - Call callMock = mock(Call.class); - return callMock; - } - }); - OkHttpClient.Builder clientBuilder = mock(OkHttpClient.Builder.class); - when(clientBuilder.build()).thenReturn(httpClient); - when(httpClient.newBuilder()).thenReturn(clientBuilder); - NetworkingModule networkingModule = new NetworkingModule(context, "", httpClient); - JavaOnlyMap body = new JavaOnlyMap(); body.putString("string", "This is request body"); mockEvents(); - networkingModule.sendRequest( + mNetworkingModule.sendRequest( "POST", "http://somedomain/bar", 0, @@ -263,7 +230,7 @@ public class NetworkingModuleTest { /* withCredentials */ false); ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Request.class); - verify(httpClient).newCall(argumentCaptor.capture()); + verify(mHttpClient).newCall(argumentCaptor.capture()); assertThat(argumentCaptor.getValue().url().toString()).isEqualTo("http://somedomain/bar"); assertThat(argumentCaptor.getValue().headers().size()).isEqualTo(2); assertThat(argumentCaptor.getValue().method()).isEqualTo("POST"); @@ -276,28 +243,12 @@ public class NetworkingModuleTest { @Test public void testHeaders() throws Exception { - OkHttpClient httpClient = mock(OkHttpClient.class); - when(httpClient.newCall(any(Request.class))) - .thenAnswer( - new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - Call callMock = mock(Call.class); - return callMock; - } - }); - OkHttpClient.Builder clientBuilder = mock(OkHttpClient.Builder.class); - when(clientBuilder.build()).thenReturn(httpClient); - when(httpClient.newBuilder()).thenReturn(clientBuilder); - NetworkingModule networkingModule = - new NetworkingModule(mock(ReactApplicationContext.class), "", httpClient); - List headers = Arrays.asList( JavaOnlyArray.of("Accept", "text/plain"), JavaOnlyArray.of("User-Agent", "React test agent/1.0")); - networkingModule.sendRequest( + mNetworkingModule.sendRequest( "GET", "http://someurl/baz", 0, @@ -308,7 +259,7 @@ public class NetworkingModuleTest { /* timeout */ 0, /* withCredentials */ false); ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Request.class); - verify(httpClient).newCall(argumentCaptor.capture()); + verify(mHttpClient).newCall(argumentCaptor.capture()); Headers requestHeaders = argumentCaptor.getValue().headers(); assertThat(requestHeaders.size()).isEqualTo(2); assertThat(requestHeaders.get("Accept")).isEqualTo("text/plain"); @@ -317,26 +268,11 @@ public class NetworkingModuleTest { @Test public void testPostJsonContentTypeHeader() throws Exception { - OkHttpClient httpClient = mock(OkHttpClient.class); - when(httpClient.newCall(any(Request.class))) - .thenAnswer( - new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - Call callMock = mock(Call.class); - return callMock; - } - }); - OkHttpClient.Builder clientBuilder = mock(OkHttpClient.Builder.class); - when(clientBuilder.build()).thenReturn(httpClient); - when(httpClient.newBuilder()).thenReturn(clientBuilder); - NetworkingModule networkingModule = - new NetworkingModule(mock(ReactApplicationContext.class), "", httpClient); JavaOnlyMap body = new JavaOnlyMap(); body.putString("string", "{ \"key\": \"value\" }"); - networkingModule.sendRequest( + mNetworkingModule.sendRequest( "POST", "http://somedomain/bar", 0, @@ -348,7 +284,7 @@ public class NetworkingModuleTest { /* withCredentials */ false); ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Request.class); - verify(httpClient).newCall(argumentCaptor.capture()); + verify(mHttpClient).newCall(argumentCaptor.capture()); // Verify okhttp does not append "charset=utf-8" assertThat(argumentCaptor.getValue().body().contentType().toString()) @@ -357,31 +293,12 @@ public class NetworkingModuleTest { @Test public void testRespectsExistingCharacterSet() throws Exception { - RCTDeviceEventEmitter emitter = mock(RCTDeviceEventEmitter.class); - ReactApplicationContext context = mock(ReactApplicationContext.class); - when(context.getJSModule(any(Class.class))).thenReturn(emitter); - - OkHttpClient httpClient = mock(OkHttpClient.class); - when(httpClient.newCall(any(Request.class))) - .thenAnswer( - new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - Call callMock = mock(Call.class); - return callMock; - } - }); - OkHttpClient.Builder clientBuilder = mock(OkHttpClient.Builder.class); - when(clientBuilder.build()).thenReturn(httpClient); - when(httpClient.newBuilder()).thenReturn(clientBuilder); - NetworkingModule networkingModule = new NetworkingModule(context, "", httpClient); - JavaOnlyMap body = new JavaOnlyMap(); body.putString("string", "Friðjónsson"); mockEvents(); - networkingModule.sendRequest( + mNetworkingModule.sendRequest( "POST", "http://somedomain/bar", 0, @@ -393,7 +310,7 @@ public class NetworkingModuleTest { /* withCredentials */ false); ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Request.class); - verify(httpClient).newCall(argumentCaptor.capture()); + verify(mHttpClient).newCall(argumentCaptor.capture()); Buffer contentBuffer = new Buffer(); argumentCaptor.getValue().body().writeTo(contentBuffer); @@ -402,31 +319,12 @@ public class NetworkingModuleTest { @Test public void testGracefullyRecoversFromInvalidContentType() throws Exception { - RCTDeviceEventEmitter emitter = mock(RCTDeviceEventEmitter.class); - ReactApplicationContext context = mock(ReactApplicationContext.class); - when(context.getJSModule(any(Class.class))).thenReturn(emitter); - - OkHttpClient httpClient = mock(OkHttpClient.class); - when(httpClient.newCall(any(Request.class))) - .thenAnswer( - new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - Call callMock = mock(Call.class); - return callMock; - } - }); - OkHttpClient.Builder clientBuilder = mock(OkHttpClient.Builder.class); - when(clientBuilder.build()).thenReturn(httpClient); - when(httpClient.newBuilder()).thenReturn(clientBuilder); - NetworkingModule networkingModule = new NetworkingModule(context, "", httpClient); - JavaOnlyMap body = new JavaOnlyMap(); body.putString("string", "test"); mockEvents(); - networkingModule.sendRequest( + mNetworkingModule.sendRequest( "POST", "http://somedomain/bar", 0, @@ -438,7 +336,7 @@ public class NetworkingModuleTest { /* withCredentials */ false); ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Request.class); - verify(httpClient).newCall(argumentCaptor.capture()); + verify(mHttpClient).newCall(argumentCaptor.capture()); Buffer contentBuffer = new Buffer(); argumentCaptor.getValue().body().writeTo(contentBuffer); @@ -467,22 +365,7 @@ public class NetworkingModuleTest { formData.pushMap(bodyPart); body.putArray("formData", formData); - OkHttpClient httpClient = mock(OkHttpClient.class); - when(httpClient.newCall(any(Request.class))) - .thenAnswer( - new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - Call callMock = mock(Call.class); - return callMock; - } - }); - OkHttpClient.Builder clientBuilder = mock(OkHttpClient.Builder.class); - when(clientBuilder.build()).thenReturn(httpClient); - when(httpClient.newBuilder()).thenReturn(clientBuilder); - NetworkingModule networkingModule = - new NetworkingModule(mock(ReactApplicationContext.class), "", httpClient); - networkingModule.sendRequest( + mNetworkingModule.sendRequest( "POST", "http://someurl/uploadFoo", 0, @@ -495,7 +378,7 @@ public class NetworkingModuleTest { // verify url, method, headers ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Request.class); - verify(httpClient).newCall(argumentCaptor.capture()); + verify(mHttpClient).newCall(argumentCaptor.capture()); assertThat(argumentCaptor.getValue().url().toString()).isEqualTo("http://someurl/uploadFoo"); assertThat(argumentCaptor.getValue().method()).isEqualTo("POST"); assertThat(argumentCaptor.getValue().body().contentType().type()) @@ -532,22 +415,7 @@ public class NetworkingModuleTest { formData.pushMap(bodyPart); body.putArray("formData", formData); - OkHttpClient httpClient = mock(OkHttpClient.class); - when(httpClient.newCall(any(Request.class))) - .thenAnswer( - new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - Call callMock = mock(Call.class); - return callMock; - } - }); - OkHttpClient.Builder clientBuilder = mock(OkHttpClient.Builder.class); - when(clientBuilder.build()).thenReturn(httpClient); - when(httpClient.newBuilder()).thenReturn(clientBuilder); - NetworkingModule networkingModule = - new NetworkingModule(mock(ReactApplicationContext.class), "", httpClient); - networkingModule.sendRequest( + mNetworkingModule.sendRequest( "POST", "http://someurl/uploadFoo", 0, @@ -560,7 +428,7 @@ public class NetworkingModuleTest { // verify url, method, headers ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Request.class); - verify(httpClient).newCall(argumentCaptor.capture()); + verify(mHttpClient).newCall(argumentCaptor.capture()); assertThat(argumentCaptor.getValue().url().toString()).isEqualTo("http://someurl/uploadFoo"); assertThat(argumentCaptor.getValue().method()).isEqualTo("POST"); assertThat(argumentCaptor.getValue().body().contentType().type()) @@ -638,23 +506,7 @@ public class NetworkingModuleTest { JavaOnlyArray.of("content-disposition", "filename=photo.jpg")))); formData.pushMap(imageBodyPart); - OkHttpClient httpClient = mock(OkHttpClient.class); - when(httpClient.newCall(any(Request.class))) - .thenAnswer( - new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - Call callMock = mock(Call.class); - return callMock; - } - }); - OkHttpClient.Builder clientBuilder = mock(OkHttpClient.Builder.class); - when(clientBuilder.build()).thenReturn(httpClient); - when(httpClient.newBuilder()).thenReturn(clientBuilder); - - NetworkingModule networkingModule = - new NetworkingModule(mock(ReactApplicationContext.class), "", httpClient); - networkingModule.sendRequest( + mNetworkingModule.sendRequest( "POST", "http://someurl/uploadFoo", 0, @@ -695,15 +547,13 @@ public class NetworkingModuleTest { @Test public void testCancelAllCallsOnCatalystInstanceDestroy() throws Exception { PowerMockito.mockStatic(OkHttpCallUtil.class); - OkHttpClient httpClient = mock(OkHttpClient.class); final int requests = 3; final Call[] calls = new Call[requests]; for (int idx = 0; idx < requests; idx++) { calls[idx] = mock(Call.class); } - when(httpClient.cookieJar()).thenReturn(mock(CookieJarContainer.class)); - when(httpClient.newCall(any(Request.class))) + when(mHttpClient.newCall(any(Request.class))) .thenAnswer( new Answer() { @Override @@ -712,15 +562,10 @@ public class NetworkingModuleTest { return calls[(Integer) request.tag() - 1]; } }); - OkHttpClient.Builder clientBuilder = mock(OkHttpClient.Builder.class); - when(clientBuilder.build()).thenReturn(httpClient); - when(httpClient.newBuilder()).thenReturn(clientBuilder); - NetworkingModule networkingModule = - new NetworkingModule(mock(ReactApplicationContext.class), "", httpClient); - networkingModule.initialize(); + mNetworkingModule.initialize(); for (int idx = 0; idx < requests; idx++) { - networkingModule.sendRequest( + mNetworkingModule.sendRequest( "GET", "http://somedomain/foo", idx + 1, @@ -731,9 +576,9 @@ public class NetworkingModuleTest { /* timeout */ 0, /* withCredentials */ false); } - verify(httpClient, times(3)).newCall(any(Request.class)); + verify(mHttpClient, times(3)).newCall(any(Request.class)); - networkingModule.onCatalystInstanceDestroy(); + mNetworkingModule.onCatalystInstanceDestroy(); PowerMockito.verifyStatic(times(3)); ArgumentCaptor clientArguments = ArgumentCaptor.forClass(OkHttpClient.class); ArgumentCaptor requestIdArguments = ArgumentCaptor.forClass(Integer.class); @@ -748,15 +593,13 @@ public class NetworkingModuleTest { @Test public void testCancelSomeCallsOnCatalystInstanceDestroy() throws Exception { PowerMockito.mockStatic(OkHttpCallUtil.class); - OkHttpClient httpClient = mock(OkHttpClient.class); final int requests = 3; final Call[] calls = new Call[requests]; for (int idx = 0; idx < requests; idx++) { calls[idx] = mock(Call.class); } - when(httpClient.cookieJar()).thenReturn(mock(CookieJarContainer.class)); - when(httpClient.newCall(any(Request.class))) + when(mHttpClient.newCall(any(Request.class))) .thenAnswer( new Answer() { @Override @@ -765,14 +608,9 @@ public class NetworkingModuleTest { return calls[(Integer) request.tag() - 1]; } }); - OkHttpClient.Builder clientBuilder = mock(OkHttpClient.Builder.class); - when(clientBuilder.build()).thenReturn(httpClient); - when(httpClient.newBuilder()).thenReturn(clientBuilder); - NetworkingModule networkingModule = - new NetworkingModule(mock(ReactApplicationContext.class), "", httpClient); for (int idx = 0; idx < requests; idx++) { - networkingModule.sendRequest( + mNetworkingModule.sendRequest( "GET", "http://somedomain/foo", idx + 1, @@ -783,9 +621,9 @@ public class NetworkingModuleTest { /* timeout */ 0, /* withCredentials */ false); } - verify(httpClient, times(3)).newCall(any(Request.class)); + verify(mHttpClient, times(3)).newCall(any(Request.class)); - networkingModule.abortRequest(requests); + mNetworkingModule.abortRequest(requests); PowerMockito.verifyStatic(times(1)); ArgumentCaptor clientArguments = ArgumentCaptor.forClass(OkHttpClient.class); ArgumentCaptor requestIdArguments = ArgumentCaptor.forClass(Integer.class); @@ -796,7 +634,7 @@ public class NetworkingModuleTest { // verifyStatic actually does not clear all calls so far, so we have to check for all of them. // If `cancelTag` would've been called again for the aborted call, we would have had // `requests + 1` calls. - networkingModule.onCatalystInstanceDestroy(); + mNetworkingModule.onCatalystInstanceDestroy(); PowerMockito.verifyStatic(times(requests)); clientArguments = ArgumentCaptor.forClass(OkHttpClient.class); requestIdArguments = ArgumentCaptor.forClass(Integer.class); diff --git a/ReactAndroid/src/test/java/com/facebook/react/modules/timing/TimingModuleTest.java b/ReactAndroid/src/test/java/com/facebook/react/modules/timing/TimingModuleTest.java index c6285d6152..1656a6a23a 100644 --- a/ReactAndroid/src/test/java/com/facebook/react/modules/timing/TimingModuleTest.java +++ b/ReactAndroid/src/test/java/com/facebook/react/modules/timing/TimingModuleTest.java @@ -74,6 +74,7 @@ public class TimingModuleTest { CatalystInstance reactInstance = mock(CatalystInstance.class); ReactApplicationContext reactContext = mock(ReactApplicationContext.class); when(reactContext.getCatalystInstance()).thenReturn(reactInstance); + when(reactContext.hasActiveCatalystInstance()).thenReturn(true); mCurrentTimeNs = 0; mPostFrameCallbackHandler = new PostFrameCallbackHandler();