package com.tinify;
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.Mock;
import mockit.MockUp;
import org.apache.commons.codec.binary.Base64;
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.Paths;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.isA;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
public class TinifyTest {
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 url)
{
return new HttpUrl.Builder()
.scheme("http")
.host(server.getHostName())
.port(server.getPort())
.encodedPath(url.replaceFirst(Client.API_ENDPOINT, ""))
.build();
}
};
}
@After
public void tearDown() throws IOException {
Tinify.setKey(null);
Tinify.setProxy(null);
server.shutdown();
}
@Test
public void keyShouldResetClientWithNewKey() throws Exception, InterruptedException {
server.enqueue(new MockResponse().setResponseCode(200));
Tinify.setKey("abcde");
Tinify.client();
Tinify.setKey("fghij");
Tinify.client().request(Client.Method.GET, "/");
RecordedRequest request = server.takeRequest(5, TimeUnit.SECONDS);
String credentials = new String(Base64.encodeBase64(("api:fghij").getBytes()));
assertEquals("Basic " + credentials, request.getHeader("Authorization"));
}
@Test
public void appIdentifierShouldResetClientWithNewAppIdentifier() throws InterruptedException {
server.enqueue(new MockResponse().setResponseCode(200));
Tinify.setKey("abcde");
Tinify.setAppIdentifier("MyApp/1.0");
Tinify.client();
Tinify.setAppIdentifier("MyApp/2.0");
Tinify.client().request(Client.Method.GET, "/");
RecordedRequest request = server.takeRequest(5, TimeUnit.SECONDS);
assertEquals(Client.USER_AGENT + " MyApp/2.0", request.getHeader("User-Agent"));
}
@Test
public void proxyShouldResetClientWithNewProxy() throws InterruptedException {
server.enqueue(new MockResponse().setResponseCode(407));
server.enqueue(new MockResponse().setResponseCode(200));
Tinify.setKey("abcde");
Tinify.setProxy("http://localhost");
Tinify.client();
Tinify.setProxy("http://user:pass@" + server.getHostName() + ":" + server.getPort());
Tinify.client().request(Client.Method.GET, "/");
RecordedRequest request1 = server.takeRequest(5, TimeUnit.SECONDS);
RecordedRequest request2 = server.takeRequest(5, TimeUnit.SECONDS);
assertEquals("Basic dXNlcjpwYXNz", request2.getHeader("Proxy-Authorization"));
}
@Test
public void clientWithKeyShouldReturnClient() {
Tinify.setKey("abcde");
assertThat(Tinify.client(), isA(Client.class));
}
@Test(expected = AccountException.class)
public void clientWithoutKeyShouldThrowException() {
Tinify.client();
}
@Test(expected = ConnectionException.class)
public void clientWithInvalidProxyShouldThrowException() {
Tinify.setKey("abcde");
Tinify.setProxy("http-bad-url");
Tinify.client();
}
@Test
public void validateWithValidKeyShouldReturnTrue() throws InterruptedException {
server.enqueue(new MockResponse()
.setResponseCode(400)
.setBody("{'error':'Input missing','message':'No input'}"));
Tinify.setKey("valid");
assertThat(Tinify.validate(), is(true));
RecordedRequest request = server.takeRequest();
assertEquals("POST /shrink HTTP/1.1", request.getRequestLine());
assertEquals(0, request.getBody().size());
}
@Test
public void validateWithLimitedKeyShouldReturnTrue() throws InterruptedException {
server.enqueue(new MockResponse()
.setResponseCode(429)
.setBody("{'error':'Too many requests','message':'Your monthly limit has been exceeded'}"));
Tinify.setKey("valid");
assertThat(Tinify.validate(), is(true));
RecordedRequest request = server.takeRequest();
assertEquals("POST /shrink HTTP/1.1", request.getRequestLine());
assertEquals(0, request.getBody().size());
}
@Test(expected = AccountException.class)
public void validateWithErrorShouldThrowException() throws InterruptedException {
server.enqueue(new MockResponse()
.setResponseCode(401)
.setBody("{'error':'Unauthorized','message':'Credentials are invalid'}"));
Tinify.setKey("invalid");
Tinify.validate();
RecordedRequest request = server.takeRequest();
assertEquals("POST /shrink HTTP/1.1", request.getRequestLine());
assertEquals(0, request.getBody().size());
}
@Test
public void fromBufferShouldReturnSource() {
Tinify.setKey("valid");
server.enqueue(new MockResponse()
.setResponseCode(201)
.addHeader("Location", "https://api.tinify.com/some/location")
.addHeader("Compression-Count", 12));
assertThat(Tinify.fromBuffer("png file".getBytes()), isA(Source.class));
}
@Test
public void fromFileShouldReturnSource() throws IOException, 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(Tinify.fromFile(filePath), isA(Source.class));
}
}