package com.vtence.molecule.middlewares;
import com.vtence.molecule.Request;
import com.vtence.molecule.Response;
import com.vtence.molecule.helpers.Streams;
import org.junit.Test;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
import static com.vtence.molecule.http.HttpStatus.NOT_ACCEPTABLE;
import static com.vtence.molecule.testing.BodyContent.asStream;
import static com.vtence.molecule.testing.ResponseAssert.assertThat;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
public class CompressorTest {
Compressor compressor = new Compressor();
Request request = new Request();
Response response = new Response();
@Test public void
deflatesResponseWhenClientAcceptsDeflate() throws Exception {
request.header("Accept-Encoding", "deflate");
compressor.handle(request, response);
response.body("uncompressed body").done();
assertNoExecutionError();
assertThat(response).hasHeader("Content-Encoding", "deflate");
assertThat("body", inflate(response), equalTo("uncompressed body"));
}
@Test public void
gzipsResponseWhenClientAcceptsGZip() throws Exception {
request.header("Accept-Encoding", "gzip");
compressor.handle(request, response);
response.body("uncompressed body").done();
assertNoExecutionError();
assertThat(response).hasHeader("Content-Encoding", "gzip");
assertThat("response body", unzip(response), equalTo("uncompressed body"));
}
@Test public void
usesFirstAcceptedContentCoding() throws Exception {
request.addHeader("Accept-Encoding", "gzip");
request.addHeader("Accept-Encoding", "deflate");
compressor.handle(request, response);
response.body("uncompressed body").done();
assertNoExecutionError();
assertThat(response).hasHeader("Content-Encoding", "gzip");
assertThat("body", unzip(response), equalTo("uncompressed body"));
}
@Test public void
skipsCompressionOfEmptyContent() throws Exception {
request.header("Accept-Encoding", "deflate");
compressor.handle(request, response);
response.done();
assertNoExecutionError();
assertThat(response).hasNoHeader("Content-Encoding");
}
@Test public void
removesContentLengthHeaderWhenCompressing() throws Exception {
request.header("Accept-Encoding", "deflate");
compressor.handle(request, response);
response.contentLength(128).body("uncompressed body...").done();
assertNoExecutionError();
assertThat(response).hasNoHeader("Content-Length");
}
@Test public void
fallsBackToNoCompressionWhenClientDoesNotAcceptOurEncodings() throws Exception {
request.header("Accept-Encoding", "compress");
compressor.handle(request, response);
response.body("uncompressed body").done();
assertNoExecutionError();
assertThat(response).hasNoHeader("Content-Encoding")
.hasBodyText("uncompressed body");
}
@Test public void
preservesContentLengthOfIdentityResponses() throws Exception {
request.header("Accept-Encoding", "identity");
compressor.handle(request, response);
response.contentLength(128).body("uncompressed body...").done();
assertNoExecutionError();
assertThat(response).hasHeader("Content-Length", "128");
}
@Test public void
skipsCompressionIfResponseAlreadyEncoded() throws Exception {
request.header("Accept-Encoding", "gzip");
compressor.handle(request, response);
response.header("Content-Encoding", "deflate").body("<compressed body>").done();
assertNoExecutionError();
assertThat(response).hasHeader("Content-Encoding", "deflate")
.hasBodyText("<compressed body>");
}
@Test public void
compressesAnywayWhenContentEncodingIsIdentity() throws Exception {
request.header("Accept-Encoding", "gzip");
compressor.handle(request, response);
response.header("Content-Encoding", "identity").body("uncompressed body").done();
assertNoExecutionError();
assertThat("body", unzip(response), equalTo("uncompressed body"));
}
@Test public void
reportsLackOfAnAcceptableEncoding() throws Exception {
request.header("Accept-Encoding", "identity;q=0");
compressor.handle(request, response);
response.body("uncompressed body").done();
assertNoExecutionError();
assertThat(response).hasStatus(NOT_ACCEPTABLE)
.hasContentType("text/plain")
.hasBodyText("An acceptable encoding could not be found");
}
@Test public void
skipsMimeTypesDeemedNotCompressible() throws Exception {
request.header("Accept-Encoding", "gzip");
compressor.compressibleTypes("text/html");
compressor.handle(request, response);
response.contentType("text/plain").body("uncompressed body").done();
assertNoExecutionError();
assertThat(response).hasNoHeader("Content-Encoding")
.hasBodyText("uncompressed body");
}
@Test public void
processesCompressibleMimeTypes() throws Exception {
request.header("Accept-Encoding", "gzip");
compressor.compressibleTypes("application/json", "text/*");
compressor.handle(request, response);
response.contentType("text/plain").body("uncompressed body").done();
assertNoExecutionError();
assertThat("body", unzip(response), equalTo("uncompressed body"));
}
@Test public void
ignoresContentTypeCharsetToDecideIfContentShouldBeCompressed() throws Exception {
request.header("Accept-Encoding", "gzip");
compressor.compressibleTypes("text/html");
compressor.handle(request, response);
response.contentType("text/html; utf-8")
.body("<html>uncompressed</html>")
.done();
assertNoExecutionError();
assertThat("body", unzip(response), equalTo("<html>uncompressed</html>"));
}
private String inflate(Response response) throws IOException {
return response.empty() ? "" : Streams.toString(new InflaterInputStream(asStream(response), new Inflater(true)));
}
private String unzip(Response response) throws IOException {
return response.empty() ? "" : Streams.toString(new GZIPInputStream(asStream(response)));
}
private void assertNoExecutionError() throws ExecutionException, InterruptedException {
response.await();
}
}