mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-23 20:01:01 +08:00
Add responseType as a concept to RCTNetworking, send binary data as base64
Summary: In preparation for Blob support (wherein binary XHR and WebSocket responses can be retained as native data blobs on the native side and JS receives a web-like opaque Blob object), this change makes RCTNetworking aware of the responseType that JS requests. A `xhr.responseType` of `''` or `'text'` translates to a native response type of `'text'`. A `xhr.responseType` of `arraybuffer` translates to a native response type of `base64`, as we currently lack an API to transmit TypedArrays directly to JS. This is analogous to how the WebSocket module already works, and it's a lot more versatile and much less brittle than converting a JS *string* back to a TypedArray, which is what's currently going on. Now that we don't always send text down to JS, JS consumers might still want to get progress updates about a binary download. This is what the `'progress'` event is designed for, so this change also implements that. This change also follows the XHR spec with regards to `xhr.response` and `xhr.responseText`: - if the response type is `'text'`, `xhr.responseText` can be peeked at by the JS consumer. It will be updated periodically as the download progresses, so long as there's either an `onreadystatechange` or `onprogress` handler on the XHR. - if the response type is not `'text'`, `xhr.responseText` can't be accessed and `xhr.response` remains `null` until the response is fully received. `'progress'` events containing response details (total bytes, downloaded so far) are dispatched if there's an `onprogress` handler. Once Blobs are landed, `xhr.responseType` of `'blob'` will correspond to the same native response type, which will cause RCTNetworking to only send a blob ID down to JS, which can then create a `Blob` object from that for consumers. Closes https://github.com/facebook/react-native/pull/8324 Reviewed By: javache Differential Revision: D3508822 Pulled By: davidaurelio fbshipit-source-id: 441b2d4d40265b6036559c3ccb9fa962999fa5df
This commit is contained in:
committed by
Facebook Github Bot 0
parent
c65eb4ef19
commit
08c375f828
@@ -83,6 +83,7 @@ public class NetworkRecordingModuleMock extends ReactContextBaseJavaModule {
|
||||
int requestId,
|
||||
ReadableArray headers,
|
||||
ReadableMap data,
|
||||
final String responseType,
|
||||
boolean incrementalUpdates,
|
||||
int timeout) {
|
||||
mLastRequestId = requestId;
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
package com.facebook.react.modules.network;
|
||||
|
||||
import android.util.Base64;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -34,6 +36,7 @@ import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEm
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.Headers;
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.JavaNetCookieJar;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.MultipartBody;
|
||||
@@ -157,6 +160,7 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
|
||||
final int requestId,
|
||||
ReadableArray headers,
|
||||
ReadableMap data,
|
||||
final String responseType,
|
||||
final boolean useIncrementalUpdates,
|
||||
int timeout) {
|
||||
Request.Builder requestBuilder = new Request.Builder().url(url);
|
||||
@@ -165,18 +169,54 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
|
||||
requestBuilder.tag(requestId);
|
||||
}
|
||||
|
||||
OkHttpClient client = mClient;
|
||||
final RCTDeviceEventEmitter eventEmitter = getEventEmitter(executorToken);
|
||||
OkHttpClient.Builder clientBuilder = mClient.newBuilder();
|
||||
|
||||
// If JS is listening for progress updates, install a ProgressResponseBody that intercepts the
|
||||
// response and counts bytes received.
|
||||
if (useIncrementalUpdates) {
|
||||
clientBuilder.addNetworkInterceptor(new Interceptor() {
|
||||
@Override
|
||||
public Response intercept(Interceptor.Chain chain) throws IOException {
|
||||
Response originalResponse = chain.proceed(chain.request());
|
||||
ProgressResponseBody responseBody = new ProgressResponseBody(
|
||||
originalResponse.body(),
|
||||
new ProgressListener() {
|
||||
long last = System.nanoTime();
|
||||
|
||||
@Override
|
||||
public void onProgress(long bytesWritten, long contentLength, boolean done) {
|
||||
long now = System.nanoTime();
|
||||
if (!done && !shouldDispatch(now, last)) {
|
||||
return;
|
||||
}
|
||||
if (responseType.equals("text")) {
|
||||
// For 'text' responses we continuously send response data with progress info to
|
||||
// JS below, so no need to do anything here.
|
||||
return;
|
||||
}
|
||||
ResponseUtil.onDataReceivedProgress(
|
||||
eventEmitter,
|
||||
requestId,
|
||||
bytesWritten,
|
||||
contentLength);
|
||||
last = now;
|
||||
}
|
||||
});
|
||||
return originalResponse.newBuilder().body(responseBody).build();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// If the current timeout does not equal the passed in timeout, we need to clone the existing
|
||||
// client and set the timeout explicitly on the clone. This is cheap as everything else is
|
||||
// shared under the hood.
|
||||
// See https://github.com/square/okhttp/wiki/Recipes#per-call-configuration for more information
|
||||
if (timeout != mClient.connectTimeoutMillis()) {
|
||||
client = mClient.newBuilder()
|
||||
.readTimeout(timeout, TimeUnit.MILLISECONDS)
|
||||
.build();
|
||||
clientBuilder.readTimeout(timeout, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
OkHttpClient client = clientBuilder.build();
|
||||
|
||||
final RCTDeviceEventEmitter eventEmitter = getEventEmitter(executorToken);
|
||||
Headers requestHeaders = extractHeaders(headers, data);
|
||||
if (requestHeaders == null) {
|
||||
ResponseUtil.onRequestError(eventEmitter, requestId, "Unrecognized headers format", null);
|
||||
@@ -247,11 +287,11 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
|
||||
method,
|
||||
RequestBodyUtil.createProgressRequest(
|
||||
multipartBuilder.build(),
|
||||
new ProgressRequestListener() {
|
||||
new ProgressListener() {
|
||||
long last = System.nanoTime();
|
||||
|
||||
@Override
|
||||
public void onRequestProgress(long bytesWritten, long contentLength, boolean done) {
|
||||
public void onProgress(long bytesWritten, long contentLength, boolean done) {
|
||||
long now = System.nanoTime();
|
||||
if (done || shouldDispatch(now, last)) {
|
||||
ResponseUtil.onDataSend(eventEmitter, requestId, bytesWritten, contentLength);
|
||||
@@ -292,13 +332,23 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
|
||||
|
||||
ResponseBody responseBody = response.body();
|
||||
try {
|
||||
if (useIncrementalUpdates) {
|
||||
// If JS wants progress updates during the download, and it requested a text response,
|
||||
// periodically send response data updates to JS.
|
||||
if (useIncrementalUpdates && responseType.equals("text")) {
|
||||
readWithProgress(eventEmitter, requestId, responseBody);
|
||||
ResponseUtil.onRequestSuccess(eventEmitter, requestId);
|
||||
} else {
|
||||
ResponseUtil.onDataReceived(eventEmitter, requestId, responseBody.string());
|
||||
ResponseUtil.onRequestSuccess(eventEmitter, requestId);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise send the data in one big chunk, in the format that JS requested.
|
||||
String responseString = "";
|
||||
if (responseType.equals("text")) {
|
||||
responseString = responseBody.string();
|
||||
} else if (responseType.equals("base64")) {
|
||||
responseString = Base64.encodeToString(responseBody.bytes(), Base64.NO_WRAP);
|
||||
}
|
||||
ResponseUtil.onDataReceived(eventEmitter, requestId, responseString);
|
||||
ResponseUtil.onRequestSuccess(eventEmitter, requestId);
|
||||
} catch (IOException e) {
|
||||
ResponseUtil.onRequestError(eventEmitter, requestId, e.getMessage(), e);
|
||||
}
|
||||
@@ -310,12 +360,27 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
|
||||
RCTDeviceEventEmitter eventEmitter,
|
||||
int requestId,
|
||||
ResponseBody responseBody) throws IOException {
|
||||
long totalBytesRead = -1;
|
||||
long contentLength = -1;
|
||||
try {
|
||||
ProgressResponseBody progressResponseBody = (ProgressResponseBody) responseBody;
|
||||
totalBytesRead = progressResponseBody.totalBytesRead();
|
||||
contentLength = progressResponseBody.contentLength();
|
||||
} catch (ClassCastException e) {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
Reader reader = responseBody.charStream();
|
||||
try {
|
||||
char[] buffer = new char[MAX_CHUNK_SIZE_BETWEEN_FLUSHES];
|
||||
int read;
|
||||
while ((read = reader.read(buffer)) != -1) {
|
||||
ResponseUtil.onDataReceived(eventEmitter, requestId, new String(buffer, 0, read));
|
||||
ResponseUtil.onIncrementalDataReceived(
|
||||
eventEmitter,
|
||||
requestId,
|
||||
new String(buffer, 0, read),
|
||||
totalBytesRead,
|
||||
contentLength);
|
||||
}
|
||||
} finally {
|
||||
reader.close();
|
||||
|
||||
@@ -6,10 +6,9 @@
|
||||
* 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.modules.network;
|
||||
|
||||
|
||||
public interface ProgressRequestListener {
|
||||
void onRequestProgress(long bytesWritten, long contentLength, boolean done);
|
||||
public interface ProgressListener {
|
||||
void onProgress(long bytesWritten, long contentLength, boolean done);
|
||||
}
|
||||
@@ -12,22 +12,19 @@ package com.facebook.react.modules.network;
|
||||
import java.io.IOException;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.internal.Util;
|
||||
import okio.BufferedSink;
|
||||
import okio.Buffer;
|
||||
import okio.Sink;
|
||||
import okio.ForwardingSink;
|
||||
import okio.ByteString;
|
||||
import okio.Okio;
|
||||
import okio.Source;
|
||||
|
||||
public class ProgressRequestBody extends RequestBody {
|
||||
|
||||
private final RequestBody mRequestBody;
|
||||
private final ProgressRequestListener mProgressListener;
|
||||
private final ProgressListener mProgressListener;
|
||||
private BufferedSink mBufferedSink;
|
||||
|
||||
public ProgressRequestBody(RequestBody requestBody, ProgressRequestListener progressListener) {
|
||||
public ProgressRequestBody(RequestBody requestBody, ProgressListener progressListener) {
|
||||
mRequestBody = requestBody;
|
||||
mProgressListener = progressListener;
|
||||
}
|
||||
@@ -63,7 +60,8 @@ public class ProgressRequestBody extends RequestBody {
|
||||
contentLength = contentLength();
|
||||
}
|
||||
bytesWritten += byteCount;
|
||||
mProgressListener.onRequestProgress(bytesWritten, contentLength, bytesWritten == contentLength);
|
||||
mProgressListener.onProgress(
|
||||
bytesWritten, contentLength, bytesWritten == contentLength);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
package com.facebook.react.modules.network;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.ResponseBody;
|
||||
import okio.Buffer;
|
||||
import okio.BufferedSource;
|
||||
import okio.ForwardingSource;
|
||||
import okio.Okio;
|
||||
import okio.Source;
|
||||
|
||||
public class ProgressResponseBody extends ResponseBody {
|
||||
|
||||
private final ResponseBody mResponseBody;
|
||||
private final ProgressListener mProgressListener;
|
||||
private @Nullable BufferedSource mBufferedSource;
|
||||
private long mTotalBytesRead;
|
||||
|
||||
public ProgressResponseBody(ResponseBody responseBody, ProgressListener progressListener) {
|
||||
this.mResponseBody = responseBody;
|
||||
this.mProgressListener = progressListener;
|
||||
mTotalBytesRead = 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MediaType contentType() {
|
||||
return mResponseBody.contentType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long contentLength() {
|
||||
return mResponseBody.contentLength();
|
||||
}
|
||||
|
||||
public long totalBytesRead() {
|
||||
return mTotalBytesRead;
|
||||
}
|
||||
|
||||
@Override public BufferedSource source() {
|
||||
if (mBufferedSource == null) {
|
||||
mBufferedSource = Okio.buffer(source(mResponseBody.source()));
|
||||
}
|
||||
return mBufferedSource;
|
||||
}
|
||||
|
||||
private Source source(Source source) {
|
||||
return new ForwardingSource(source) {
|
||||
@Override public long read(Buffer sink, long byteCount) throws IOException {
|
||||
long bytesRead = super.read(sink, byteCount);
|
||||
// read() returns the number of bytes read, or -1 if this source is exhausted.
|
||||
mTotalBytesRead += bytesRead != -1 ? bytesRead : 0;
|
||||
mProgressListener.onProgress(
|
||||
mTotalBytesRead, mResponseBody.contentLength(), bytesRead == -1);
|
||||
return bytesRead;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -117,7 +117,9 @@ import okio.Source;
|
||||
/**
|
||||
* Creates a ProgressRequestBody that can be used for showing uploading progress
|
||||
*/
|
||||
public static ProgressRequestBody createProgressRequest(RequestBody requestBody, ProgressRequestListener listener) {
|
||||
public static ProgressRequestBody createProgressRequest(
|
||||
RequestBody requestBody,
|
||||
ProgressListener listener) {
|
||||
return new ProgressRequestBody(requestBody, listener);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,34 @@ public class ResponseUtil {
|
||||
eventEmitter.emit("didSendNetworkData", args);
|
||||
}
|
||||
|
||||
public static void onIncrementalDataReceived(
|
||||
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);
|
||||
}
|
||||
|
||||
public static void onDataReceivedProgress(
|
||||
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);
|
||||
}
|
||||
|
||||
public static void onDataReceived(
|
||||
RCTDeviceEventEmitter eventEmitter,
|
||||
int requestId,
|
||||
|
||||
@@ -61,11 +61,12 @@ import static org.mockito.Mockito.when;
|
||||
Call.class,
|
||||
RequestBodyUtil.class,
|
||||
ProgressRequestBody.class,
|
||||
ProgressRequestListener.class,
|
||||
ProgressListener.class,
|
||||
MultipartBody.class,
|
||||
MultipartBody.Builder.class,
|
||||
NetworkingModule.class,
|
||||
OkHttpClient.class,
|
||||
OkHttpClient.Builder.class,
|
||||
OkHttpCallUtil.class})
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*"})
|
||||
@@ -84,6 +85,9 @@ public class NetworkingModuleTest {
|
||||
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);
|
||||
|
||||
@@ -91,11 +95,12 @@ public class NetworkingModuleTest {
|
||||
mock(ExecutorToken.class),
|
||||
"GET",
|
||||
"http://somedomain/foo",
|
||||
0,
|
||||
JavaOnlyArray.of(),
|
||||
null,
|
||||
true,
|
||||
0);
|
||||
/* requestId */ 0,
|
||||
/* headers */ JavaOnlyArray.of(),
|
||||
/* body */ null,
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
/* timeout */ 0);
|
||||
|
||||
ArgumentCaptor<Request> argumentCaptor = ArgumentCaptor.forClass(Request.class);
|
||||
verify(httpClient).newCall(argumentCaptor.capture());
|
||||
@@ -112,6 +117,9 @@ public class NetworkingModuleTest {
|
||||
when(context.getJSModule(any(ExecutorToken.class), 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<JavaOnlyArray> invalidHeaders = Arrays.asList(JavaOnlyArray.of("foo"));
|
||||
@@ -122,11 +130,12 @@ public class NetworkingModuleTest {
|
||||
mock(ExecutorToken.class),
|
||||
"GET",
|
||||
"http://somedoman/foo",
|
||||
0,
|
||||
JavaOnlyArray.from(invalidHeaders),
|
||||
null,
|
||||
true,
|
||||
0);
|
||||
/* requestId */ 0,
|
||||
/* headers */ JavaOnlyArray.from(invalidHeaders),
|
||||
/* body */ null,
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
/* timeout */ 0);
|
||||
|
||||
verifyErrorEmit(emitter, 0);
|
||||
}
|
||||
@@ -138,6 +147,9 @@ public class NetworkingModuleTest {
|
||||
when(context.getJSModule(any(ExecutorToken.class), 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();
|
||||
@@ -152,8 +164,9 @@ public class NetworkingModuleTest {
|
||||
0,
|
||||
JavaOnlyArray.of(),
|
||||
body,
|
||||
true,
|
||||
0);
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
/* timeout */ 0);
|
||||
|
||||
verifyErrorEmit(emitter, 0);
|
||||
}
|
||||
@@ -196,6 +209,9 @@ public class NetworkingModuleTest {
|
||||
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);
|
||||
|
||||
@@ -209,8 +225,9 @@ public class NetworkingModuleTest {
|
||||
0,
|
||||
JavaOnlyArray.of(JavaOnlyArray.of("Content-Type", "text/plain")),
|
||||
body,
|
||||
true,
|
||||
0);
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
/* timeout */ 0);
|
||||
|
||||
ArgumentCaptor<Request> argumentCaptor = ArgumentCaptor.forClass(Request.class);
|
||||
verify(httpClient).newCall(argumentCaptor.capture());
|
||||
@@ -234,6 +251,9 @@ public class NetworkingModuleTest {
|
||||
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);
|
||||
|
||||
@@ -248,8 +268,9 @@ public class NetworkingModuleTest {
|
||||
0,
|
||||
JavaOnlyArray.from(headers),
|
||||
null,
|
||||
true,
|
||||
0);
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
/* timeout */ 0);
|
||||
ArgumentCaptor<Request> argumentCaptor = ArgumentCaptor.forClass(Request.class);
|
||||
verify(httpClient).newCall(argumentCaptor.capture());
|
||||
Headers requestHeaders = argumentCaptor.getValue().headers();
|
||||
@@ -265,7 +286,8 @@ public class NetworkingModuleTest {
|
||||
.thenReturn(mock(InputStream.class));
|
||||
when(RequestBodyUtil.create(any(MediaType.class), any(InputStream.class)))
|
||||
.thenReturn(mock(RequestBody.class));
|
||||
when(RequestBodyUtil.createProgressRequest(any(RequestBody.class), any(ProgressRequestListener.class))).thenCallRealMethod();
|
||||
when(RequestBodyUtil.createProgressRequest(any(RequestBody.class), any(ProgressListener.class)))
|
||||
.thenCallRealMethod();
|
||||
|
||||
JavaOnlyMap body = new JavaOnlyMap();
|
||||
JavaOnlyArray formData = new JavaOnlyArray();
|
||||
@@ -288,6 +310,9 @@ public class NetworkingModuleTest {
|
||||
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(
|
||||
@@ -297,8 +322,9 @@ public class NetworkingModuleTest {
|
||||
0,
|
||||
new JavaOnlyArray(),
|
||||
body,
|
||||
true,
|
||||
0);
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
/* timeout */ 0);
|
||||
|
||||
// verify url, method, headers
|
||||
ArgumentCaptor<Request> argumentCaptor = ArgumentCaptor.forClass(Request.class);
|
||||
@@ -320,7 +346,8 @@ public class NetworkingModuleTest {
|
||||
.thenReturn(mock(InputStream.class));
|
||||
when(RequestBodyUtil.create(any(MediaType.class), any(InputStream.class)))
|
||||
.thenReturn(mock(RequestBody.class));
|
||||
when(RequestBodyUtil.createProgressRequest(any(RequestBody.class), any(ProgressRequestListener.class))).thenCallRealMethod();
|
||||
when(RequestBodyUtil.createProgressRequest(any(RequestBody.class), any(ProgressListener.class)))
|
||||
.thenCallRealMethod();
|
||||
|
||||
List<JavaOnlyArray> headers = Arrays.asList(
|
||||
JavaOnlyArray.of("Accept", "text/plain"),
|
||||
@@ -348,6 +375,9 @@ public class NetworkingModuleTest {
|
||||
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(
|
||||
@@ -357,8 +387,9 @@ public class NetworkingModuleTest {
|
||||
0,
|
||||
JavaOnlyArray.from(headers),
|
||||
body,
|
||||
true,
|
||||
0);
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
/* timeout */ 0);
|
||||
|
||||
// verify url, method, headers
|
||||
ArgumentCaptor<Request> argumentCaptor = ArgumentCaptor.forClass(Request.class);
|
||||
@@ -383,7 +414,8 @@ public class NetworkingModuleTest {
|
||||
when(RequestBodyUtil.getFileInputStream(any(ReactContext.class), any(String.class)))
|
||||
.thenReturn(inputStream);
|
||||
when(RequestBodyUtil.create(any(MediaType.class), any(InputStream.class))).thenCallRealMethod();
|
||||
when(RequestBodyUtil.createProgressRequest(any(RequestBody.class), any(ProgressRequestListener.class))).thenCallRealMethod();
|
||||
when(RequestBodyUtil.createProgressRequest(any(RequestBody.class), any(ProgressListener.class)))
|
||||
.thenCallRealMethod();
|
||||
when(inputStream.available()).thenReturn("imageUri".length());
|
||||
|
||||
final MultipartBody.Builder multipartBuilder = mock(MultipartBody.Builder.class);
|
||||
@@ -445,6 +477,9 @@ public class NetworkingModuleTest {
|
||||
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);
|
||||
@@ -455,8 +490,9 @@ public class NetworkingModuleTest {
|
||||
0,
|
||||
JavaOnlyArray.from(headers),
|
||||
body,
|
||||
true,
|
||||
0);
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
/* timeout */ 0);
|
||||
|
||||
// verify RequestBodyPart for image
|
||||
PowerMockito.verifyStatic(times(1));
|
||||
@@ -503,6 +539,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);
|
||||
networkingModule.initialize();
|
||||
@@ -515,7 +554,8 @@ public class NetworkingModuleTest {
|
||||
idx + 1,
|
||||
JavaOnlyArray.of(),
|
||||
null,
|
||||
true,
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
0);
|
||||
}
|
||||
verify(httpClient, times(3)).newCall(any(Request.class));
|
||||
@@ -550,6 +590,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);
|
||||
|
||||
@@ -561,7 +604,8 @@ public class NetworkingModuleTest {
|
||||
idx + 1,
|
||||
JavaOnlyArray.of(),
|
||||
null,
|
||||
true,
|
||||
/* responseType */ "text",
|
||||
/* useIncrementalUpdates*/ true,
|
||||
0);
|
||||
}
|
||||
verify(httpClient, times(3)).newCall(any(Request.class));
|
||||
|
||||
Reference in New Issue
Block a user