diff --git a/ReactAndroid/src/test/java/com/facebook/react/devsupport/BUCK b/ReactAndroid/src/test/java/com/facebook/react/devsupport/BUCK new file mode 100644 index 000000000..80a647901 --- /dev/null +++ b/ReactAndroid/src/test/java/com/facebook/react/devsupport/BUCK @@ -0,0 +1,31 @@ +include_defs('//ReactAndroid/DEFS') + +robolectric3_test( + name = 'devsupport', + # Please change the contact to the oncall of your team + contacts = ['oncall+fbandroid_sheriff@xmail.facebook.com'], + srcs = glob(['**/*.java']), + deps = [ + react_native_target('java/com/facebook/react/devsupport:devsupport'), + react_native_target('java/com/facebook/react/common:common'), + react_native_target('java/com/facebook/react/bridge:bridge'), + react_native_target('java/com/facebook/react:react'), + + react_native_tests_target('java/com/facebook/react/bridge:testhelpers'), + react_native_dep('third-party/java/okhttp:okhttp3'), + react_native_dep('third-party/java/okhttp:okhttp3-ws'), + react_native_dep('libraries/fbcore/src/test/java/com/facebook/powermock:powermock'), + react_native_dep('third-party/java/fest:fest'), + react_native_dep('third-party/java/jsr-305:jsr-305'), + react_native_dep('third-party/java/junit:junit'), + react_native_dep('third-party/java/mockito:mockito'), + react_native_dep('third-party/java/robolectric3/robolectric:robolectric'), + ], + visibility = [ + 'PUBLIC' + ], +) + +project_config( + test_target = ':devsupport', +) diff --git a/ReactAndroid/src/test/java/com/facebook/react/devsupport/JSDebuggerWebSocketClientTest.java b/ReactAndroid/src/test/java/com/facebook/react/devsupport/JSDebuggerWebSocketClientTest.java new file mode 100644 index 000000000..1f25ee634 --- /dev/null +++ b/ReactAndroid/src/test/java/com/facebook/react/devsupport/JSDebuggerWebSocketClientTest.java @@ -0,0 +1,111 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.facebook.react.devsupport; + +import com.facebook.react.common.JavascriptException; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.rule.PowerMockRule; +import org.robolectric.RobolectricTestRunner; + +import java.util.HashMap; + +import okhttp3.ResponseBody; +import okhttp3.ws.WebSocket; + +import static org.mockito.Mockito.*; + +@PrepareForTest({ JSDebuggerWebSocketClient.class }) +@RunWith(RobolectricTestRunner.class) +@PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*"}) +public class JSDebuggerWebSocketClientTest { + + @Rule + public PowerMockRule rule = new PowerMockRule(); + + @Test + public void test_prepareJSRuntime_ShouldSendCorrectMessage() throws Exception { + final JSDebuggerWebSocketClient.JSDebuggerCallback cb = + PowerMockito.mock(JSDebuggerWebSocketClient.JSDebuggerCallback.class); + + JSDebuggerWebSocketClient client = PowerMockito.spy(new JSDebuggerWebSocketClient()); + client.prepareJSRuntime(cb); + PowerMockito.verifyPrivate(client).invoke("sendMessage", 0, + "{\"id\":0,\"method\":\"prepareJSRuntime\"}"); + } + + @Test + public void test_loadApplicationScript_ShouldSendCorrectMessage() throws Exception { + final JSDebuggerWebSocketClient.JSDebuggerCallback cb = + PowerMockito.mock(JSDebuggerWebSocketClient.JSDebuggerCallback.class); + + JSDebuggerWebSocketClient client = PowerMockito.spy(new JSDebuggerWebSocketClient()); + HashMap injectedObjects = new HashMap<>(); + injectedObjects.put("key1", "value1"); + injectedObjects.put("key2", "value2"); + + client.loadApplicationScript("http://localhost:8080/index.js", injectedObjects, cb); + PowerMockito.verifyPrivate(client).invoke("sendMessage", 0, + "{\"id\":0,\"method\":\"executeApplicationScript\",\"url\":\"http://localhost:8080/index.js\"" + + ",\"inject\":{\"key1\":\"value1\",\"key2\":\"value2\"}}"); + } + + @Test + public void test_executeJSCall_ShouldSendCorrectMessage() throws Exception { + final JSDebuggerWebSocketClient.JSDebuggerCallback cb = + PowerMockito.mock(JSDebuggerWebSocketClient.JSDebuggerCallback.class); + + JSDebuggerWebSocketClient client = PowerMockito.spy(new JSDebuggerWebSocketClient()); + + client.executeJSCall("foo", "[1,2,3]", cb); + PowerMockito.verifyPrivate(client).invoke("sendMessage", 0, + "{\"id\":0,\"method\":\"foo\",\"arguments\":[1,2,3]}"); + } + + @Test + public void test_onMessage_WithInvalidContentType_ShouldNotTriggerCallbacks() throws Exception { + JSDebuggerWebSocketClient client = PowerMockito.spy(new JSDebuggerWebSocketClient()); + + client.onMessage(ResponseBody.create(WebSocket.BINARY, "{\"replyID\":0, \"result\":\"OK\"}")); + PowerMockito.verifyPrivate(client, never()).invoke("triggerRequestSuccess", anyInt(), anyString()); + PowerMockito.verifyPrivate(client, never()).invoke("triggerRequestFailure", anyInt(), any()); + } + + @Test + public void test_onMessage_WithoutReplyId_ShouldNotTriggerCallbacks() throws Exception { + JSDebuggerWebSocketClient client = PowerMockito.spy(new JSDebuggerWebSocketClient()); + + client.onMessage(ResponseBody.create(WebSocket.TEXT, "{\"result\":\"OK\"}")); + PowerMockito.verifyPrivate(client, never()).invoke("triggerRequestSuccess", anyInt(), anyString()); + PowerMockito.verifyPrivate(client, never()).invoke("triggerRequestFailure", anyInt(), any()); + } + + @Test + public void test_onMessage_WithResult_ShouldTriggerRequestSuccess() throws Exception { + JSDebuggerWebSocketClient client = PowerMockito.spy(new JSDebuggerWebSocketClient()); + + client.onMessage(ResponseBody.create(WebSocket.TEXT, "{\"replyID\":0, \"result\":\"OK\"}")); + PowerMockito.verifyPrivate(client).invoke("triggerRequestSuccess", 0, "OK"); + PowerMockito.verifyPrivate(client, never()).invoke("triggerRequestFailure", anyInt(), any()); + } + + @Test + public void test_onMessage_WithError_ShouldCallAbort() throws Exception { + JSDebuggerWebSocketClient client = PowerMockito.spy(new JSDebuggerWebSocketClient()); + + client.onMessage(ResponseBody.create(WebSocket.TEXT, "{\"replyID\":0, \"error\":\"BOOM\"}")); + PowerMockito.verifyPrivate(client).invoke("abort", eq("BOOM"), isA(JavascriptException.class)); + } +} diff --git a/ReactAndroid/src/test/java/com/facebook/react/devsupport/JSPackagerWebSocketClientTest.java b/ReactAndroid/src/test/java/com/facebook/react/devsupport/JSPackagerWebSocketClientTest.java new file mode 100644 index 000000000..f137ba7c5 --- /dev/null +++ b/ReactAndroid/src/test/java/com/facebook/react/devsupport/JSPackagerWebSocketClientTest.java @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.facebook.react.devsupport; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.ParameterizedRobolectricTestRunner; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; + +import okhttp3.MediaType; +import okhttp3.ResponseBody; +import okhttp3.ws.WebSocket; + +import static org.mockito.Mockito.*; +import org.robolectric.RobolectricTestRunner; + +@RunWith(RobolectricTestRunner.class) +public class JSPackagerWebSocketClientTest { + + @Test + public void test_onMessage_ShouldTriggerCallback() throws IOException { + final JSPackagerWebSocketClient.JSPackagerCallback callback = + mock(JSPackagerWebSocketClient.JSPackagerCallback.class); + final JSPackagerWebSocketClient client = new JSPackagerWebSocketClient("ws://not_needed", callback); + client.onMessage(ResponseBody.create(WebSocket.TEXT, + "{\"version\": 1, \"target\": \"targetValue\", \"action\": \"actionValue\"}")); + verify(callback).onMessage("targetValue", "actionValue"); + } + + @Test + public void test_onMessage_WithInvalidContentType_ShouldNotTriggerCallback() throws IOException { + final JSPackagerWebSocketClient.JSPackagerCallback callback = + mock(JSPackagerWebSocketClient.JSPackagerCallback.class); + final JSPackagerWebSocketClient client = new JSPackagerWebSocketClient("ws://not_needed", callback); + client.onMessage(ResponseBody.create(WebSocket.BINARY, + "{\"version\": 1, \"target\": \"targetValue\", \"action\": \"actionValue\"}")); + verify(callback, never()).onMessage(anyString(), anyString()); + } + + @Test + public void test_onMessage_WithoutTarget_ShouldNotTriggerCallback() throws IOException { + final JSPackagerWebSocketClient.JSPackagerCallback callback = + mock(JSPackagerWebSocketClient.JSPackagerCallback.class); + final JSPackagerWebSocketClient client = new JSPackagerWebSocketClient("ws://not_needed", callback); + client.onMessage(ResponseBody.create(WebSocket.TEXT, + "{\"version\": 1, \"action\": \"actionValue\"}")); + verify(callback, never()).onMessage(anyString(), anyString()); + } + + @Test + public void test_onMessage_WithoutAction_ShouldNotTriggerCallback() throws IOException { + final JSPackagerWebSocketClient.JSPackagerCallback callback = + mock(JSPackagerWebSocketClient.JSPackagerCallback.class); + final JSPackagerWebSocketClient client = new JSPackagerWebSocketClient("ws://not_needed", callback); + client.onMessage(ResponseBody.create(WebSocket.TEXT, + "{\"version\": 1, \"target\": \"targetValue\"}")); + verify(callback, never()).onMessage(anyString(), anyString()); + } + + @Test + public void test_onMessage_WrongVersion_ShouldNotTriggerCallback() throws IOException { + final JSPackagerWebSocketClient.JSPackagerCallback callback = + mock(JSPackagerWebSocketClient.JSPackagerCallback.class); + final JSPackagerWebSocketClient client = new JSPackagerWebSocketClient("ws://not_needed", callback); + client.onMessage(ResponseBody.create(WebSocket.TEXT, + "{\"version\": 2, \"target\": \"targetValue\", \"action\": \"actionValue\"}")); + verify(callback, never()).onMessage(anyString(), anyString()); + } +}