package com.auth0.client;
import okhttp3.HttpUrl;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeDiagnosingMatcher;
import java.util.Arrays;
public class UrlMatcher extends TypeSafeDiagnosingMatcher<String> {
private static final int BASE_URL = 0;
private static final int QUERY_PARAMETER = 1;
private static final int ENCODED_QUERY = 2;
private final int checkingOption;
private String encodedQueryContains;
private String scheme;
private String host;
private String path;
private String paramKey;
private String paramValue;
private UrlMatcher(String scheme, String host, String path) {
this.checkingOption = BASE_URL;
this.scheme = scheme;
this.host = host;
this.path = path;
}
private UrlMatcher(String paramKey, String paramValue) {
this.checkingOption = QUERY_PARAMETER;
this.paramKey = paramKey;
this.paramValue = paramValue;
}
private UrlMatcher(String encodedQueryContains) {
this.checkingOption = ENCODED_QUERY;
this.encodedQueryContains = encodedQueryContains;
}
@Override
protected boolean matchesSafely(String item, Description mismatchDescription) {
if (item == null) {
mismatchDescription.appendText("was null");
return false;
}
HttpUrl url = HttpUrl.parse(item);
if (url == null) {
mismatchDescription.appendText("was not a valid url");
return false;
}
switch (checkingOption) {
default:
case BASE_URL:
return matchesBaseUrl(url, mismatchDescription);
case QUERY_PARAMETER:
return matchesParameter(url, mismatchDescription);
case ENCODED_QUERY:
return matchesEncodedQuery(url, mismatchDescription);
}
}
private boolean matchesEncodedQuery(HttpUrl url, Description mismatchDescription) {
if (!url.encodedQuery().contains(encodedQueryContains)) {
mismatchDescription.appendText("encoded query was ").appendValue(url.encodedQuery());
return false;
}
return true;
}
private boolean matchesBaseUrl(HttpUrl url, Description mismatchDescription) {
if (!url.scheme().equals(scheme)) {
mismatchDescription.appendText("scheme was ").appendValue(url.scheme());
return false;
}
if (!url.host().equals(host)) {
mismatchDescription.appendText("host was ").appendValue(url.host());
return false;
}
if (path == null) {
return true;
}
if (path.startsWith("/")) {
path = path.substring(1, path.length());
}
if (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}
if (!url.pathSegments().equals(Arrays.asList(path.split("/")))) {
StringBuilder sb = new StringBuilder();
for (String p : url.pathSegments()) {
sb.append(p).append("/");
}
sb.deleteCharAt(sb.length() - 1);
mismatchDescription.appendText("path was ").appendValue(sb.toString());
return false;
}
return true;
}
private boolean matchesParameter(HttpUrl url, Description mismatchDescription) {
String value = url.queryParameter(paramKey);
if (value != null && !value.equals(paramValue) || value == null && paramValue != null) {
mismatchDescription.appendText("value was ").appendValue(value);
return false;
}
return true;
}
@Override
public void describeTo(Description description) {
switch (checkingOption) {
default:
case BASE_URL:
description.appendText("An url with scheme ")
.appendValue(scheme)
.appendText(", host ")
.appendValue(host)
.appendText("and path ")
.appendValue(path);
break;
case QUERY_PARAMETER:
description.appendText("An url with the query parameter ")
.appendValue(paramKey)
.appendText(" with value ")
.appendValue(paramValue);
break;
case ENCODED_QUERY:
description.appendText("An url with encoded query containing ")
.appendValue(encodedQueryContains);
break;
}
}
public static UrlMatcher isUrl(String scheme, String host, String path) {
return new UrlMatcher(scheme, host, path);
}
public static UrlMatcher isUrl(String scheme, String host) {
return new UrlMatcher(scheme, host, null);
}
public static UrlMatcher hasQueryParameter(String key, String value) {
return new UrlMatcher(key, value);
}
public static UrlMatcher encodedQueryContains(String text) {
return new UrlMatcher(text);
}
}