blob: 5838bb762930bf93feb4e3b2474173d6a60b9883 [file] [log] [blame]
/*
* Copyright (C) 2021 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.libraries.entitlement.http;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.testng.Assert.expectThrows;
import static java.nio.charset.StandardCharsets.UTF_8;
import android.net.Network;
import androidx.test.runner.AndroidJUnit4;
import com.android.libraries.entitlement.ServiceEntitlementException;
import com.android.libraries.entitlement.http.HttpConstants.ContentType;
import com.android.libraries.entitlement.http.HttpConstants.RequestMethod;
import com.android.libraries.entitlement.testing.FakeURLStreamHandler;
import com.android.libraries.entitlement.testing.FakeURLStreamHandler.FakeHttpsURLConnection;
import com.android.libraries.entitlement.testing.FakeURLStreamHandler.FakeResponse;
import com.google.common.collect.ImmutableMap;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
@RunWith(AndroidJUnit4.class)
public class HttpClientTest {
private static final String TEST_URL = "https://test.url";
private static final String TEST_RESPONSE_BODY = "TEST_RESPONSE_BODY";
private static final String CONTENT_TYPE_STRING_JSON = "application/json";
private static final String RETRY_AFTER = "RETRY_AFTER";
private static FakeURLStreamHandler sFakeURLStreamHandler;
private HttpClient mHttpClient;
@BeforeClass
public static void setupURLStreamHandlerFactory() {
sFakeURLStreamHandler = new FakeURLStreamHandler();
URL.setURLStreamHandlerFactory(sFakeURLStreamHandler);
}
@Before
public void setUp() {
// Reset sFakeURLStreamHandler
sFakeURLStreamHandler.stubResponse(ImmutableMap.of());
mHttpClient = new HttpClient();
}
@Test
public void request_contentTypeXml_returnsXmlBody() throws Exception {
FakeResponse responseContent =
FakeResponse.builder()
.setResponseCode(HttpURLConnection.HTTP_OK)
.setResponseLocation(null)
.setResponseBody(TEST_RESPONSE_BODY.getBytes(UTF_8))
.setContentType(CONTENT_TYPE_STRING_JSON)
.build();
Map<String, FakeResponse> response = ImmutableMap.of(TEST_URL, responseContent);
sFakeURLStreamHandler.stubResponse(response);
HttpRequest request =
HttpRequest.builder()
.setUrl(TEST_URL)
.setRequestMethod(RequestMethod.GET)
.setTimeoutInSec(70)
.build();
HttpResponse httpResponse = mHttpClient.request(request);
// Verify that one HttpURLConnection was opened and its timeout is 70 seconds.
assertThat(sFakeURLStreamHandler.getConnections()).hasSize(1);
HttpURLConnection connection = sFakeURLStreamHandler.getConnections().get(0);
assertThat(connection.getConnectTimeout()).isEqualTo(70 * 1000);
assertThat(connection.getReadTimeout()).isEqualTo(70 * 1000);
// Verify the HttpResponse.
assertThat(httpResponse.contentType()).isEqualTo(ContentType.JSON);
assertThat(httpResponse.body()).isEqualTo(TEST_RESPONSE_BODY);
assertThat(httpResponse.responseCode()).isEqualTo(HttpURLConnection.HTTP_OK);
}
@Test
public void request_httpGetResponseBadRequest_throwsException() {
FakeResponse responseContent =
FakeResponse.builder()
.setResponseCode(HttpURLConnection.HTTP_BAD_REQUEST)
.setResponseLocation(null)
.setResponseBody(TEST_RESPONSE_BODY.getBytes(UTF_8))
.setContentType(CONTENT_TYPE_STRING_JSON)
.setRetryAfter(RETRY_AFTER)
.build();
HttpRequest request =
HttpRequest.builder().setUrl(TEST_URL).setRequestMethod(RequestMethod.GET).build();
Map<String, FakeResponse> response = ImmutableMap.of(TEST_URL, responseContent);
sFakeURLStreamHandler.stubResponse(response);
ServiceEntitlementException exception =
expectThrows(ServiceEntitlementException.class, () -> mHttpClient.request(request));
// Verify the ServiceEntitlementException.
assertThat(exception.getErrorCode()).isEqualTo(
ServiceEntitlementException.ERROR_HTTP_STATUS_NOT_SUCCESS);
assertThat(exception.getHttpStatus()).isEqualTo(HttpURLConnection.HTTP_BAD_REQUEST);
assertThat(exception).hasMessageThat().contains("Invalid connection response");
assertThat(exception.getRetryAfter()).isEqualTo(RETRY_AFTER);
// Verify that one HttpURLConnection was opened and its timeout is 30 seconds.
assertThat(sFakeURLStreamHandler.getConnections()).hasSize(1);
HttpURLConnection connection = sFakeURLStreamHandler.getConnections().get(0);
assertThat(connection.getConnectTimeout()).isEqualTo(30 * 1000);
assertThat(connection.getReadTimeout()).isEqualTo(30 * 1000);
}
@Test
public void request_contentTypeXml_returnsXmlBody_useSpecificNetwork() throws Exception {
FakeResponse responseContent =
FakeResponse.builder()
.setResponseCode(HttpURLConnection.HTTP_OK)
.setResponseLocation(null)
.setResponseBody(TEST_RESPONSE_BODY.getBytes(UTF_8))
.setContentType(CONTENT_TYPE_STRING_JSON)
.build();
Network network = mock(Network.class);
URL url = new URL(TEST_URL);
FakeHttpsURLConnection connection = new FakeHttpsURLConnection(url, responseContent);
when(network.openConnection(url)).thenReturn(connection);
HttpRequest request =
HttpRequest.builder()
.setUrl(TEST_URL)
.setRequestMethod(RequestMethod.GET)
.setNetwork(network)
.setTimeoutInSec(70)
.build();
HttpResponse httpResponse = mHttpClient.request(request);
// Verify that the HttpURLConnection associsted with Netwotk was opened
// and its timeout is 70 seconds.
verify(network).openConnection(url);
assertThat(connection.getConnectTimeout()).isEqualTo(70 * 1000);
assertThat(connection.getReadTimeout()).isEqualTo(70 * 1000);
// Verify the HttpResponse.
assertThat(httpResponse.contentType()).isEqualTo(ContentType.JSON);
assertThat(httpResponse.body()).isEqualTo(TEST_RESPONSE_BODY);
assertThat(httpResponse.responseCode()).isEqualTo(HttpURLConnection.HTTP_OK);
}
@Test
public void request_postJson_doNotEscapeForwardSlash() throws Exception {
String postData = "{\"key\":\"base64/base64+b\"}";
HttpRequest request =
HttpRequest.builder()
.setUrl(TEST_URL)
.setRequestMethod(RequestMethod.POST)
.setPostData(new JSONObject(postData))
.build();
FakeResponse responseContent =
FakeResponse.builder()
.setResponseCode(HttpURLConnection.HTTP_OK)
.setResponseBody(TEST_RESPONSE_BODY.getBytes(UTF_8))
.setContentType(CONTENT_TYPE_STRING_JSON)
.build();
Map<String, FakeResponse> response = ImmutableMap.of(TEST_URL, responseContent);
sFakeURLStreamHandler.stubResponse(response);
HttpResponse httpResponse = mHttpClient.request(request);
FakeHttpsURLConnection connection = sFakeURLStreamHandler.getConnections().get(0);
assertThat(connection.getBytesWrittenToOutputStream()).isEqualTo(postData.getBytes(UTF_8));
}
}