Loading java/src/com/android/inputmethod/latin/network/AuthException.java 0 → 100644 +35 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.inputmethod.latin.network; /** * Authentication exception. When this exception is thrown, the client may * try to refresh the authentication token and try again. */ public class AuthException extends Exception { public AuthException() { super(); } public AuthException(Throwable throwable) { super(throwable); } public AuthException(String detailMessage) { super(detailMessage); } } No newline at end of file java/src/com/android/inputmethod/latin/network/BlockingHttpClient.java +19 −15 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.inputmethod.latin.network; import android.util.Log; import com.android.inputmethod.annotations.UsedForTesting; import java.io.BufferedOutputStream; Loading @@ -35,20 +37,15 @@ import javax.annotation.Nullable; */ @UsedForTesting public class BlockingHttpClient { private static final boolean DEBUG = false; private static final String TAG = BlockingHttpClient.class.getSimpleName(); private final HttpURLConnection mConnection; /** * Interface that handles processing the response for a request. */ public interface ResponseProcessor { /** * Called when the HTTP request fails with an error. * * @param httpStatusCode The status code of the HTTP response. * @param message The HTTP response message, if any, or null. */ void onError(int httpStatusCode, @Nullable String message); public interface ResponseProcessor<T> { /** * Called when the HTTP request finishes successfully. * The {@link InputStream} is closed by the client after the method finishes, Loading @@ -56,7 +53,7 @@ public class BlockingHttpClient { * * @param response An input stream that can be used to read the HTTP response. */ void onSuccess(InputStream response); T onSuccess(InputStream response) throws IOException; } /** Loading @@ -73,11 +70,11 @@ public class BlockingHttpClient { * TODO: Remove @UsedForTesting after this is actually used. * * @param request The request payload, if any, or null. * @param responeProcessor A processor for the HTTP response. * @param responseProcessor A processor for the HTTP response. */ @UsedForTesting public void execute(@Nullable byte[] request, @Nonnull ResponseProcessor responseProcessor) throws IOException { public <T> T execute(@Nullable byte[] request, @Nonnull ResponseProcessor<T> responseProcessor) throws IOException, AuthException, HttpException { try { if (request != null) { OutputStream out = new BufferedOutputStream(mConnection.getOutputStream()); Loading @@ -88,9 +85,16 @@ public class BlockingHttpClient { final int responseCode = mConnection.getResponseCode(); if (responseCode != HttpURLConnection.HTTP_OK) { responseProcessor.onError(responseCode, mConnection.getResponseMessage()); if (DEBUG) { Log.d(TAG, "Response error: " + responseCode + ", Message: " + mConnection.getResponseMessage()); } if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) { throw new AuthException(mConnection.getResponseMessage()); } throw new HttpException(responseCode); } else { responseProcessor.onSuccess(mConnection.getInputStream()); return responseProcessor.onSuccess(mConnection.getInputStream()); } } finally { mConnection.disconnect(); Loading java/src/com/android/inputmethod/latin/network/HttpException.java 0 → 100644 +46 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.inputmethod.latin.network; import com.android.inputmethod.annotations.UsedForTesting; /** * The HttpException exception represents a XML/HTTP fault with a HTTP status code. */ public class HttpException extends Exception { /** * The HTTP status code. */ private final int mStatusCode; /** * @param statusCode int HTTP status code. */ public HttpException(int statusCode) { super("Response Code: " + statusCode); mStatusCode = statusCode; } /** * @return the HTTP status code related to this exception. */ @UsedForTesting public int getHttpStatusCode() { return mStatusCode; } } No newline at end of file java/src/com/android/inputmethod/latin/network/HttpUrlConnectionBuilder.java +25 −9 Original line number Diff line number Diff line Loading @@ -36,6 +36,11 @@ import java.util.Map.Entry; public class HttpUrlConnectionBuilder { private static final int DEFAULT_TIMEOUT_MILLIS = 5 * 1000; /** * Request header key for authentication. */ public static final String HTTP_HEADER_AUTHORIZATION = "Authorization"; /** * Request header key for cache control. */ Loading Loading @@ -78,7 +83,7 @@ public class HttpUrlConnectionBuilder { * Sets the URL that'll be used for the request. * This *must* be set before calling {@link #build()} * * TODO: Remove @UsedForTesting after this is actually used. * TODO: Remove @UsedForTesting after this method is actually used. */ @UsedForTesting public HttpUrlConnectionBuilder setUrl(String url) throws MalformedURLException { Loading @@ -92,7 +97,7 @@ public class HttpUrlConnectionBuilder { /** * Sets the connect timeout. Defaults to {@value #DEFAULT_TIMEOUT} milliseconds. * * TODO: Remove @UsedForTesting after this is actually used. * TODO: Remove @UsedForTesting after this method is actually used. */ @UsedForTesting public HttpUrlConnectionBuilder setConnectTimeout(int timeoutMillis) { Loading @@ -107,7 +112,7 @@ public class HttpUrlConnectionBuilder { /** * Sets the read timeout. Defaults to {@value #DEFAULT_TIMEOUT} milliseconds. * * TODO: Remove @UsedForTesting after this is actually used. * TODO: Remove @UsedForTesting after this method is actually used. */ @UsedForTesting public HttpUrlConnectionBuilder setReadTimeout(int timeoutMillis) { Loading @@ -122,7 +127,7 @@ public class HttpUrlConnectionBuilder { /** * Adds an entry to the request header. * * TODO: Remove @UsedForTesting after this is actually used. * TODO: Remove @UsedForTesting after this method is actually used. */ @UsedForTesting public HttpUrlConnectionBuilder addHeader(String key, String value) { Loading @@ -130,11 +135,22 @@ public class HttpUrlConnectionBuilder { return this; } /** * Sets an authentication token. * * TODO: Remove @UsedForTesting after this method is actually used. */ @UsedForTesting public HttpUrlConnectionBuilder setAuthToken(String value) { mHeaderMap.put(HTTP_HEADER_AUTHORIZATION, value); return this; } /** * Sets the request to be executed such that the input is not buffered. * This may be set when the request size is known beforehand. * * TODO: Remove @UsedForTesting after this is actually used. * TODO: Remove @UsedForTesting after this method is actually used. */ @UsedForTesting public HttpUrlConnectionBuilder setFixedLengthForStreaming(int length) { Loading @@ -145,7 +161,7 @@ public class HttpUrlConnectionBuilder { /** * Indicates if the request can use cached responses or not. * * TODO: Remove @UsedForTesting after this is actually used. * TODO: Remove @UsedForTesting after this method is actually used. */ @UsedForTesting public HttpUrlConnectionBuilder setUseCache(boolean useCache) { Loading @@ -161,7 +177,7 @@ public class HttpUrlConnectionBuilder { * @see #MODE_DOWNLOAD_ONLY * @see #MODE_BI_DIRECTIONAL * * TODO: Remove @UsedForTesting after this is actually used. * TODO: Remove @UsedForTesting after this method is actually used */ @UsedForTesting public HttpUrlConnectionBuilder setMode(int mode) { Loading @@ -177,7 +193,7 @@ public class HttpUrlConnectionBuilder { /** * Builds the {@link HttpURLConnection} instance that can be used to execute the request. * * TODO: Remove @UsedForTesting after this is actually used. * TODO: Remove @UsedForTesting after this method is actually used. */ @UsedForTesting public HttpURLConnection build() throws IOException { Loading tests/src/com/android/inputmethod/latin/network/BlockingHttpClientTests.java +38 −44 Original line number Diff line number Diff line Loading @@ -16,8 +16,8 @@ package com.android.inputmethod.latin.network; import static org.mockito.Mockito.any; import static org.mockito.Mockito.eq; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading Loading @@ -53,41 +53,52 @@ public class BlockingHttpClientTests extends AndroidTestCase { MockitoAnnotations.initMocks(this); } public void testError_badGateway() throws IOException { public void testError_badGateway() throws IOException, AuthException { when(mMockHttpConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_BAD_GATEWAY); final BlockingHttpClient client = new BlockingHttpClient(mMockHttpConnection); final FakeErrorResponseProcessor processor = new FakeErrorResponseProcessor(HttpURLConnection.HTTP_BAD_GATEWAY); final FakeErrorResponseProcessor processor = new FakeErrorResponseProcessor(); try { client.execute(null /* empty request */, processor); assertTrue("ResponseProcessor was not invoked", processor.mInvoked); fail("Expecting an HttpException"); } catch (HttpException e) { // expected HttpException assertEquals(HttpURLConnection.HTTP_BAD_GATEWAY, e.getHttpStatusCode()); } } public void testError_clientTimeout() throws IOException { public void testError_clientTimeout() throws Exception { when(mMockHttpConnection.getResponseCode()).thenReturn( HttpURLConnection.HTTP_CLIENT_TIMEOUT); final BlockingHttpClient client = new BlockingHttpClient(mMockHttpConnection); final FakeErrorResponseProcessor processor = new FakeErrorResponseProcessor(HttpURLConnection.HTTP_CLIENT_TIMEOUT); final FakeErrorResponseProcessor processor = new FakeErrorResponseProcessor(); try { client.execute(null /* empty request */, processor); assertTrue("ResponseProcessor was not invoked", processor.mInvoked); fail("Expecting an HttpException"); } catch (HttpException e) { // expected HttpException assertEquals(HttpURLConnection.HTTP_CLIENT_TIMEOUT, e.getHttpStatusCode()); } } public void testError_forbiddenWithRequest() throws IOException { public void testError_forbiddenWithRequest() throws Exception { final OutputStream mockOutputStream = Mockito.mock(OutputStream.class); when(mMockHttpConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_FORBIDDEN); when(mMockHttpConnection.getOutputStream()).thenReturn(mockOutputStream); final BlockingHttpClient client = new BlockingHttpClient(mMockHttpConnection); final FakeErrorResponseProcessor processor = new FakeErrorResponseProcessor(HttpURLConnection.HTTP_FORBIDDEN); final FakeErrorResponseProcessor processor = new FakeErrorResponseProcessor(); try { client.execute(new byte[100], processor); fail("Expecting an HttpException"); } catch (HttpException e) { assertEquals(HttpURLConnection.HTTP_FORBIDDEN, e.getHttpStatusCode()); } verify(mockOutputStream).write(any(byte[].class), eq(0), eq(100)); assertTrue("ResponseProcessor was not invoked", processor.mInvoked); } public void testSuccess_emptyRequest() throws IOException { public void testSuccess_emptyRequest() throws Exception { final Random rand = new Random(); byte[] response = new byte[100]; rand.nextBytes(response); Loading @@ -101,7 +112,7 @@ public class BlockingHttpClientTests extends AndroidTestCase { assertTrue("ResponseProcessor was not invoked", processor.mInvoked); } public void testSuccess() throws IOException { public void testSuccess() throws Exception { final OutputStream mockOutputStream = Mockito.mock(OutputStream.class); final Random rand = new Random(); byte[] response = new byte[100]; Loading @@ -117,28 +128,15 @@ public class BlockingHttpClientTests extends AndroidTestCase { assertTrue("ResponseProcessor was not invoked", processor.mInvoked); } private static class FakeErrorResponseProcessor implements ResponseProcessor { private final int mExpectedStatusCode; boolean mInvoked; FakeErrorResponseProcessor(int expectedStatusCode) { mExpectedStatusCode = expectedStatusCode; } @Override public void onError(int httpStatusCode, String message) { mInvoked = true; assertEquals("onError:", mExpectedStatusCode, httpStatusCode); } private static class FakeErrorResponseProcessor implements ResponseProcessor<Void> { @Override public void onSuccess(InputStream response) { public Void onSuccess(InputStream response) { fail("Expected an error but received success"); return null; } } private static class FakeSuccessResponseProcessor implements ResponseProcessor { private static class FakeSuccessResponseProcessor implements ResponseProcessor<Void> { private final byte[] mExpectedResponse; boolean mInvoked; Loading @@ -148,12 +146,7 @@ public class BlockingHttpClientTests extends AndroidTestCase { } @Override public void onError(int httpStatusCode, String message) { fail("Expected a response but received an error"); } @Override public void onSuccess(InputStream response) { public Void onSuccess(InputStream response) { try { mInvoked = true; BufferedInputStream in = new BufferedInputStream(response); Loading @@ -169,6 +162,7 @@ public class BlockingHttpClientTests extends AndroidTestCase { } catch (IOException ex) { fail("IOException in onSuccess"); } return null; } } } Loading
java/src/com/android/inputmethod/latin/network/AuthException.java 0 → 100644 +35 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.inputmethod.latin.network; /** * Authentication exception. When this exception is thrown, the client may * try to refresh the authentication token and try again. */ public class AuthException extends Exception { public AuthException() { super(); } public AuthException(Throwable throwable) { super(throwable); } public AuthException(String detailMessage) { super(detailMessage); } } No newline at end of file
java/src/com/android/inputmethod/latin/network/BlockingHttpClient.java +19 −15 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.inputmethod.latin.network; import android.util.Log; import com.android.inputmethod.annotations.UsedForTesting; import java.io.BufferedOutputStream; Loading @@ -35,20 +37,15 @@ import javax.annotation.Nullable; */ @UsedForTesting public class BlockingHttpClient { private static final boolean DEBUG = false; private static final String TAG = BlockingHttpClient.class.getSimpleName(); private final HttpURLConnection mConnection; /** * Interface that handles processing the response for a request. */ public interface ResponseProcessor { /** * Called when the HTTP request fails with an error. * * @param httpStatusCode The status code of the HTTP response. * @param message The HTTP response message, if any, or null. */ void onError(int httpStatusCode, @Nullable String message); public interface ResponseProcessor<T> { /** * Called when the HTTP request finishes successfully. * The {@link InputStream} is closed by the client after the method finishes, Loading @@ -56,7 +53,7 @@ public class BlockingHttpClient { * * @param response An input stream that can be used to read the HTTP response. */ void onSuccess(InputStream response); T onSuccess(InputStream response) throws IOException; } /** Loading @@ -73,11 +70,11 @@ public class BlockingHttpClient { * TODO: Remove @UsedForTesting after this is actually used. * * @param request The request payload, if any, or null. * @param responeProcessor A processor for the HTTP response. * @param responseProcessor A processor for the HTTP response. */ @UsedForTesting public void execute(@Nullable byte[] request, @Nonnull ResponseProcessor responseProcessor) throws IOException { public <T> T execute(@Nullable byte[] request, @Nonnull ResponseProcessor<T> responseProcessor) throws IOException, AuthException, HttpException { try { if (request != null) { OutputStream out = new BufferedOutputStream(mConnection.getOutputStream()); Loading @@ -88,9 +85,16 @@ public class BlockingHttpClient { final int responseCode = mConnection.getResponseCode(); if (responseCode != HttpURLConnection.HTTP_OK) { responseProcessor.onError(responseCode, mConnection.getResponseMessage()); if (DEBUG) { Log.d(TAG, "Response error: " + responseCode + ", Message: " + mConnection.getResponseMessage()); } if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) { throw new AuthException(mConnection.getResponseMessage()); } throw new HttpException(responseCode); } else { responseProcessor.onSuccess(mConnection.getInputStream()); return responseProcessor.onSuccess(mConnection.getInputStream()); } } finally { mConnection.disconnect(); Loading
java/src/com/android/inputmethod/latin/network/HttpException.java 0 → 100644 +46 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.inputmethod.latin.network; import com.android.inputmethod.annotations.UsedForTesting; /** * The HttpException exception represents a XML/HTTP fault with a HTTP status code. */ public class HttpException extends Exception { /** * The HTTP status code. */ private final int mStatusCode; /** * @param statusCode int HTTP status code. */ public HttpException(int statusCode) { super("Response Code: " + statusCode); mStatusCode = statusCode; } /** * @return the HTTP status code related to this exception. */ @UsedForTesting public int getHttpStatusCode() { return mStatusCode; } } No newline at end of file
java/src/com/android/inputmethod/latin/network/HttpUrlConnectionBuilder.java +25 −9 Original line number Diff line number Diff line Loading @@ -36,6 +36,11 @@ import java.util.Map.Entry; public class HttpUrlConnectionBuilder { private static final int DEFAULT_TIMEOUT_MILLIS = 5 * 1000; /** * Request header key for authentication. */ public static final String HTTP_HEADER_AUTHORIZATION = "Authorization"; /** * Request header key for cache control. */ Loading Loading @@ -78,7 +83,7 @@ public class HttpUrlConnectionBuilder { * Sets the URL that'll be used for the request. * This *must* be set before calling {@link #build()} * * TODO: Remove @UsedForTesting after this is actually used. * TODO: Remove @UsedForTesting after this method is actually used. */ @UsedForTesting public HttpUrlConnectionBuilder setUrl(String url) throws MalformedURLException { Loading @@ -92,7 +97,7 @@ public class HttpUrlConnectionBuilder { /** * Sets the connect timeout. Defaults to {@value #DEFAULT_TIMEOUT} milliseconds. * * TODO: Remove @UsedForTesting after this is actually used. * TODO: Remove @UsedForTesting after this method is actually used. */ @UsedForTesting public HttpUrlConnectionBuilder setConnectTimeout(int timeoutMillis) { Loading @@ -107,7 +112,7 @@ public class HttpUrlConnectionBuilder { /** * Sets the read timeout. Defaults to {@value #DEFAULT_TIMEOUT} milliseconds. * * TODO: Remove @UsedForTesting after this is actually used. * TODO: Remove @UsedForTesting after this method is actually used. */ @UsedForTesting public HttpUrlConnectionBuilder setReadTimeout(int timeoutMillis) { Loading @@ -122,7 +127,7 @@ public class HttpUrlConnectionBuilder { /** * Adds an entry to the request header. * * TODO: Remove @UsedForTesting after this is actually used. * TODO: Remove @UsedForTesting after this method is actually used. */ @UsedForTesting public HttpUrlConnectionBuilder addHeader(String key, String value) { Loading @@ -130,11 +135,22 @@ public class HttpUrlConnectionBuilder { return this; } /** * Sets an authentication token. * * TODO: Remove @UsedForTesting after this method is actually used. */ @UsedForTesting public HttpUrlConnectionBuilder setAuthToken(String value) { mHeaderMap.put(HTTP_HEADER_AUTHORIZATION, value); return this; } /** * Sets the request to be executed such that the input is not buffered. * This may be set when the request size is known beforehand. * * TODO: Remove @UsedForTesting after this is actually used. * TODO: Remove @UsedForTesting after this method is actually used. */ @UsedForTesting public HttpUrlConnectionBuilder setFixedLengthForStreaming(int length) { Loading @@ -145,7 +161,7 @@ public class HttpUrlConnectionBuilder { /** * Indicates if the request can use cached responses or not. * * TODO: Remove @UsedForTesting after this is actually used. * TODO: Remove @UsedForTesting after this method is actually used. */ @UsedForTesting public HttpUrlConnectionBuilder setUseCache(boolean useCache) { Loading @@ -161,7 +177,7 @@ public class HttpUrlConnectionBuilder { * @see #MODE_DOWNLOAD_ONLY * @see #MODE_BI_DIRECTIONAL * * TODO: Remove @UsedForTesting after this is actually used. * TODO: Remove @UsedForTesting after this method is actually used */ @UsedForTesting public HttpUrlConnectionBuilder setMode(int mode) { Loading @@ -177,7 +193,7 @@ public class HttpUrlConnectionBuilder { /** * Builds the {@link HttpURLConnection} instance that can be used to execute the request. * * TODO: Remove @UsedForTesting after this is actually used. * TODO: Remove @UsedForTesting after this method is actually used. */ @UsedForTesting public HttpURLConnection build() throws IOException { Loading
tests/src/com/android/inputmethod/latin/network/BlockingHttpClientTests.java +38 −44 Original line number Diff line number Diff line Loading @@ -16,8 +16,8 @@ package com.android.inputmethod.latin.network; import static org.mockito.Mockito.any; import static org.mockito.Mockito.eq; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading Loading @@ -53,41 +53,52 @@ public class BlockingHttpClientTests extends AndroidTestCase { MockitoAnnotations.initMocks(this); } public void testError_badGateway() throws IOException { public void testError_badGateway() throws IOException, AuthException { when(mMockHttpConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_BAD_GATEWAY); final BlockingHttpClient client = new BlockingHttpClient(mMockHttpConnection); final FakeErrorResponseProcessor processor = new FakeErrorResponseProcessor(HttpURLConnection.HTTP_BAD_GATEWAY); final FakeErrorResponseProcessor processor = new FakeErrorResponseProcessor(); try { client.execute(null /* empty request */, processor); assertTrue("ResponseProcessor was not invoked", processor.mInvoked); fail("Expecting an HttpException"); } catch (HttpException e) { // expected HttpException assertEquals(HttpURLConnection.HTTP_BAD_GATEWAY, e.getHttpStatusCode()); } } public void testError_clientTimeout() throws IOException { public void testError_clientTimeout() throws Exception { when(mMockHttpConnection.getResponseCode()).thenReturn( HttpURLConnection.HTTP_CLIENT_TIMEOUT); final BlockingHttpClient client = new BlockingHttpClient(mMockHttpConnection); final FakeErrorResponseProcessor processor = new FakeErrorResponseProcessor(HttpURLConnection.HTTP_CLIENT_TIMEOUT); final FakeErrorResponseProcessor processor = new FakeErrorResponseProcessor(); try { client.execute(null /* empty request */, processor); assertTrue("ResponseProcessor was not invoked", processor.mInvoked); fail("Expecting an HttpException"); } catch (HttpException e) { // expected HttpException assertEquals(HttpURLConnection.HTTP_CLIENT_TIMEOUT, e.getHttpStatusCode()); } } public void testError_forbiddenWithRequest() throws IOException { public void testError_forbiddenWithRequest() throws Exception { final OutputStream mockOutputStream = Mockito.mock(OutputStream.class); when(mMockHttpConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_FORBIDDEN); when(mMockHttpConnection.getOutputStream()).thenReturn(mockOutputStream); final BlockingHttpClient client = new BlockingHttpClient(mMockHttpConnection); final FakeErrorResponseProcessor processor = new FakeErrorResponseProcessor(HttpURLConnection.HTTP_FORBIDDEN); final FakeErrorResponseProcessor processor = new FakeErrorResponseProcessor(); try { client.execute(new byte[100], processor); fail("Expecting an HttpException"); } catch (HttpException e) { assertEquals(HttpURLConnection.HTTP_FORBIDDEN, e.getHttpStatusCode()); } verify(mockOutputStream).write(any(byte[].class), eq(0), eq(100)); assertTrue("ResponseProcessor was not invoked", processor.mInvoked); } public void testSuccess_emptyRequest() throws IOException { public void testSuccess_emptyRequest() throws Exception { final Random rand = new Random(); byte[] response = new byte[100]; rand.nextBytes(response); Loading @@ -101,7 +112,7 @@ public class BlockingHttpClientTests extends AndroidTestCase { assertTrue("ResponseProcessor was not invoked", processor.mInvoked); } public void testSuccess() throws IOException { public void testSuccess() throws Exception { final OutputStream mockOutputStream = Mockito.mock(OutputStream.class); final Random rand = new Random(); byte[] response = new byte[100]; Loading @@ -117,28 +128,15 @@ public class BlockingHttpClientTests extends AndroidTestCase { assertTrue("ResponseProcessor was not invoked", processor.mInvoked); } private static class FakeErrorResponseProcessor implements ResponseProcessor { private final int mExpectedStatusCode; boolean mInvoked; FakeErrorResponseProcessor(int expectedStatusCode) { mExpectedStatusCode = expectedStatusCode; } @Override public void onError(int httpStatusCode, String message) { mInvoked = true; assertEquals("onError:", mExpectedStatusCode, httpStatusCode); } private static class FakeErrorResponseProcessor implements ResponseProcessor<Void> { @Override public void onSuccess(InputStream response) { public Void onSuccess(InputStream response) { fail("Expected an error but received success"); return null; } } private static class FakeSuccessResponseProcessor implements ResponseProcessor { private static class FakeSuccessResponseProcessor implements ResponseProcessor<Void> { private final byte[] mExpectedResponse; boolean mInvoked; Loading @@ -148,12 +146,7 @@ public class BlockingHttpClientTests extends AndroidTestCase { } @Override public void onError(int httpStatusCode, String message) { fail("Expected a response but received an error"); } @Override public void onSuccess(InputStream response) { public Void onSuccess(InputStream response) { try { mInvoked = true; BufferedInputStream in = new BufferedInputStream(response); Loading @@ -169,6 +162,7 @@ public class BlockingHttpClientTests extends AndroidTestCase { } catch (IOException ex) { fail("IOException in onSuccess"); } return null; } } }