package com.tinify;
import com.google.gson.Gson;
import com.squareup.okhttp.HttpUrl;
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.MockWebServer;
import com.squareup.okhttp.mockwebserver.RecordedRequest;
import mockit.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.lang.*;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.hamcrest.Matchers.*;
public class SourceTest {
MockWebServer server;
@Before
public void setup() throws IOException {
Logger.getLogger(MockWebServer.class.getName()).setLevel(Level.WARNING);
server = new MockWebServer();
server.start();
new MockUp<HttpUrl>()
{
@Mock
@SuppressWarnings("unused")
HttpUrl parse(String input)
{
return new HttpUrl.Builder()
.scheme("http")
.host(server.getHostName())
.port(server.getPort())
.encodedPath("/shrink")
.build();
}
};
}
@After
public void tearDown() throws IOException {
server.shutdown();
}
public void assertJsonEquals(String expected, String actual)
{
Gson gson = new Gson();
@SuppressWarnings("unchecked")
Map<String, Object> expectedMap = gson.fromJson(expected, Map.class);
@SuppressWarnings("unchecked")
Map<String, Object> actualMap = gson.fromJson(actual, Map.class);
assertEquals(expectedMap, actualMap);
}
@Test(expected = AccountException.class)
public void withInvalidApiKeyFromFileShouldThrowAccountException() throws Exception, IOException, URISyntaxException {
Tinify.setKey("invalid");
server.enqueue(new MockResponse()
.setResponseCode(401)
.setBody("{'error':'Unauthorized','message':'Credentials are invalid'}"));
String filePath = Paths.get(getClass().getResource("/dummy.png").toURI()).toAbsolutePath().toString();
Source.fromFile(filePath);
}
@Test(expected = AccountException.class)
public void withInvalidApiKeyFromBufferShouldThrowAccountException() throws Exception, IOException {
Tinify.setKey("invalid");
server.enqueue(new MockResponse()
.setResponseCode(401)
.setBody("{'error':'Unauthorized','message':'Credentials are invalid'}"));
Source.fromBuffer("png file".getBytes());
}
@Test(expected = AccountException.class)
public void withInvalidApiKeyFromUrlShouldThrowAccountException() throws Exception, IOException {
Tinify.setKey("invalid");
server.enqueue(new MockResponse()
.setResponseCode(401)
.setBody("{'error':'Unauthorized','message':'Credentials are invalid'}"));
Source.fromUrl("http://example.com/test.jpg");
}
@Test
public void withValidApiKeyFromFileShouldReturnSource() throws IOException, Exception, URISyntaxException {
Tinify.setKey("valid");
server.enqueue(new MockResponse()
.setResponseCode(201)
.addHeader("Location", "https://api.tinify.com/some/location")
.addHeader("Compression-Count", 12));
String filePath = Paths.get(getClass().getResource("/dummy.png").toURI()).toAbsolutePath().toString();
assertThat(Source.fromFile(filePath), isA(Source.class));
}
@Test
public void withValidApiKeyFromFileShouldReturnSourceWithData() throws IOException, Exception, URISyntaxException {
Tinify.setKey("valid");
server.enqueue(new MockResponse()
.setResponseCode(201)
.addHeader("Location", "https://api.tinify.com/some/location"));
server.enqueue(new MockResponse()
.setResponseCode(200)
.setBody("compressed file"));
String filePath = Paths.get(getClass().getResource("/dummy.png").toURI()).toAbsolutePath().toString();
assertThat(Source.fromFile(filePath).toBuffer(), is(equalTo("compressed file".getBytes())));
}
@Test
public void withValidApiKeyFromBufferShouldReturnSource() throws IOException, Exception {
Tinify.setKey("valid");
server.enqueue(new MockResponse()
.setResponseCode(201)
.addHeader("Location", "https://api.tinify.com/some/location")
.addHeader("Compression-Count", 12));
assertThat(Source.fromBuffer("png file".getBytes()), isA(Source.class));
}
@Test
public void withValidApiKeyFromBufferShouldReturnSourceWithData() throws IOException, Exception {
Tinify.setKey("valid");
server.enqueue(new MockResponse()
.setResponseCode(201)
.addHeader("Location", "https://api.tinify.com/some/location"));
server.enqueue(new MockResponse()
.setResponseCode(200)
.setBody("compressed file"));
assertThat(Source.fromBuffer("png file".getBytes()).toBuffer(),
is(equalTo("compressed file".getBytes())));
}
@Test
public void withValidApiKeyFromUrlShouldReturnSource() throws IOException, Exception {
Tinify.setKey("valid");
server.enqueue(new MockResponse()
.setResponseCode(201)
.addHeader("Location", "https://api.tinify.com/some/location")
.addHeader("Compression-Count", 12));
assertThat(Source.fromUrl("http://example.com/test.jpg"), isA(Source.class));
}
@Test
public void withValidApiKeyFromUrlShouldReturnSourceWithData() throws IOException, Exception, InterruptedException {
Tinify.setKey("valid");
server.enqueue(new MockResponse()
.setResponseCode(201)
.addHeader("Location", "https://api.tinify.com/some/location"));
server.enqueue(new MockResponse()
.setResponseCode(200)
.setBody("compressed file"));
assertThat(Source.fromUrl("http://example.com/test.jpg").toBuffer(),
is(equalTo("compressed file".getBytes())));
RecordedRequest request1 = server.takeRequest(3, TimeUnit.SECONDS);
assertJsonEquals("{\"source\":{\"url\":\"http://example.com/test.jpg\"}}", request1.getBody().readUtf8());
}
@Test(expected = ClientException.class)
public void withValidApiKeyFromUrlShouldThrowExceptionIfRequestIsNotOK() throws IOException, Exception {
Tinify.setKey("valid");
server.enqueue(new MockResponse()
.setResponseCode(400)
.setBody("{'error':'Source not found','message':'Cannot parse URL'}"));
Source.fromUrl("file://wrong");
}
@Test
public void withValidApiKeyResultShouldReturnResult() throws Exception, IOException {
Tinify.setKey("valid");
server.enqueue(new MockResponse()
.setResponseCode(201)
.addHeader("Location", "https://api.tinify.com/some/location")
.addHeader("Compression-Count", 12));
server.enqueue(new MockResponse()
.setResponseCode(200)
.setBody("compressed file"));
assertThat(Source.fromBuffer("png file".getBytes()).result(),
isA(Result.class));
}
@Test
public void withValidApiKeyPreserveShouldReturnSource() throws Exception, InterruptedException {
Tinify.setKey("valid");
server.enqueue(new MockResponse()
.setResponseCode(201)
.addHeader("Location", "https://api.tinify.com/some/location"));
server.enqueue(new MockResponse()
.setResponseCode(200)
.setBody("copyrighted file"));
assertThat(Source.fromBuffer("png file".getBytes()).preserve("copyright", "location"),
isA(Source.class));
RecordedRequest request1 = server.takeRequest(3, TimeUnit.SECONDS);
assertEquals("png file", request1.getBody().readUtf8());
}
@Test
public void withValidApiKeyPreserveShouldReturnSourceWithData() throws Exception, IOException, InterruptedException {
Tinify.setKey("valid");
server.enqueue(new MockResponse()
.setResponseCode(201)
.addHeader("Location", "https://api.tinify.com/some/location"));
server.enqueue(new MockResponse()
.setResponseCode(200)
.setBody("copyrighted file"));
assertThat(Source.fromBuffer("png file".getBytes()).preserve("copyright", "location").toBuffer(),
is(equalTo("copyrighted file".getBytes())));
RecordedRequest request1 = server.takeRequest(3, TimeUnit.SECONDS);
assertEquals("png file", request1.getBody().readUtf8());
RecordedRequest request2 = server.takeRequest(3, TimeUnit.SECONDS);
assertJsonEquals("{\"preserve\":[\"copyright\",\"location\"]}", request2.getBody().readUtf8());
}
@Test
public void withValidApiKeyPreserveShouldReturnSourceWithDataForArray() throws Exception, IOException, InterruptedException {
Tinify.setKey("valid");
server.enqueue(new MockResponse()
.setResponseCode(201)
.addHeader("Location", "https://api.tinify.com/some/location"));
server.enqueue(new MockResponse()
.setResponseCode(200)
.setBody("copyrighted file"));
String[] options = new String [] {"copyright", "location"};
assertThat(Source.fromBuffer("png file".getBytes()).preserve(options).toBuffer(),
is(equalTo("copyrighted file".getBytes())));
RecordedRequest request1 = server.takeRequest(3, TimeUnit.SECONDS);
assertEquals("png file", request1.getBody().readUtf8());
RecordedRequest request2 = server.takeRequest(3, TimeUnit.SECONDS);
assertJsonEquals("{\"preserve\":[\"copyright\",\"location\"]}", request2.getBody().readUtf8());
}
@Test
public void withValidApiKeyPreserveShouldIncludeOtherOptionsIfSet() throws Exception, IOException, InterruptedException {
Tinify.setKey("valid");
server.enqueue(new MockResponse()
.setResponseCode(201)
.addHeader("Location", "https://api.tinify.com/some/location"));
server.enqueue(new MockResponse()
.setResponseCode(200)
.setBody("copyrighted resized file"));
Options resizeOptions = new Options().with("width", 100).with("height", 60);
String[] preserveOptions = new String [] {"copyright", "location"};
assertThat(Source.fromBuffer("png file".getBytes()).resize(resizeOptions).preserve(preserveOptions).toBuffer(),
is(equalTo("copyrighted resized file".getBytes())));
RecordedRequest request1 = server.takeRequest(3, TimeUnit.SECONDS);
assertEquals("png file", request1.getBody().readUtf8());
RecordedRequest request2 = server.takeRequest(3, TimeUnit.SECONDS);
assertJsonEquals("{\"resize\":{\"width\":100,\"height\":60},\"preserve\":[\"copyright\",\"location\"]}", request2.getBody().readUtf8());
}
@Test
public void withValidApiKeyResizeShouldReturnSource() throws Exception, InterruptedException {
Tinify.setKey("valid");
server.enqueue(new MockResponse()
.setResponseCode(201)
.addHeader("Location", "https://api.tinify.com/some/location"));
server.enqueue(new MockResponse()
.setResponseCode(200)
.setBody("small file"));
Options options = new Options().with("width", 100).with("height", 60);
assertThat(Source.fromBuffer("png file".getBytes()).resize(options),
isA(Source.class));
RecordedRequest request1 = server.takeRequest(3, TimeUnit.SECONDS);
assertEquals("png file", request1.getBody().readUtf8());
}
@Test
public void withValidApiKeyResizeShouldReturnSourceWithData() throws Exception, IOException, InterruptedException {
Tinify.setKey("valid");
server.enqueue(new MockResponse()
.setResponseCode(201)
.addHeader("Location", "https://api.tinify.com/some/location"));
server.enqueue(new MockResponse()
.setResponseCode(200)
.setBody("small file"));
Options options = new Options().with("width", 100).with("height", 60);
assertThat(Source.fromBuffer("png file".getBytes()).resize(options).toBuffer(),
is(equalTo("small file".getBytes())));
RecordedRequest request1 = server.takeRequest(3, TimeUnit.SECONDS);
assertEquals("png file", request1.getBody().readUtf8());
RecordedRequest request2 = server.takeRequest(3, TimeUnit.SECONDS);
assertJsonEquals("{\"resize\":{\"width\":100,\"height\":60}}", request2.getBody().readUtf8());
}
@Test
public void withValidApiKeyStoreShouldReturnResultMeta() throws Exception, InterruptedException {
Tinify.setKey("valid");
server.enqueue(new MockResponse()
.setResponseCode(201)
.addHeader("Location", "https://api.tinify.com/some/location")
.addHeader("Compression-Count", 12));
server.enqueue(new MockResponse()
.setResponseCode(200)
.addHeader("Location", "https://bucket.s3.amazonaws.com/example"));
Options options = new Options().with("service", "s3");
assertThat(Source.fromBuffer("png file".getBytes()).store(options),
isA(ResultMeta.class));
RecordedRequest request1 = server.takeRequest(3, TimeUnit.SECONDS);
assertEquals("png file", request1.getBody().readUtf8());
RecordedRequest request2 = server.takeRequest(3, TimeUnit.SECONDS);
assertJsonEquals("{\"store\":{\"service\":\"s3\"}}", request2.getBody().readUtf8());
}
@Test
public void withValidApiKeyStoreShouldReturnResultMetaWithLocation() throws Exception, InterruptedException {
Tinify.setKey("valid");
server.enqueue(new MockResponse()
.setResponseCode(201)
.addHeader("Location", "https://api.tinify.com/some/location")
.addHeader("Compression-Count", 12));
server.enqueue(new MockResponse()
.setResponseCode(200)
.addHeader("Location", "https://bucket.s3.amazonaws.com/example"));
Options options = new Options().with("service", "s3");
assertEquals("https://bucket.s3.amazonaws.com/example",
Source.fromBuffer("png file".getBytes()).store(options).location());
RecordedRequest request1 = server.takeRequest(3, TimeUnit.SECONDS);
assertEquals("png file", request1.getBody().readUtf8());
RecordedRequest request2 = server.takeRequest(3, TimeUnit.SECONDS);
assertJsonEquals("{\"store\":{\"service\":\"s3\"}}", request2.getBody().readUtf8());
}
@Test
public void withValidApiKeyStoreShouldIncludeOtherOptionsIfSet() throws Exception, IOException, InterruptedException {
Tinify.setKey("valid");
server.enqueue(new MockResponse()
.setResponseCode(201)
.addHeader("Location", "https://api.tinify.com/some/location")
.addHeader("Compression-Count", 12));
server.enqueue(new MockResponse()
.setResponseCode(200)
.setBody("compressed file"));
server.enqueue(new MockResponse()
.setResponseCode(200)
.addHeader("Location", "https://bucket.s3.amazonaws.com/example"));
Options resizeOptions = new Options().with("width", 100);
Options storeOptions = new Options().with("service", "s3");
Source.fromBuffer("png file".getBytes()).resize(resizeOptions).store(storeOptions);
RecordedRequest request1 = server.takeRequest(3, TimeUnit.SECONDS);
assertEquals("png file", request1.getBody().readUtf8());
RecordedRequest request2 = server.takeRequest(3, TimeUnit.SECONDS);
assertJsonEquals("{\"resize\":{\"width\":100},\"store\":{\"service\":\"s3\"}}", request2.getBody().readUtf8());
}
@Test
public void withValidApiKeyToBufferShouldReturnImageData() throws Exception, IOException {
Tinify.setKey("valid");
server.enqueue(new MockResponse()
.setResponseCode(201)
.addHeader("Location", "https://api.tinify.com/some/location")
.addHeader("Compression-Count", 12));
server.enqueue(new MockResponse()
.setResponseCode(200)
.setBody("compressed file"));
assertThat(Source.fromBuffer("png file".getBytes()).toBuffer(),
is(equalTo("compressed file".getBytes())));
}
@Test
public void withValidApiKeyToFileShouldStoreImageData() throws Exception, IOException {
Tinify.setKey("valid");
server.enqueue(new MockResponse()
.setResponseCode(201)
.addHeader("Location", "https://api.tinify.com/some/location")
.addHeader("Compression-Count", 12));
server.enqueue(new MockResponse()
.setResponseCode(200)
.setBody("compressed file"));
Path tempFile = Files.createTempFile("tinify_", null);
tempFile.toFile().deleteOnExit();
Source.fromBuffer("png file".getBytes()).toFile(tempFile.toString());
assertThat(Files.readAllBytes(tempFile),
is(equalTo("compressed file".getBytes())));
}
}