package com.vtence.molecule.testing;
import com.vtence.molecule.Response;
import com.vtence.molecule.http.HeaderNames;
import com.vtence.molecule.http.HttpStatus;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.MatcherAssert;
import org.hamcrest.core.IsEqual;
import java.nio.charset.Charset;
import java.util.Arrays;
import static com.vtence.molecule.http.HeaderNames.CONTENT_TYPE;
import static com.vtence.molecule.testing.CharsetDetector.detectCharsetOf;
import static org.hamcrest.CoreMatchers.any;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
public class ResponseAssert {
private final Response response;
protected ResponseAssert(Response response) {
this.response = response;
}
public static ResponseAssert assertThat(Response response) {
return new ResponseAssert(response);
}
public ResponseAssert hasStatusCode(int code) {
hasStatusCode(is(code));
return this;
}
public ResponseAssert hasStatusCode(Matcher<? super Integer> matching) {
MatcherAssert.assertThat("response status code", response.statusCode(), matching);
return this;
}
public ResponseAssert hasStatusText(String text) {
hasStatusText(is(text));
return this;
}
public ResponseAssert hasStatusText(Matcher<? super String> matching) {
MatcherAssert.assertThat("response status text", response.statusText(), matching);
return this;
}
public ResponseAssert hasStatus(HttpStatus expected) {
hasStatusCode(expected.code);
hasStatusText(expected.text);
return this;
}
public ResponseAssert isRedirectedTo(String location) {
isRedirectedTo(equalTo(location));
return this;
}
public ResponseAssert isRedirectedTo(Matcher<? super String> matching) {
hasHeader(HeaderNames.LOCATION, matching);
return this;
}
public ResponseAssert hasHeader(String named) {
hasHeader(named, any(String.class));
return this;
}
public ResponseAssert hasHeader(String name, String value) {
hasHeader(name, equalTo(value));
return this;
}
public ResponseAssert hasHeader(String name, Matcher<? super String> matchingValue) {
MatcherAssert.assertThat("response '" + name + "' header", response.header(name), matchingValue);
return this;
}
public ResponseAssert hasHeaders(String name, Matcher<Iterable<? extends String>> matchingValues) {
MatcherAssert.assertThat("response '" + name + "' headers", response.headers(name), matchingValues);
return this;
}
public ResponseAssert hasNoHeader(String named) {
hasHeader(named, nullValue());
return this;
}
public ResponseAssert hasContentType(String contentType) {
hasContentType(equalTo(contentType));
return this;
}
public ResponseAssert hasContentType(Matcher<? super String> matching) {
hasHeader(CONTENT_TYPE, matching);
return this;
}
public ResponseAssert hasBodyText(String body) {
return hasBodyText(equalTo(body));
}
public ResponseAssert hasBodyText(Matcher<? super String> matching) {
MatcherAssert.assertThat("response body text", BodyContent.asText(response), matching);
return this;
}
public ResponseAssert hasBodyContent(byte[] content) {
byte[] actual = BodyContent.asBytes(response);
// Yep, I know, but it's good enough
MatcherAssert.assertThat("response body byte stream", actual, new IsEqual<byte[]>(content) {
public void describeTo(Description description) {
description.appendValue(Arrays.toString(content));
}
public void describeMismatch(Object item, Description description) {
description.appendText("was ").appendValue(Arrays.toString((byte[]) item));
}
});
return this;
}
public ResponseAssert isEmpty() {
return hasBodySize(0);
}
public ResponseAssert hasBodySize(long byteCount) {
return hasSize(is(byteCount));
}
public ResponseAssert hasSize(Matcher<? super Long> matching) {
MatcherAssert.assertThat("response size", response.size(), matching);
return this;
}
public ResponseAssert hasBodyEncoding(Charset charset) {
return hasBodyEncoding(charset.name());
}
public ResponseAssert hasBodyEncoding(String encoding) {
return hasBodyEncoding(equalTo(encoding));
}
public ResponseAssert hasBodyEncoding(Matcher<? super String> matching) {
MatcherAssert.assertThat("response body encoding", detectCharsetOf(BodyContent.asBytes(response)), matching);
return this;
}
public ResponseAssert isDone() {
MatcherAssert.assertThat("response completed", response.isDone(), is(true));
return this;
}
}