package com.pivotallabs.api;
import com.pivotallabs.util.Strings;
import org.apache.http.HttpRequest;
import org.apache.http.auth.AuthScope;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.ClientContext;
import org.hamcrest.CoreMatchers;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.tester.org.apache.http.HttpRequestInfo;
import java.io.InputStream;
import java.util.Map;
import static com.pivotallabs.TestResponses.GENERIC_XML;
import static com.pivotallabs.util.TestUtil.asString;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.CoreMatchers.sameInstance;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertThat;
@RunWith(RobolectricTestRunner.class)
public class ApiGatewayTest {
private ApiGateway apiGateway;
private TestApiResponseCallbacks responseCallbacks;
@Before
public void setUp() throws Exception {
apiGateway = new ApiGateway();
responseCallbacks = new TestApiResponseCallbacks();
}
@Test
public void dispatch_shouldCallOntoTheSuccessWhenApiResponseIsSuccess() throws Exception {
XmlApiResponse apiResponse = new XmlApiResponse(200);
apiGateway.dispatch(apiResponse, responseCallbacks);
assertThat(responseCallbacks.successResponse, sameInstance(apiResponse));
assertThat(responseCallbacks.failureResponse, nullValue());
assertThat(responseCallbacks.onCompleteWasCalled, equalTo(true));
}
@Test
public void dispatch_shouldCallOnFailureWhenApiResponseIsFailure() throws Exception {
XmlApiResponse apiResponse = new XmlApiResponse(500);
apiGateway.dispatch(apiResponse, responseCallbacks);
assertThat(responseCallbacks.failureResponse, sameInstance((ApiResponse) apiResponse));
assertThat(responseCallbacks.successResponse, nullValue());
assertThat(responseCallbacks.onCompleteWasCalled, equalTo(true));
}
@Test
public void dispatch_shouldCallOnFailureWhenXmlParseErrorOccurs() throws Exception {
Robolectric.addPendingHttpResponse(200, "Invalid x-shmail");
apiGateway.makeRequest(new TestGetRequest(), responseCallbacks);
assertThat(responseCallbacks.successResponse, nullValue());
assertThat(responseCallbacks.failureResponse, not(nullValue()));
assertThat(responseCallbacks.onCompleteWasCalled, equalTo(true));
}
@Test
public void dispatch_shouldCallOnFailureWhenOnSuccessFails() throws Exception {
XmlApiResponse apiResponse = new XmlApiResponse(200);
TestApiResponseCallbacks callbacks = new TestApiResponseCallbacks() {
@Override
public void onSuccess(XmlApiResponse successResponse) {
throw new RuntimeException("boom!");
}
};
apiGateway.dispatch(apiResponse, callbacks);
assertThat(callbacks.failureResponse, sameInstance((ApiResponse) apiResponse));
assertThat(callbacks.onCompleteWasCalled, equalTo(true));
}
@Test
public void shouldMakeRemoteGetCalls() {
Robolectric.getBackgroundScheduler().pause();
TestGetRequest apiRequest = new TestGetRequest();
apiGateway.makeRequest(apiRequest, responseCallbacks);
Robolectric.addPendingHttpResponse(200, GENERIC_XML);
Robolectric.getBackgroundScheduler().runOneTask();
HttpRequestInfo sentHttpRequestData = Robolectric.getSentHttpRequestInfo(0);
HttpRequest sentHttpRequest = sentHttpRequestData.getHttpRequest();
assertThat(sentHttpRequest.getRequestLine().getUri(), equalTo("www.example.com"));
assertThat(sentHttpRequest.getRequestLine().getMethod(), equalTo(HttpGet.METHOD_NAME));
assertThat(sentHttpRequest.getHeaders("foo")[0].getValue(), equalTo("bar"));
CredentialsProvider credentialsProvider =
(CredentialsProvider) sentHttpRequestData.getHttpContext().getAttribute(ClientContext.CREDS_PROVIDER);
assertThat(credentialsProvider.getCredentials(AuthScope.ANY).getUserPrincipal().getName(), CoreMatchers.equalTo("spongebob"));
assertThat(credentialsProvider.getCredentials(AuthScope.ANY).getPassword(), CoreMatchers.equalTo("squarepants"));
}
@Test
public void shouldMakeRemotePostCalls() throws Exception {
Robolectric.getBackgroundScheduler().pause();
TestPostRequest apiRequest = new TestPostRequest();
apiGateway.makeRequest(apiRequest, responseCallbacks);
Robolectric.addPendingHttpResponse(200, GENERIC_XML);
Robolectric.getBackgroundScheduler().runOneTask();
HttpRequestInfo sentHttpRequestData = Robolectric.getSentHttpRequestInfo(0);
HttpRequest sentHttpRequest = sentHttpRequestData.getHttpRequest();
assertThat(sentHttpRequest.getRequestLine().getUri(), equalTo("www.example.com"));
assertThat(sentHttpRequest.getRequestLine().getMethod(), equalTo(HttpPost.METHOD_NAME));
assertThat(sentHttpRequest.getHeaders("foo")[0].getValue(), equalTo("bar"));
InputStream contentStream = ((HttpPost) sentHttpRequest).getEntity().getContent();
assertThat(Strings.fromStream(contentStream), CoreMatchers.equalTo("post body content"));
CredentialsProvider credentialsProvider =
(CredentialsProvider) sentHttpRequestData.getHttpContext().getAttribute(ClientContext.CREDS_PROVIDER);
assertThat(credentialsProvider.getCredentials(AuthScope.ANY).getUserPrincipal().getName(), CoreMatchers.equalTo("spongebob"));
assertThat(credentialsProvider.getCredentials(AuthScope.ANY).getPassword(), CoreMatchers.equalTo("squarepants"));
}
@Test
public void shouldDispatchUponReceivingResponse() throws Exception {
Robolectric.getBackgroundScheduler().pause();
Robolectric.getUiThreadScheduler().pause();
Robolectric.addPendingHttpResponse(200, GENERIC_XML);
apiGateway.makeRequest(new TestGetRequest(), responseCallbacks);
Robolectric.getBackgroundScheduler().runOneTask();
assertThat(responseCallbacks.successResponse, nullValue());
Robolectric.getUiThreadScheduler().runOneTask();
assertThat(asString(responseCallbacks.successResponse.getResponseDocument()), equalTo(GENERIC_XML));
}
private class TestGetRequest extends ApiRequest<XmlApiResponse> {
@Override
public String getUrlString() {
return "www.example.com";
}
@Override
public Map<String, String> getParameters() {
Map<String, String> parameters = super.getParameters();
parameters.put("baz", "bang");
return parameters;
}
@Override
public Map<String, String> getHeaders() {
Map<String, String> headers = super.getHeaders();
headers.put("foo", "bar");
return headers;
}
@Override
public String getMethod() {
return HttpGet.METHOD_NAME;
}
@Override
public String getPostBody() {
return super.getPostBody();
}
@Override
public String getUsername() {
return "spongebob";
}
@Override
public String getPassword() {
return "squarepants";
}
@Override
public XmlApiResponse createResponse(int statusCode) {
return new XmlApiResponse(statusCode);
}
}
private class TestPostRequest extends ApiRequest {
@Override
public String getUrlString() {
return "www.example.com";
}
@Override
public Map<String, String> getParameters() {
Map<String, String> parameters = super.getParameters();
parameters.put("baz", "bang");
return parameters;
}
@Override
public Map<String, String> getHeaders() {
Map<String, String> headers = super.getHeaders();
headers.put("foo", "bar");
return headers;
}
@Override
public String getMethod() {
return HttpPost.METHOD_NAME;
}
@Override
public String getPostBody() {
return "post body content";
}
@Override
public String getUsername() {
return "spongebob";
}
@Override
public String getPassword() {
return "squarepants";
}
@Override
public ApiResponse createResponse(int statusCode) {
return new XmlApiResponse(statusCode);
}
}
}