mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
refactor: convert NetworkingModuleTest to kotlin (#41792)
Summary: Migrated `NetworkingModuleTest` to kotlin (part of https://github.com/facebook/react-native/issues/38825) ## Changelog: [Android] [CHANGED] - NetworkingModuleTest.java -> NetworkingModuleTest.kt Pull Request resolved: https://github.com/facebook/react-native/pull/41792 Test Plan: `./gradlew :packages:react-native:ReactAndroid:test` Reviewed By: cortinico Differential Revision: D51847402 Pulled By: rshest fbshipit-source-id: 7a1938c575a7e5b22b6ff578e1f8d26b600f2c27
This commit is contained in:
committed by
Facebook GitHub Bot
parent
bdcc9d0937
commit
852f2b1758
-635
@@ -1,635 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.modules.network;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
import static org.mockito.Mockito.times;
|
||||
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;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.common.network.OkHttpCallUtil;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Headers;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.MultipartBody;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okio.Buffer;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link NetworkingModule}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Ignore("Ignored due to unsupported mocking mechanism with JDK 18")
|
||||
public class NetworkingModuleTest {
|
||||
private NetworkingModule mNetworkingModule;
|
||||
private OkHttpClient mHttpClient;
|
||||
private ReactApplicationContext mContext;
|
||||
|
||||
private MockedStatic<Arguments> arguments;
|
||||
|
||||
@Before
|
||||
public void prepareModules() {
|
||||
mHttpClient = mock(OkHttpClient.class);
|
||||
when(mHttpClient.cookieJar()).thenReturn(mock(CookieJarContainer.class));
|
||||
when(mHttpClient.newCall(any(Request.class)))
|
||||
.thenAnswer(
|
||||
invocation -> {
|
||||
Call callMock = mock(Call.class);
|
||||
return callMock;
|
||||
});
|
||||
OkHttpClient.Builder clientBuilder = mock(OkHttpClient.Builder.class);
|
||||
when(clientBuilder.build()).thenReturn(mHttpClient);
|
||||
when(mHttpClient.newBuilder()).thenReturn(clientBuilder);
|
||||
|
||||
CatalystInstance reactInstance = mock(CatalystInstance.class);
|
||||
|
||||
mContext = mock(ReactApplicationContext.class);
|
||||
when(mContext.getCatalystInstance()).thenReturn(reactInstance);
|
||||
when(mContext.hasActiveReactInstance()).thenReturn(true);
|
||||
mNetworkingModule = new NetworkingModule(mContext, "", mHttpClient);
|
||||
|
||||
arguments = mockStatic(Arguments.class);
|
||||
arguments.when(Arguments::createArray).thenAnswer(invocation -> new JavaOnlyArray());
|
||||
arguments.when(Arguments::createMap).thenAnswer(invocation -> new JavaOnlyMap());
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
arguments.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetWithoutHeaders() throws Exception {
|
||||
mNetworkingModule.sendRequest(
|
||||
"GET",
|
||||
"http://somedomain/foo",
|
||||
/* requestId */ 0,
|
||||
/* headers */ JavaOnlyArray.of(),
|
||||
/* body */ null,
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
/* timeout */ 0,
|
||||
/* withCredentials */ false);
|
||||
|
||||
ArgumentCaptor<Request> argumentCaptor = ArgumentCaptor.forClass(Request.class);
|
||||
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);
|
||||
assertThat(argumentCaptor.getValue().method()).isEqualTo("GET");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailGetWithInvalidHeadersStruct() throws Exception {
|
||||
List<JavaOnlyArray> invalidHeaders = Arrays.asList(JavaOnlyArray.of("foo"));
|
||||
|
||||
mNetworkingModule.sendRequest(
|
||||
"GET",
|
||||
"http://somedoman/foo",
|
||||
/* requestId */ 0,
|
||||
/* headers */ JavaOnlyArray.from(invalidHeaders),
|
||||
/* body */ null,
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
/* timeout */ 0,
|
||||
/* withCredentials */ false);
|
||||
|
||||
verifyErrorEmit(mContext, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailPostWithoutContentType() throws Exception {
|
||||
JavaOnlyMap body = new JavaOnlyMap();
|
||||
body.putString("string", "This is request body");
|
||||
|
||||
mNetworkingModule.sendRequest(
|
||||
"POST",
|
||||
"http://somedomain/bar",
|
||||
0,
|
||||
JavaOnlyArray.of(),
|
||||
body,
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
/* timeout */ 0,
|
||||
/* withCredentials */ false);
|
||||
|
||||
verifyErrorEmit(mContext, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailInvalidUrl() throws Exception {
|
||||
mNetworkingModule.sendRequest(
|
||||
"GET",
|
||||
"aaa",
|
||||
/* requestId */ 0,
|
||||
/* headers */ JavaOnlyArray.of(),
|
||||
/* body */ null,
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
/* timeout */ 0,
|
||||
/* withCredentials */ false);
|
||||
|
||||
verifyErrorEmit(mContext, 0);
|
||||
}
|
||||
|
||||
private static void verifyErrorEmit(ReactApplicationContext context, int requestId) {
|
||||
ArgumentCaptor<WritableArray> captor = ArgumentCaptor.forClass(WritableArray.class);
|
||||
verify(context).emitDeviceEvent(eq("didCompleteNetworkResponse"), captor.capture());
|
||||
|
||||
WritableArray array = captor.getValue();
|
||||
assertThat(array.getInt(0)).isEqualTo(requestId);
|
||||
assertThat(array.getString(1)).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccessfulPostRequest() throws Exception {
|
||||
JavaOnlyMap body = new JavaOnlyMap();
|
||||
body.putString("string", "This is request body");
|
||||
|
||||
mNetworkingModule.sendRequest(
|
||||
"POST",
|
||||
"http://somedomain/bar",
|
||||
0,
|
||||
JavaOnlyArray.of(JavaOnlyArray.of("Content-Type", "text/plain")),
|
||||
body,
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
/* timeout */ 0,
|
||||
/* withCredentials */ false);
|
||||
|
||||
ArgumentCaptor<Request> argumentCaptor = ArgumentCaptor.forClass(Request.class);
|
||||
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");
|
||||
assertThat(argumentCaptor.getValue().body().contentType().type()).isEqualTo("text");
|
||||
assertThat(argumentCaptor.getValue().body().contentType().subtype()).isEqualTo("plain");
|
||||
Buffer contentBuffer = new Buffer();
|
||||
argumentCaptor.getValue().body().writeTo(contentBuffer);
|
||||
assertThat(contentBuffer.readUtf8()).isEqualTo("This is request body");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHeaders() throws Exception {
|
||||
List<JavaOnlyArray> headers =
|
||||
Arrays.asList(
|
||||
JavaOnlyArray.of("Accept", "text/plain"),
|
||||
JavaOnlyArray.of("User-Agent", "React test agent/1.0"));
|
||||
|
||||
mNetworkingModule.sendRequest(
|
||||
"GET",
|
||||
"http://someurl/baz",
|
||||
0,
|
||||
JavaOnlyArray.from(headers),
|
||||
null,
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
/* timeout */ 0,
|
||||
/* withCredentials */ false);
|
||||
ArgumentCaptor<Request> argumentCaptor = ArgumentCaptor.forClass(Request.class);
|
||||
verify(mHttpClient).newCall(argumentCaptor.capture());
|
||||
Headers requestHeaders = argumentCaptor.getValue().headers();
|
||||
assertThat(requestHeaders.size()).isEqualTo(2);
|
||||
assertThat(requestHeaders.get("Accept")).isEqualTo("text/plain");
|
||||
assertThat(requestHeaders.get("User-Agent")).isEqualTo("React test agent/1.0");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostJsonContentTypeHeader() throws Exception {
|
||||
|
||||
JavaOnlyMap body = new JavaOnlyMap();
|
||||
body.putString("string", "{ \"key\": \"value\" }");
|
||||
|
||||
mNetworkingModule.sendRequest(
|
||||
"POST",
|
||||
"http://somedomain/bar",
|
||||
0,
|
||||
JavaOnlyArray.of(JavaOnlyArray.of("Content-Type", "application/json")),
|
||||
body,
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
/* timeout */ 0,
|
||||
/* withCredentials */ false);
|
||||
|
||||
ArgumentCaptor<Request> argumentCaptor = ArgumentCaptor.forClass(Request.class);
|
||||
verify(mHttpClient).newCall(argumentCaptor.capture());
|
||||
|
||||
// Verify okhttp does not append "charset=utf-8"
|
||||
assertThat(argumentCaptor.getValue().body().contentType().toString())
|
||||
.isEqualTo("application/json");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRespectsExistingCharacterSet() throws Exception {
|
||||
JavaOnlyMap body = new JavaOnlyMap();
|
||||
body.putString("string", "Friðjónsson");
|
||||
|
||||
mNetworkingModule.sendRequest(
|
||||
"POST",
|
||||
"http://somedomain/bar",
|
||||
0,
|
||||
JavaOnlyArray.of(JavaOnlyArray.of("Content-Type", "text/plain; charset=utf-16")),
|
||||
body,
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
/* timeout */ 0,
|
||||
/* withCredentials */ false);
|
||||
|
||||
ArgumentCaptor<Request> argumentCaptor = ArgumentCaptor.forClass(Request.class);
|
||||
verify(mHttpClient).newCall(argumentCaptor.capture());
|
||||
|
||||
Buffer contentBuffer = new Buffer();
|
||||
argumentCaptor.getValue().body().writeTo(contentBuffer);
|
||||
assertThat(contentBuffer.readString(StandardCharsets.UTF_16)).isEqualTo("Friðjónsson");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGracefullyRecoversFromInvalidContentType() throws Exception {
|
||||
JavaOnlyMap body = new JavaOnlyMap();
|
||||
body.putString("string", "test");
|
||||
|
||||
mNetworkingModule.sendRequest(
|
||||
"POST",
|
||||
"http://somedomain/bar",
|
||||
0,
|
||||
JavaOnlyArray.of(JavaOnlyArray.of("Content-Type", "invalid")),
|
||||
body,
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
/* timeout */ 0,
|
||||
/* withCredentials */ false);
|
||||
|
||||
ArgumentCaptor<Request> argumentCaptor = ArgumentCaptor.forClass(Request.class);
|
||||
verify(mHttpClient).newCall(argumentCaptor.capture());
|
||||
|
||||
Buffer contentBuffer = new Buffer();
|
||||
argumentCaptor.getValue().body().writeTo(contentBuffer);
|
||||
|
||||
assertThat(contentBuffer.readString(StandardCharsets.UTF_8)).isEqualTo("test");
|
||||
assertThat(argumentCaptor.getValue().header("Content-Type")).isEqualTo("invalid");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipartPostRequestSimple() throws Exception {
|
||||
MockedStatic<RequestBodyUtil> requestBodyUtil = mockStatic(RequestBodyUtil.class);
|
||||
requestBodyUtil
|
||||
.when(() -> RequestBodyUtil.getFileInputStream(any(ReactContext.class), any(String.class)))
|
||||
.thenReturn(mock(InputStream.class));
|
||||
requestBodyUtil
|
||||
.when(() -> RequestBodyUtil.create(any(MediaType.class), any(InputStream.class)))
|
||||
.thenReturn(mock(RequestBody.class));
|
||||
requestBodyUtil
|
||||
.when(
|
||||
() ->
|
||||
RequestBodyUtil.createProgressRequest(
|
||||
any(RequestBody.class), any(ProgressListener.class)))
|
||||
.thenCallRealMethod();
|
||||
|
||||
JavaOnlyMap body = new JavaOnlyMap();
|
||||
JavaOnlyArray formData = new JavaOnlyArray();
|
||||
JavaOnlyMap bodyPart = new JavaOnlyMap();
|
||||
bodyPart.putString("string", "value");
|
||||
bodyPart.putArray(
|
||||
"headers",
|
||||
JavaOnlyArray.from(Arrays.asList(JavaOnlyArray.of("content-disposition", "name"))));
|
||||
formData.pushMap(bodyPart);
|
||||
body.putArray("formData", formData);
|
||||
|
||||
mNetworkingModule.sendRequest(
|
||||
"POST",
|
||||
"http://someurl/uploadFoo",
|
||||
0,
|
||||
new JavaOnlyArray(),
|
||||
body,
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
/* timeout */ 0,
|
||||
/* withCredentials */ false);
|
||||
|
||||
// verify url, method, headers
|
||||
ArgumentCaptor<Request> argumentCaptor = ArgumentCaptor.forClass(Request.class);
|
||||
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())
|
||||
.isEqualTo(MultipartBody.FORM.type());
|
||||
assertThat(argumentCaptor.getValue().body().contentType().subtype())
|
||||
.isEqualTo(MultipartBody.FORM.subtype());
|
||||
Headers requestHeaders = argumentCaptor.getValue().headers();
|
||||
assertThat(requestHeaders.size()).isEqualTo(1);
|
||||
|
||||
requestBodyUtil.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipartPostRequestHeaders() throws Exception {
|
||||
MockedStatic<RequestBodyUtil> requestBodyUtil = mockStatic(RequestBodyUtil.class);
|
||||
requestBodyUtil
|
||||
.when(() -> RequestBodyUtil.getFileInputStream(any(ReactContext.class), any(String.class)))
|
||||
.thenReturn(mock(InputStream.class));
|
||||
requestBodyUtil
|
||||
.when(() -> RequestBodyUtil.create(any(MediaType.class), any(InputStream.class)))
|
||||
.thenReturn(mock(RequestBody.class));
|
||||
requestBodyUtil
|
||||
.when(
|
||||
() ->
|
||||
RequestBodyUtil.createProgressRequest(
|
||||
any(RequestBody.class), any(ProgressListener.class)))
|
||||
.thenCallRealMethod();
|
||||
|
||||
List<JavaOnlyArray> headers =
|
||||
Arrays.asList(
|
||||
JavaOnlyArray.of("Accept", "text/plain"),
|
||||
JavaOnlyArray.of("User-Agent", "React test agent/1.0"),
|
||||
JavaOnlyArray.of("content-type", "multipart/form-data"));
|
||||
|
||||
JavaOnlyMap body = new JavaOnlyMap();
|
||||
JavaOnlyArray formData = new JavaOnlyArray();
|
||||
JavaOnlyMap bodyPart = new JavaOnlyMap();
|
||||
bodyPart.putString("string", "value");
|
||||
bodyPart.putArray(
|
||||
"headers",
|
||||
JavaOnlyArray.from(Arrays.asList(JavaOnlyArray.of("content-disposition", "name"))));
|
||||
formData.pushMap(bodyPart);
|
||||
body.putArray("formData", formData);
|
||||
|
||||
mNetworkingModule.sendRequest(
|
||||
"POST",
|
||||
"http://someurl/uploadFoo",
|
||||
0,
|
||||
JavaOnlyArray.from(headers),
|
||||
body,
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
/* timeout */ 0,
|
||||
/* withCredentials */ false);
|
||||
|
||||
// verify url, method, headers
|
||||
ArgumentCaptor<Request> argumentCaptor = ArgumentCaptor.forClass(Request.class);
|
||||
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())
|
||||
.isEqualTo(MultipartBody.FORM.type());
|
||||
assertThat(argumentCaptor.getValue().body().contentType().subtype())
|
||||
.isEqualTo(MultipartBody.FORM.subtype());
|
||||
Headers requestHeaders = argumentCaptor.getValue().headers();
|
||||
assertThat(requestHeaders.size()).isEqualTo(3);
|
||||
assertThat(requestHeaders.get("Accept")).isEqualTo("text/plain");
|
||||
assertThat(requestHeaders.get("User-Agent")).isEqualTo("React test agent/1.0");
|
||||
assertThat(requestHeaders.get("content-type")).isEqualTo("multipart/form-data");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipartPostRequestBody() throws Exception {
|
||||
InputStream inputStream = mock(InputStream.class);
|
||||
|
||||
MockedStatic<RequestBodyUtil> requestBodyUtil = mockStatic(RequestBodyUtil.class);
|
||||
requestBodyUtil
|
||||
.when(() -> RequestBodyUtil.getFileInputStream(any(ReactContext.class), any(String.class)))
|
||||
.thenReturn(mock(InputStream.class));
|
||||
requestBodyUtil
|
||||
.when(() -> RequestBodyUtil.create(any(MediaType.class), any(InputStream.class)))
|
||||
.thenCallRealMethod();
|
||||
requestBodyUtil
|
||||
.when(
|
||||
() ->
|
||||
RequestBodyUtil.createProgressRequest(
|
||||
any(RequestBody.class), any(ProgressListener.class)))
|
||||
.thenCallRealMethod();
|
||||
|
||||
when(inputStream.available()).thenReturn("imageUri".length());
|
||||
|
||||
final MultipartBody.Builder multipartBuilder = mock(MultipartBody.Builder.class);
|
||||
// TODO This PowerMock statement should be migrated to an equivalent for Mockito
|
||||
// once this test is unsuppressed.
|
||||
// whenNew(MultipartBody.Builder.class)
|
||||
// .withNoArguments()
|
||||
// .thenReturn(multipartBuilder);
|
||||
when(multipartBuilder.setType(any(MediaType.class)))
|
||||
.thenAnswer(
|
||||
new Answer<Object>() {
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
return multipartBuilder;
|
||||
}
|
||||
});
|
||||
when(multipartBuilder.addPart(any(Headers.class), any(RequestBody.class)))
|
||||
.thenAnswer(
|
||||
new Answer<Object>() {
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
return multipartBuilder;
|
||||
}
|
||||
});
|
||||
when(multipartBuilder.build())
|
||||
.thenAnswer(
|
||||
new Answer<Object>() {
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
return mock(MultipartBody.class);
|
||||
}
|
||||
});
|
||||
|
||||
List<JavaOnlyArray> headers =
|
||||
Arrays.asList(JavaOnlyArray.of("content-type", "multipart/form-data"));
|
||||
|
||||
JavaOnlyMap body = new JavaOnlyMap();
|
||||
JavaOnlyArray formData = new JavaOnlyArray();
|
||||
body.putArray("formData", formData);
|
||||
|
||||
JavaOnlyMap bodyPart = new JavaOnlyMap();
|
||||
bodyPart.putString("string", "locale");
|
||||
bodyPart.putArray(
|
||||
"headers",
|
||||
JavaOnlyArray.from(Arrays.asList(JavaOnlyArray.of("content-disposition", "user"))));
|
||||
formData.pushMap(bodyPart);
|
||||
|
||||
JavaOnlyMap imageBodyPart = new JavaOnlyMap();
|
||||
imageBodyPart.putString("uri", "imageUri");
|
||||
imageBodyPart.putArray(
|
||||
"headers",
|
||||
JavaOnlyArray.from(
|
||||
Arrays.asList(
|
||||
JavaOnlyArray.of("content-type", "image/jpg"),
|
||||
JavaOnlyArray.of(
|
||||
"content-disposition",
|
||||
"filename=\"测试photo.jpg\"; filename*=utf-8''%E6%B5%8B%E8%AF%95photo.jpg"))));
|
||||
formData.pushMap(imageBodyPart);
|
||||
|
||||
mNetworkingModule.sendRequest(
|
||||
"POST",
|
||||
"http://someurl/uploadFoo",
|
||||
0,
|
||||
JavaOnlyArray.from(headers),
|
||||
body,
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
/* timeout */ 0,
|
||||
/* withCredentials */ false);
|
||||
|
||||
// verify RequestBodyPart for image
|
||||
|
||||
// TODO This should be migrated to requestBodyUtil.verify();
|
||||
// PowerMockito.verifyStatic(RequestBodyUtil.class, times(1));
|
||||
RequestBodyUtil.getFileInputStream(any(ReactContext.class), eq("imageUri"));
|
||||
// TODO This should be migrated to requestBodyUtil.verify();
|
||||
// PowerMockito.verifyStatic(RequestBodyUtil.class, times(1));
|
||||
RequestBodyUtil.create(MediaType.parse("image/jpg"), inputStream);
|
||||
|
||||
// verify body
|
||||
verify(multipartBuilder).build();
|
||||
verify(multipartBuilder).setType(MultipartBody.FORM);
|
||||
ArgumentCaptor<Headers> headersArgumentCaptor = ArgumentCaptor.forClass(Headers.class);
|
||||
ArgumentCaptor<RequestBody> bodyArgumentCaptor = ArgumentCaptor.forClass(RequestBody.class);
|
||||
verify(multipartBuilder, times(2))
|
||||
.addPart(headersArgumentCaptor.capture(), bodyArgumentCaptor.capture());
|
||||
|
||||
List<Headers> bodyHeaders = headersArgumentCaptor.getAllValues();
|
||||
assertThat(bodyHeaders.size()).isEqualTo(2);
|
||||
List<RequestBody> bodyRequestBody = bodyArgumentCaptor.getAllValues();
|
||||
assertThat(bodyRequestBody.size()).isEqualTo(2);
|
||||
|
||||
assertThat(bodyHeaders.get(0).get("content-disposition")).isEqualTo("user");
|
||||
assertThat(bodyRequestBody.get(0).contentType()).isNull();
|
||||
assertThat(bodyRequestBody.get(0).contentLength()).isEqualTo("locale".getBytes().length);
|
||||
assertThat(bodyHeaders.get(1).get("content-disposition"))
|
||||
.isEqualTo("filename=\"测试photo.jpg\"; filename*=utf-8''%E6%B5%8B%E8%AF%95photo.jpg");
|
||||
assertThat(bodyRequestBody.get(1).contentType()).isEqualTo(MediaType.parse("image/jpg"));
|
||||
assertThat(bodyRequestBody.get(1).contentLength()).isEqualTo("imageUri".getBytes().length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancelAllCallsInvalidate() throws Exception {
|
||||
MockedStatic<OkHttpCallUtil> okHttpCallUtil = mockStatic(OkHttpCallUtil.class);
|
||||
final int requests = 3;
|
||||
final Call[] calls = new Call[requests];
|
||||
for (int idx = 0; idx < requests; idx++) {
|
||||
calls[idx] = mock(Call.class);
|
||||
}
|
||||
|
||||
when(mHttpClient.newCall(any(Request.class)))
|
||||
.thenAnswer(
|
||||
new Answer<Object>() {
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
Request request = (Request) invocation.getArguments()[0];
|
||||
return calls[(Integer) request.tag() - 1];
|
||||
}
|
||||
});
|
||||
mNetworkingModule.initialize();
|
||||
|
||||
for (int idx = 0; idx < requests; idx++) {
|
||||
mNetworkingModule.sendRequest(
|
||||
"GET",
|
||||
"http://somedomain/foo",
|
||||
idx + 1,
|
||||
JavaOnlyArray.of(),
|
||||
null,
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
/* timeout */ 0,
|
||||
/* withCredentials */ false);
|
||||
}
|
||||
verify(mHttpClient, times(3)).newCall(any(Request.class));
|
||||
|
||||
mNetworkingModule.invalidate();
|
||||
// TODO This should be migrated to okHttpCallUtil.verify();
|
||||
// PowerMockito.verifyStatic(OkHttpCallUtil.class, times(3));
|
||||
ArgumentCaptor<OkHttpClient> clientArguments = ArgumentCaptor.forClass(OkHttpClient.class);
|
||||
ArgumentCaptor<Integer> requestIdArguments = ArgumentCaptor.forClass(Integer.class);
|
||||
OkHttpCallUtil.cancelTag(clientArguments.capture(), requestIdArguments.capture());
|
||||
|
||||
assertThat(requestIdArguments.getAllValues().size()).isEqualTo(requests);
|
||||
for (int idx = 0; idx < requests; idx++) {
|
||||
assertThat(requestIdArguments.getAllValues().contains(idx + 1)).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancelSomeCallsInvalidate() throws Exception {
|
||||
MockedStatic<OkHttpCallUtil> okHttpCallUtil = mockStatic(OkHttpCallUtil.class);
|
||||
final int requests = 3;
|
||||
final Call[] calls = new Call[requests];
|
||||
for (int idx = 0; idx < requests; idx++) {
|
||||
calls[idx] = mock(Call.class);
|
||||
}
|
||||
|
||||
when(mHttpClient.newCall(any(Request.class)))
|
||||
.thenAnswer(
|
||||
new Answer<Object>() {
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
Request request = (Request) invocation.getArguments()[0];
|
||||
return calls[(Integer) request.tag() - 1];
|
||||
}
|
||||
});
|
||||
|
||||
for (int idx = 0; idx < requests; idx++) {
|
||||
mNetworkingModule.sendRequest(
|
||||
"GET",
|
||||
"http://somedomain/foo",
|
||||
idx + 1,
|
||||
JavaOnlyArray.of(),
|
||||
null,
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
/* timeout */ 0,
|
||||
/* withCredentials */ false);
|
||||
}
|
||||
verify(mHttpClient, times(3)).newCall(any(Request.class));
|
||||
|
||||
mNetworkingModule.abortRequest(requests);
|
||||
// TODO This should be migrated to okHttpCallUtil.verify();
|
||||
// PowerMockito.verifyStatic(OkHttpCallUtil.class, times(1));
|
||||
ArgumentCaptor<OkHttpClient> clientArguments = ArgumentCaptor.forClass(OkHttpClient.class);
|
||||
ArgumentCaptor<Integer> requestIdArguments = ArgumentCaptor.forClass(Integer.class);
|
||||
OkHttpCallUtil.cancelTag(clientArguments.capture(), requestIdArguments.capture());
|
||||
assertThat(requestIdArguments.getAllValues().size()).isEqualTo(1);
|
||||
assertThat(requestIdArguments.getAllValues().get(0)).isEqualTo(requests);
|
||||
|
||||
// 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.
|
||||
mNetworkingModule.invalidate();
|
||||
// TODO This should be migrated to okHttpCallUtil.verify();
|
||||
// PowerMockito.verifyStatic(OkHttpCallUtil.class, times(requests));
|
||||
clientArguments = ArgumentCaptor.forClass(OkHttpClient.class);
|
||||
requestIdArguments = ArgumentCaptor.forClass(Integer.class);
|
||||
OkHttpCallUtil.cancelTag(clientArguments.capture(), requestIdArguments.capture());
|
||||
assertThat(requestIdArguments.getAllValues().size()).isEqualTo(requests);
|
||||
for (int idx = 0; idx < requests; idx++) {
|
||||
assertThat(requestIdArguments.getAllValues().contains(idx + 1)).isTrue();
|
||||
}
|
||||
}
|
||||
}
|
||||
+599
@@ -0,0 +1,599 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.modules.network
|
||||
|
||||
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
|
||||
import com.facebook.react.bridge.ReactContext
|
||||
import com.facebook.react.bridge.WritableArray
|
||||
import com.facebook.react.bridge.WritableMap
|
||||
import com.facebook.react.common.network.OkHttpCallUtil
|
||||
import java.io.InputStream
|
||||
import java.nio.charset.StandardCharsets
|
||||
import okhttp3.Call
|
||||
import okhttp3.Headers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MultipartBody
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody
|
||||
import okio.Buffer
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentCaptor
|
||||
import org.mockito.ArgumentMatchers.any
|
||||
import org.mockito.ArgumentMatchers.eq
|
||||
import org.mockito.Captor
|
||||
import org.mockito.MockedStatic
|
||||
import org.mockito.Mockito.mock
|
||||
import org.mockito.Mockito.mockStatic
|
||||
import org.mockito.Mockito.times
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
|
||||
/**
|
||||
* Returns Mockito.any() as nullable type to avoid java.lang.IllegalStateException when null is
|
||||
* returned.
|
||||
*/
|
||||
private fun <T> anyOrNull(type: Class<T>): T = any(type)
|
||||
|
||||
/**
|
||||
* Returns ArgumentCaptor.capture() as nullable type to avoid java.lang.IllegalStateException when
|
||||
* null is returned.
|
||||
*/
|
||||
fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
class NetworkingModuleTest {
|
||||
private lateinit var networkingModule: NetworkingModule
|
||||
private lateinit var httpClient: OkHttpClient
|
||||
private lateinit var context: ReactApplicationContext
|
||||
private lateinit var arguments: MockedStatic<Arguments>
|
||||
private lateinit var requestBodyUtil: MockedStatic<RequestBodyUtil>
|
||||
|
||||
@Captor private lateinit var requestArgumentCaptor: ArgumentCaptor<Request>
|
||||
|
||||
@Before
|
||||
fun prepareModules() {
|
||||
httpClient = mock(OkHttpClient::class.java)
|
||||
whenever(httpClient.cookieJar()).thenReturn(mock(CookieJarContainer::class.java))
|
||||
whenever(httpClient.newCall(anyOrNull(Request::class.java))).thenAnswer {
|
||||
val callMock = mock(Call::class.java)
|
||||
callMock
|
||||
}
|
||||
|
||||
val clientBuilder = mock(OkHttpClient.Builder::class.java)
|
||||
whenever(clientBuilder.build()).thenReturn(httpClient)
|
||||
whenever(httpClient.newBuilder()).thenReturn(clientBuilder)
|
||||
|
||||
val reactInstance = mock(CatalystInstance::class.java)
|
||||
|
||||
context = mock(ReactApplicationContext::class.java)
|
||||
whenever(context.catalystInstance).thenReturn(reactInstance)
|
||||
whenever(context.hasActiveReactInstance()).thenReturn(true)
|
||||
|
||||
networkingModule = NetworkingModule(context, "", httpClient)
|
||||
|
||||
arguments = mockStatic(Arguments::class.java)
|
||||
arguments.`when`<WritableArray>(Arguments::createArray).thenAnswer { JavaOnlyArray() }
|
||||
arguments.`when`<WritableMap>(Arguments::createMap).thenAnswer { JavaOnlyMap() }
|
||||
|
||||
requestBodyUtil = mockStatic(RequestBodyUtil::class.java)
|
||||
requestBodyUtil
|
||||
.`when`<InputStream> {
|
||||
RequestBodyUtil.getFileInputStream(any(ReactContext::class.java), any(String::class.java))
|
||||
}
|
||||
.thenReturn(mock(InputStream::class.java))
|
||||
|
||||
requestBodyUtil
|
||||
.`when`<RequestBody> {
|
||||
RequestBodyUtil.create(any(MediaType::class.java), any(InputStream::class.java))
|
||||
}
|
||||
.thenReturn(mock(RequestBody::class.java))
|
||||
|
||||
requestBodyUtil
|
||||
.`when`<ProgressRequestBody> {
|
||||
RequestBodyUtil.createProgressRequest(
|
||||
any(RequestBody::class.java), any(ProgressListener::class.java))
|
||||
}
|
||||
.thenCallRealMethod()
|
||||
|
||||
requestArgumentCaptor = ArgumentCaptor.forClass(Request::class.java)
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
arguments.close()
|
||||
requestBodyUtil.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetWithoutHeaders() {
|
||||
networkingModule.sendRequest(
|
||||
"GET",
|
||||
"http://somedomain/foo",
|
||||
0.0, /* requestId */
|
||||
JavaOnlyArray.of(), /* headers */
|
||||
null, /* body */
|
||||
"text", /* responseType */
|
||||
true, /* useIncrementalUpdates*/
|
||||
0.0, /* timeout */
|
||||
false /* withCredentials */)
|
||||
|
||||
verify(httpClient).newCall(capture(requestArgumentCaptor))
|
||||
assertThat(requestArgumentCaptor.value.url().toString()).isEqualTo("http://somedomain/foo")
|
||||
// We set the User-Agent header by default
|
||||
assertThat(requestArgumentCaptor.value.headers().size()).isEqualTo(1)
|
||||
assertThat(requestArgumentCaptor.value.method()).isEqualTo("GET")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFailGetWithInvalidHeadersStruct() {
|
||||
val invalidHeaders = listOf(JavaOnlyArray.of("foo"))
|
||||
|
||||
networkingModule.sendRequest(
|
||||
"GET",
|
||||
"http://somedoman/foo",
|
||||
0.0, /* requestId */
|
||||
JavaOnlyArray.from(invalidHeaders), /* headers */
|
||||
null, /* body */
|
||||
"text", /* responseType */
|
||||
true, /* useIncrementalUpdates*/
|
||||
0.0, /* timeout */
|
||||
false /* withCredentials */)
|
||||
|
||||
verifyErrorEmit(context, 0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFailPostWithoutContentType() {
|
||||
val body = JavaOnlyMap()
|
||||
body.putString("string", "This is request body")
|
||||
|
||||
networkingModule.sendRequest(
|
||||
"POST",
|
||||
"http://somedomain/bar",
|
||||
0.0,
|
||||
JavaOnlyArray.of(),
|
||||
body,
|
||||
"text", /* responseType */
|
||||
true, /* useIncrementalUpdates*/
|
||||
0.0, /* timeout */
|
||||
false /* withCredentials */)
|
||||
|
||||
verifyErrorEmit(context, 0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFailInvalidUrl() {
|
||||
networkingModule.sendRequest(
|
||||
"GET",
|
||||
"aaa",
|
||||
0.0, /* requestId */
|
||||
JavaOnlyArray.of(), /* headers */
|
||||
null, /* body */
|
||||
"text", /* responseType */
|
||||
true, /* useIncrementalUpdates*/
|
||||
0.0, /* timeout */
|
||||
false /* withCredentials */)
|
||||
|
||||
verifyErrorEmit(context, 0)
|
||||
}
|
||||
|
||||
private fun verifyErrorEmit(context: ReactApplicationContext, requestId: Int) {
|
||||
val captor = ArgumentCaptor.forClass(WritableArray::class.java)
|
||||
verify(context).emitDeviceEvent(eq("didCompleteNetworkResponse"), captor.capture())
|
||||
|
||||
val array = captor.value
|
||||
assertThat(array.getInt(0)).isEqualTo(requestId)
|
||||
assertThat(array.getString(1)).isNotNull
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSuccessfulPostRequest() {
|
||||
val body = JavaOnlyMap()
|
||||
body.putString("string", "This is request body")
|
||||
|
||||
networkingModule.sendRequest(
|
||||
"POST",
|
||||
"http://somedomain/bar",
|
||||
0.0,
|
||||
JavaOnlyArray.of(JavaOnlyArray.of("Content-Type", "text/plain")),
|
||||
body,
|
||||
"text", /* responseType */
|
||||
true, /* useIncrementalUpdates*/
|
||||
0.0, /* timeout */
|
||||
false /* withCredentials */)
|
||||
|
||||
verify(httpClient).newCall(capture(requestArgumentCaptor))
|
||||
assertThat(requestArgumentCaptor.value.url().toString()).isEqualTo("http://somedomain/bar")
|
||||
assertThat(requestArgumentCaptor.value.headers().size()).isEqualTo(2)
|
||||
assertThat(requestArgumentCaptor.value.method()).isEqualTo("POST")
|
||||
assertThat(requestArgumentCaptor.value.body()!!.contentType()!!.type()).isEqualTo("text")
|
||||
assertThat(requestArgumentCaptor.value.body()!!.contentType()!!.subtype()).isEqualTo("plain")
|
||||
val contentBuffer = Buffer()
|
||||
requestArgumentCaptor.value.body()!!.writeTo(contentBuffer)
|
||||
assertThat(contentBuffer.readUtf8()).isEqualTo("This is request body")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testHeaders() {
|
||||
val headers =
|
||||
listOf(
|
||||
JavaOnlyArray.of("Accept", "text/plain"),
|
||||
JavaOnlyArray.of("User-Agent", "React test agent/1.0"))
|
||||
|
||||
networkingModule.sendRequest(
|
||||
"GET",
|
||||
"http://someurl/baz",
|
||||
0.0,
|
||||
JavaOnlyArray.from(headers),
|
||||
null,
|
||||
"text", /* responseType */
|
||||
true, /* useIncrementalUpdates*/
|
||||
0.0, /* timeout */
|
||||
false /* withCredentials */)
|
||||
|
||||
verify(httpClient).newCall(capture(requestArgumentCaptor))
|
||||
val requestHeaders = requestArgumentCaptor.value.headers()
|
||||
assertThat(requestHeaders.size()).isEqualTo(2)
|
||||
assertThat(requestHeaders["Accept"]).isEqualTo("text/plain")
|
||||
assertThat(requestHeaders["User-Agent"]).isEqualTo("React test agent/1.0")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPostJsonContentTypeHeader() {
|
||||
val body = JavaOnlyMap()
|
||||
body.putString("string", "{ \"key\": \"value\" }")
|
||||
|
||||
networkingModule.sendRequest(
|
||||
"POST",
|
||||
"http://somedomain/bar",
|
||||
0.0,
|
||||
JavaOnlyArray.of(JavaOnlyArray.of("Content-Type", "application/json")),
|
||||
body,
|
||||
"text", /* responseType */
|
||||
true, /* useIncrementalUpdates*/
|
||||
0.0, /* timeout */
|
||||
false /* withCredentials */)
|
||||
|
||||
verify(httpClient).newCall(capture(requestArgumentCaptor))
|
||||
|
||||
// Verify okhttp does not append "charset=utf-8"
|
||||
assertThat(requestArgumentCaptor.value.body()!!.contentType().toString())
|
||||
.isEqualTo("application/json")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRespectsExistingCharacterSet() {
|
||||
val testString = "Friðjónsson"
|
||||
|
||||
val body = JavaOnlyMap()
|
||||
body.putString("string", testString)
|
||||
|
||||
networkingModule.sendRequest(
|
||||
"POST",
|
||||
"http://somedomain/bar",
|
||||
0.0,
|
||||
JavaOnlyArray.of(JavaOnlyArray.of("Content-Type", "text/plain; charset=utf-16")),
|
||||
body,
|
||||
"text", /* responseType */
|
||||
true, /* useIncrementalUpdates*/
|
||||
0.0, /* timeout */
|
||||
false /* withCredentials */)
|
||||
|
||||
verify(httpClient).newCall(capture(requestArgumentCaptor))
|
||||
|
||||
val contentBuffer = Buffer()
|
||||
requestArgumentCaptor.value.body()!!.writeTo(contentBuffer)
|
||||
assertThat(contentBuffer.readString(StandardCharsets.UTF_16)).isEqualTo(testString)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGracefullyRecoversFromInvalidContentType() {
|
||||
val body = JavaOnlyMap()
|
||||
body.putString("string", "test")
|
||||
|
||||
networkingModule.sendRequest(
|
||||
"POST",
|
||||
"http://somedomain/bar",
|
||||
0.0,
|
||||
JavaOnlyArray.of(JavaOnlyArray.of("Content-Type", "invalid")),
|
||||
body,
|
||||
"text", /* responseType */
|
||||
true, /* useIncrementalUpdates*/
|
||||
0.0, /* timeout */
|
||||
false /* withCredentials */)
|
||||
|
||||
verify(httpClient).newCall(capture(requestArgumentCaptor))
|
||||
|
||||
val contentBuffer = Buffer()
|
||||
requestArgumentCaptor.value.body()!!.writeTo(contentBuffer)
|
||||
|
||||
assertThat(contentBuffer.readString(StandardCharsets.UTF_8)).isEqualTo("test")
|
||||
assertThat(requestArgumentCaptor.value.header("Content-Type")).isEqualTo("invalid")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMultipartPostRequestSimple() {
|
||||
val body = JavaOnlyMap()
|
||||
val formData = JavaOnlyArray()
|
||||
val bodyPart = JavaOnlyMap()
|
||||
bodyPart.putString("string", "value")
|
||||
bodyPart.putArray(
|
||||
"headers", JavaOnlyArray.from(listOf(JavaOnlyArray.of("content-disposition", "name"))))
|
||||
|
||||
formData.pushMap(bodyPart)
|
||||
body.putArray("formData", formData)
|
||||
|
||||
networkingModule.sendRequest(
|
||||
"POST",
|
||||
"http://someurl/uploadFoo",
|
||||
0.0,
|
||||
JavaOnlyArray(),
|
||||
body,
|
||||
"text", /* responseType */
|
||||
true, /* useIncrementalUpdates*/
|
||||
0.0, /* timeout */
|
||||
false /* withCredentials */)
|
||||
|
||||
// verify url, method, headers
|
||||
verify(httpClient).newCall(capture(requestArgumentCaptor))
|
||||
assertThat(requestArgumentCaptor.value.url().toString()).isEqualTo("http://someurl/uploadFoo")
|
||||
assertThat(requestArgumentCaptor.value.method()).isEqualTo("POST")
|
||||
assertThat(requestArgumentCaptor.value.body()!!.contentType()!!.type())
|
||||
.isEqualTo(MultipartBody.FORM.type())
|
||||
assertThat(requestArgumentCaptor.value.body()!!.contentType()!!.subtype())
|
||||
.isEqualTo(MultipartBody.FORM.subtype())
|
||||
|
||||
val requestHeaders = requestArgumentCaptor.value.headers()
|
||||
assertThat(requestHeaders.size()).isEqualTo(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMultipartPostRequestHeaders() {
|
||||
val headers =
|
||||
listOf(
|
||||
JavaOnlyArray.of("Accept", "text/plain"),
|
||||
JavaOnlyArray.of("User-Agent", "React test agent/1.0"),
|
||||
JavaOnlyArray.of("content-type", "multipart/form-data"))
|
||||
|
||||
val body = JavaOnlyMap()
|
||||
val formData = JavaOnlyArray()
|
||||
val bodyPart = JavaOnlyMap()
|
||||
bodyPart.putString("string", "value")
|
||||
bodyPart.putArray(
|
||||
"headers", JavaOnlyArray.from(listOf(JavaOnlyArray.of("content-disposition", "name"))))
|
||||
|
||||
formData.pushMap(bodyPart)
|
||||
body.putArray("formData", formData)
|
||||
|
||||
networkingModule.sendRequest(
|
||||
"POST",
|
||||
"http://someurl/uploadFoo",
|
||||
0.0,
|
||||
JavaOnlyArray.from(headers),
|
||||
body,
|
||||
"text", /* responseType */
|
||||
true, /* useIncrementalUpdates*/
|
||||
0.0, /* timeout */
|
||||
false /* withCredentials */)
|
||||
|
||||
// verify url, method, headers
|
||||
verify(httpClient).newCall(capture(requestArgumentCaptor))
|
||||
assertThat(requestArgumentCaptor.value.url().toString()).isEqualTo("http://someurl/uploadFoo")
|
||||
assertThat(requestArgumentCaptor.value.method()).isEqualTo("POST")
|
||||
assertThat(requestArgumentCaptor.value.body()!!.contentType()!!.type())
|
||||
.isEqualTo(MultipartBody.FORM.type())
|
||||
assertThat(requestArgumentCaptor.value.body()!!.contentType()!!.subtype())
|
||||
.isEqualTo(MultipartBody.FORM.subtype())
|
||||
|
||||
val requestHeaders = requestArgumentCaptor.value.headers()
|
||||
assertThat(requestHeaders.size()).isEqualTo(3)
|
||||
assertThat(requestHeaders["Accept"]).isEqualTo("text/plain")
|
||||
assertThat(requestHeaders["User-Agent"]).isEqualTo("React test agent/1.0")
|
||||
assertThat(requestHeaders["content-type"]).isEqualTo("multipart/form-data")
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("TODO: Fix me (T171890419)")
|
||||
fun testMultipartPostRequestBody() {
|
||||
val inputStream = mock(InputStream::class.java)
|
||||
whenever(inputStream.available()).thenReturn("imageUri".length)
|
||||
|
||||
val multipartBuilder = mock(MultipartBody.Builder::class.java)
|
||||
// TODO This PowerMock statement should be migrated to an equivalent for Mockito
|
||||
// once this test is unsuppressed.
|
||||
// whenNew(MultipartBody.Builder.class)
|
||||
// .withNoArguments()
|
||||
// .thenReturn(multipartBuilder);
|
||||
whenever(multipartBuilder.setType(anyOrNull(MediaType::class.java))).thenAnswer {
|
||||
multipartBuilder
|
||||
}
|
||||
whenever(multipartBuilder.addPart(any(Headers::class.java), anyOrNull(RequestBody::class.java)))
|
||||
.thenAnswer { multipartBuilder }
|
||||
|
||||
whenever(multipartBuilder.build()).thenAnswer { mock(MultipartBody::class.java) }
|
||||
|
||||
val headers = listOf(JavaOnlyArray.of("content-type", "multipart/form-data"))
|
||||
|
||||
val body = JavaOnlyMap()
|
||||
val formData = JavaOnlyArray()
|
||||
body.putArray("formData", formData)
|
||||
|
||||
val bodyPart = JavaOnlyMap()
|
||||
bodyPart.putString("string", "locale")
|
||||
bodyPart.putArray(
|
||||
"headers", JavaOnlyArray.from(listOf(JavaOnlyArray.of("content-disposition", "user"))))
|
||||
|
||||
formData.pushMap(bodyPart)
|
||||
|
||||
val imageBodyPart = JavaOnlyMap()
|
||||
imageBodyPart.putString("uri", "imageUri")
|
||||
imageBodyPart.putArray(
|
||||
"headers",
|
||||
JavaOnlyArray.from(
|
||||
listOf(
|
||||
JavaOnlyArray.of("content-type", "image/jpg"),
|
||||
JavaOnlyArray.of(
|
||||
"content-disposition",
|
||||
"filename=\"测试photo.jpg\"; filename*=utf-8''%E6%B5%8B%E8%AF%95photo.jpg"))))
|
||||
|
||||
formData.pushMap(imageBodyPart)
|
||||
|
||||
networkingModule.sendRequest(
|
||||
"POST",
|
||||
"http://someurl/uploadFoo",
|
||||
0.0,
|
||||
JavaOnlyArray.from(headers),
|
||||
body,
|
||||
"text", /* responseType */
|
||||
true, /* useIncrementalUpdates*/
|
||||
0.0, /* timeout */
|
||||
false /* withCredentials */)
|
||||
|
||||
// verify RequestBodyPart for image
|
||||
|
||||
// TODO This should be migrated to requestBodyUtil.verify();
|
||||
// PowerMockito.verifyStatic(RequestBodyUtil.class, times(1));
|
||||
RequestBodyUtil.getFileInputStream(any(ReactContext::class.java), eq("imageUri"))
|
||||
// TODO This should be migrated to requestBodyUtil.verify();
|
||||
// PowerMockito.verifyStatic(RequestBodyUtil.class, times(1));
|
||||
RequestBodyUtil.create(MediaType.parse("image/jpg"), inputStream)
|
||||
|
||||
// verify body
|
||||
// TODO fix it (now mock is not called)
|
||||
verify(multipartBuilder).build()
|
||||
verify(multipartBuilder).setType(MultipartBody.FORM)
|
||||
// TODO fix it (Captors are nulls)
|
||||
val headersArgumentCaptor = ArgumentCaptor.forClass(Headers::class.java)
|
||||
val bodyArgumentCaptor = ArgumentCaptor.forClass(RequestBody::class.java)
|
||||
verify(multipartBuilder, times(2))
|
||||
.addPart(capture(headersArgumentCaptor), capture(bodyArgumentCaptor))
|
||||
|
||||
val bodyHeaders = headersArgumentCaptor.allValues
|
||||
assertThat(bodyHeaders.size).isEqualTo(2)
|
||||
val bodyRequestBody = bodyArgumentCaptor.allValues
|
||||
assertThat(bodyRequestBody.size).isEqualTo(2)
|
||||
|
||||
assertThat(bodyHeaders[0]["content-disposition"]).isEqualTo("user")
|
||||
assertThat(bodyRequestBody[0].contentType()).isNull()
|
||||
assertThat(bodyRequestBody[0].contentLength()).isEqualTo("locale".toByteArray().size.toLong())
|
||||
|
||||
assertThat(bodyHeaders[1]["content-disposition"])
|
||||
.isEqualTo("filename=\"测试photo.jpg\"; filename*=utf-8''%E6%B5%8B%E8%AF%95photo.jpg")
|
||||
|
||||
assertThat<MediaType?>(bodyRequestBody[1].contentType()).isEqualTo(MediaType.parse("image/jpg"))
|
||||
assertThat(bodyRequestBody[1].contentLength()).isEqualTo("imageUri".toByteArray().size.toLong())
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("TODO: Fix me (T171890419)")
|
||||
fun testCancelAllCallsInvalidate() {
|
||||
val requests = 3
|
||||
val calls = arrayOfNulls<Call>(requests)
|
||||
for (idx in 0 until requests) {
|
||||
calls[idx] = mock(Call::class.java)
|
||||
}
|
||||
|
||||
whenever(httpClient.newCall(anyOrNull(Request::class.java))).thenAnswer { invocation ->
|
||||
val request = invocation.arguments[0] as Request
|
||||
calls[(request.tag() as Int?)!! - 1]
|
||||
}
|
||||
networkingModule.initialize()
|
||||
|
||||
for (idx in 0 until requests) {
|
||||
networkingModule.sendRequest(
|
||||
"GET",
|
||||
"http://somedomain/foo",
|
||||
(idx + 1).toDouble(),
|
||||
JavaOnlyArray.of(),
|
||||
null,
|
||||
"text", /* responseType */
|
||||
true, /* useIncrementalUpdates*/
|
||||
0.0, /* timeout */
|
||||
false /* withCredentials */)
|
||||
}
|
||||
|
||||
verify(httpClient, times(3)).newCall(anyOrNull(Request::class.java))
|
||||
|
||||
networkingModule.invalidate()
|
||||
// TODO This should be migrated to okHttpCallUtil.verify();
|
||||
// PowerMockito.verifyStatic(OkHttpCallUtil.class, times(3));
|
||||
val clientArguments = ArgumentCaptor.forClass(OkHttpClient::class.java)
|
||||
val requestIdArguments = ArgumentCaptor.forClass(Int::class.java)
|
||||
|
||||
OkHttpCallUtil.cancelTag(capture(clientArguments), capture(requestIdArguments))
|
||||
|
||||
assertThat(requestIdArguments.allValues.size).isEqualTo(requests)
|
||||
for (idx in 0 until requests) {
|
||||
assertThat(requestIdArguments.allValues.contains(idx + 1)).isTrue
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("TODO: Fix me (T171890419)")
|
||||
fun testCancelSomeCallsInvalidate() {
|
||||
val requests = 3
|
||||
val calls = arrayOfNulls<Call>(requests)
|
||||
for (idx in 0 until requests) {
|
||||
calls[idx] = mock(Call::class.java)
|
||||
}
|
||||
whenever(httpClient.newCall(anyOrNull(Request::class.java))).thenAnswer { invocation ->
|
||||
val request = invocation.arguments[0] as Request
|
||||
calls[(request.tag() as Int?)!! - 1]
|
||||
}
|
||||
|
||||
for (idx in 0 until requests) {
|
||||
networkingModule.sendRequest(
|
||||
"GET",
|
||||
"http://somedomain/foo",
|
||||
(idx + 1).toDouble(),
|
||||
JavaOnlyArray.of(),
|
||||
null,
|
||||
"text", /* responseType */
|
||||
true, /* useIncrementalUpdates*/
|
||||
0.0, /* timeout */
|
||||
false /* withCredentials */)
|
||||
}
|
||||
verify(httpClient, times(3)).newCall(anyOrNull(Request::class.java))
|
||||
|
||||
networkingModule.abortRequest(requests.toDouble())
|
||||
// TODO This should be migrated to okHttpCallUtil.verify();
|
||||
// PowerMockito.verifyStatic(OkHttpCallUtil.class, times(1));
|
||||
var clientArguments = ArgumentCaptor.forClass(OkHttpClient::class.java)
|
||||
var requestIdArguments = ArgumentCaptor.forClass(Int::class.java)
|
||||
OkHttpCallUtil.cancelTag(clientArguments.capture(), requestIdArguments.capture())
|
||||
println(requestIdArguments.allValues)
|
||||
assertThat(requestIdArguments.allValues.size).isEqualTo(1)
|
||||
assertThat(requestIdArguments.allValues[0]).isEqualTo(requests)
|
||||
|
||||
// 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.invalidate()
|
||||
// TODO This should be migrated to okHttpCallUtil.verify();
|
||||
// PowerMockito.verifyStatic(OkHttpCallUtil.class, times(requests));
|
||||
clientArguments = ArgumentCaptor.forClass(OkHttpClient::class.java)
|
||||
requestIdArguments = ArgumentCaptor.forClass(Int::class.java)
|
||||
OkHttpCallUtil.cancelTag(clientArguments.capture(), requestIdArguments.capture())
|
||||
assertThat(requestIdArguments.allValues.size).isEqualTo(requests)
|
||||
for (idx in 0 until requests) {
|
||||
assertThat(requestIdArguments.allValues.contains(idx + 1)).isTrue
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user