package com.twilio.http;
import com.twilio.exception.ApiConnectionException;
import mockit.Expectations;
import mockit.Mocked;
import mockit.NonStrictExpectations;
import mockit.Tested;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
public class NetworkHttpClientTest {
@Tested
private NetworkHttpClient tested;
@Mocked
private Request mockRequest;
@Mocked
private URL mockUrl;
@Mocked
private HttpURLConnection mockConn;
@Mocked
private OutputStream mockOutputStream;
@Mocked
private OutputStreamWriter mockWriter;
@Test
public void testGet() throws IOException {
String content = "frobozz";
final InputStream stream = new ByteArrayInputStream(content.getBytes("UTF-8"));
new Expectations() {{
mockRequest.constructURL();
result = mockUrl;
mockRequest.getMethod();
result = HttpMethod.GET;
mockUrl.openConnection();
result = mockConn;
mockConn.setAllowUserInteraction(false);
mockConn.addRequestProperty("Accept", "application/json");
mockConn.addRequestProperty("Accept-Encoding", "utf-8");
mockConn.setInstanceFollowRedirects(true);
mockConn.setRequestMethod("GET");
mockRequest.requiresAuthentication();
result = false;
mockConn.connect();
mockConn.getResponseCode();
result = 200;
mockConn.getErrorStream();
result = null;
mockConn.getInputStream();
result = stream;
}};
NetworkHttpClient client = new NetworkHttpClient();
Response resp = client.makeRequest(mockRequest);
assertEquals(resp.getStatusCode(), 200);
assertEquals(resp.getContent(), "frobozz");
}
@Test(expected = ApiConnectionException.class)
public void testMakeRequestIOException() throws IOException {
NetworkHttpClient client = new NetworkHttpClient();
new NonStrictExpectations() {{
mockUrl.openConnection();
result = new IOException();
}};
client.makeRequest(new Request(HttpMethod.GET, "http://www.example.com"));
fail("ApiConnectionException was expected");
}
@Test
public void testPost() throws IOException {
String content = "frobozz";
final InputStream stream = new ByteArrayInputStream(content.getBytes("UTF-8"));
new Expectations() {{
mockRequest.constructURL();
result = mockUrl;
mockRequest.getMethod();
result = HttpMethod.POST;
mockUrl.openConnection();
result = mockConn;
mockConn.setAllowUserInteraction(false);
mockConn.addRequestProperty("Accept", "application/json");
mockConn.addRequestProperty("Accept-Encoding", "utf-8");
mockConn.setInstanceFollowRedirects(true);
mockConn.setRequestMethod("POST");
mockRequest.requiresAuthentication();
result = false;
mockConn.setDoOutput(true);
mockConn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded");
mockConn.connect();
mockRequest.encodeFormBody();
result = "foo=bar&baz=quux";
mockConn.getOutputStream();
result = mockOutputStream;
new OutputStreamWriter(mockOutputStream);
result = mockWriter;
mockWriter.write("foo=bar&baz=quux");
mockWriter.close();
mockConn.getResponseCode();
result = 201;
mockConn.getErrorStream();
result = null;
mockConn.getInputStream();
result = stream;
}};
NetworkHttpClient client = new NetworkHttpClient();
Response resp = client.makeRequest(mockRequest);
assertEquals(resp.getStatusCode(), 201);
assertEquals(resp.getContent(), "frobozz");
}
@Test
public void testReliableRequest() {
final HttpClient httpClient = new NetworkHttpClient();
Request request = new Request(HttpMethod.GET, "/uri");
new NonStrictExpectations(httpClient) {{
httpClient.makeRequest((Request) any);
result = new Response("", TwilioRestClient.HTTP_STATUS_CODE_NO_CONTENT);
}};
httpClient.reliableRequest(request);
}
@Test
public void testReliableRequestWithRetries() {
final HttpClient httpClient = new NetworkHttpClient();
Request request = new Request(HttpMethod.GET, "/uri");
new NonStrictExpectations(httpClient) {{
httpClient.makeRequest((Request) any);
result = null;
times = 3;
}};
httpClient.reliableRequest(request);
}
@Test
public void testReliableRequestWithRetries100() throws InterruptedException {
final HttpClient httpClient = new NetworkHttpClient();
Request request = new Request(HttpMethod.GET, "/uri");
new NonStrictExpectations(httpClient) {{
httpClient.makeRequest((Request) any);
result = new Response("", 500);
}};
httpClient.reliableRequest(request);
}
@Test
public void testDelete() throws IOException {
String content = "";
final InputStream stream = new ByteArrayInputStream(content.getBytes("UTF-8"));
new Expectations() {{
mockRequest.constructURL();
result = mockUrl;
mockRequest.getMethod();
result = HttpMethod.DELETE;
mockUrl.openConnection();
result = mockConn;
mockConn.setAllowUserInteraction(false);
mockConn.addRequestProperty("Accept", "application/json");
mockConn.addRequestProperty("Accept-Encoding", "utf-8");
mockConn.setInstanceFollowRedirects(true);
mockConn.setRequestMethod("DELETE");
mockRequest.requiresAuthentication();
result = false;
mockConn.connect();
mockConn.getResponseCode();
result = 204;
mockConn.getErrorStream();
result = null;
mockConn.getInputStream();
result = stream;
}};
NetworkHttpClient client = new NetworkHttpClient();
Response resp = client.makeRequest(mockRequest);
assertEquals(resp.getStatusCode(), 204);
assertEquals(resp.getContent(), "");
}
@Test
public void testAuthedGet() throws IOException {
String content = "frobozz";
final InputStream stream = new ByteArrayInputStream(content.getBytes("UTF-8"));
new Expectations() {{
mockRequest.constructURL();
result = mockUrl;
mockRequest.getMethod();
result = HttpMethod.GET;
mockUrl.openConnection();
result = mockConn;
mockConn.setAllowUserInteraction(false);
mockConn.addRequestProperty("Accept", "application/json");
mockConn.addRequestProperty("Accept-Encoding", "utf-8");
mockConn.setInstanceFollowRedirects(true);
mockConn.setRequestMethod("GET");
mockRequest.requiresAuthentication();
result = true;
mockRequest.getUsername();
result = "foo";
mockRequest.getPassword();
result = "bar";
mockConn.setRequestProperty("Authorization", "Basic Zm9vOmJhcg==");
mockConn.connect();
mockConn.getResponseCode();
result = 200;
mockConn.getErrorStream();
result = null;
mockConn.getInputStream();
result = stream;
}};
NetworkHttpClient client = new NetworkHttpClient();
Response resp = client.makeRequest(mockRequest);
assertEquals(resp.getStatusCode(), 200);
assertEquals(resp.getContent(), "frobozz");
}
@Test
public void testErrorResponse() throws IOException {
String error = "womp";
final InputStream stream = new ByteArrayInputStream(error.getBytes("UTF-8"));
new Expectations() {{
mockRequest.constructURL();
result = mockUrl;
mockRequest.getMethod();
result = HttpMethod.GET;
mockUrl.openConnection();
result = mockConn;
mockConn.setAllowUserInteraction(false);
mockConn.addRequestProperty("Accept", "application/json");
mockConn.addRequestProperty("Accept-Encoding", "utf-8");
mockConn.setInstanceFollowRedirects(true);
mockConn.setRequestMethod("GET");
mockRequest.requiresAuthentication();
result = true;
mockRequest.getUsername();
result = "foo";
mockRequest.getPassword();
result = "bar";
mockConn.setRequestProperty("Authorization", "Basic Zm9vOmJhcg==");
mockConn.connect();
mockConn.getResponseCode();
result = 404;
mockConn.getErrorStream();
result = stream;
}};
NetworkHttpClient client = new NetworkHttpClient();
Response resp = client.makeRequest(mockRequest);
assertEquals(resp.getStatusCode(), 404);
assertEquals(resp.getContent(), "womp");
}
}