blob: a5bdb4cc26ae4c8fd86204d5ecf08866250984ff [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.testing;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import javax.net.ssl.HttpsURLConnection;
/**
* A {@link URLStreamHandlerFactory} to return faked {@link URLConnection}, as {@link URL} is a
* final class and {@link URL#openConnection} cannot be mocked using mockito.
*/
public class FakeURLStreamHandler extends URLStreamHandler implements URLStreamHandlerFactory {
private Map<String, FakeResponse> mResponses = ImmutableMap.of();
private List<FakeHttpsURLConnection> mConnections = new ArrayList<>();
private static final String ACCESS_TOKEN = "8dGozfI6%2FEaSsE7LaTfJKwdy";
private static final String LOCATION = "Location";
private static final String CONTENT_TYPE = "Content-Type";
private static final String RETRY_AFTER = "Retry-After";
@Override
public URLConnection openConnection(URL u) {
FakeHttpsURLConnection connection =
new FakeHttpsURLConnection(u, mResponses.get(u.toString()));
mConnections.add(connection);
return connection;
}
@Override
public URLStreamHandler createURLStreamHandler(String protocol) {
return this;
}
/**
* Prepares canned responses. Must be called before using this handler to open any {@link
* URLConnection}.
*/
public FakeURLStreamHandler stubResponse(Map<String, FakeResponse> response) {
mResponses = response;
mConnections = new ArrayList<>();
return this;
}
/** Returns {@link URLConnection}s opened by this handler since last {@link #stubResponse}. */
public ImmutableList<FakeHttpsURLConnection> getConnections() {
return ImmutableList.copyOf(mConnections);
}
/** Faked {@link HttpsURLConnection} to avoid making any network connection. */
public static class FakeHttpsURLConnection extends HttpsURLConnection {
private final FakeResponse mResponse;
private final ByteArrayOutputStream mOutputStream = new ByteArrayOutputStream();
public FakeHttpsURLConnection(URL url, FakeResponse response) {
super(url);
mResponse = response;
}
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(mResponse.responseBody());
}
@Override
public OutputStream getOutputStream() {
return mOutputStream;
}
public byte[] getBytesWrittenToOutputStream() {
return mOutputStream.toByteArray();
}
@Override
public int getResponseCode() {
return mResponse.responseCode();
}
@Override
public Map<String, List<String>> getHeaderFields() {
List<String> locationList = ImmutableList.of("access_token=" + ACCESS_TOKEN);
return ImmutableMap.of("Location", locationList);
}
@Override
public String getHeaderField(String name) {
switch (name) {
case LOCATION:
return "Location: " + mResponse.responseLocation();
case CONTENT_TYPE:
return mResponse.contentType();
case RETRY_AFTER:
return mResponse.retryAfter();
default:
return null;
}
}
@Override
public void connect() {
}
@Override
public void disconnect() {
}
@Override
public boolean usingProxy() {
return false;
}
@Override
public String getCipherSuite() {
return null;
}
@Override
public Certificate[] getLocalCertificates() {
return null;
}
@Override
public Certificate[] getServerCertificates() {
return null;
}
}
@AutoValue
public abstract static class FakeResponse {
public abstract int responseCode();
@Nullable
public abstract String responseLocation();
@SuppressWarnings("mutable") // For test only
public abstract byte[] responseBody();
public abstract String contentType();
public abstract String retryAfter();
public static Builder builder() {
return new AutoValue_FakeURLStreamHandler_FakeResponse.Builder()
.setResponseBody(new byte[]{})
.setContentType("")
.setResponseCode(0)
.setResponseLocation("")
.setRetryAfter("");
}
@AutoValue.Builder
public abstract static class Builder {
public abstract Builder setResponseCode(int value);
public abstract Builder setResponseLocation(String value);
public abstract Builder setResponseBody(byte[] value);
public abstract Builder setContentType(String contentType);
public abstract Builder setRetryAfter(String retryAfter);
public abstract FakeResponse build();
}
}
}