1 package com.xtremelabs.robolectric.shadows; 2 3 import com.xtremelabs.robolectric.Robolectric; 4 import com.xtremelabs.robolectric.WithTestDefaultsRunner; 5 import com.xtremelabs.robolectric.tester.org.apache.http.FakeHttpLayer; 6 import com.xtremelabs.robolectric.tester.org.apache.http.RequestMatcher; 7 import com.xtremelabs.robolectric.tester.org.apache.http.TestHttpResponse; 8 import com.xtremelabs.robolectric.util.Strings; 9 import junit.framework.Assert; 10 import org.apache.http.HttpRequest; 11 import org.apache.http.HttpResponse; 12 import org.apache.http.client.methods.HttpGet; 13 import org.apache.http.client.methods.HttpPost; 14 import org.apache.http.client.methods.HttpUriRequest; 15 import org.apache.http.conn.ConnectTimeoutException; 16 import org.apache.http.conn.ConnectionKeepAliveStrategy; 17 import org.apache.http.impl.client.BasicResponseHandler; 18 import org.apache.http.impl.client.DefaultHttpClient; 19 import org.apache.http.impl.client.DefaultRequestDirector; 20 import org.apache.http.message.BasicHeader; 21 import org.apache.http.params.HttpConnectionParams; 22 import org.apache.http.params.HttpParams; 23 import org.apache.http.protocol.HttpContext; 24 import org.junit.After; 25 import org.junit.Before; 26 import org.junit.Test; 27 import org.junit.runner.RunWith; 28 29 import java.io.IOException; 30 import java.io.InputStream; 31 import java.net.URI; 32 33 import static com.xtremelabs.robolectric.Robolectric.shadowOf; 34 import static org.hamcrest.core.IsEqual.equalTo; 35 import static org.junit.Assert.*; 36 37 @RunWith(WithTestDefaultsRunner.class) 38 public class DefaultRequestDirectorTest { 39 private DefaultRequestDirector requestDirector; 40 private ConnectionKeepAliveStrategy connectionKeepAliveStrategy; 41 42 @Before setUp_EnsureStaticStateIsReset()43 public void setUp_EnsureStaticStateIsReset() { 44 FakeHttpLayer fakeHttpLayer = Robolectric.getFakeHttpLayer(); 45 assertFalse(fakeHttpLayer.hasPendingResponses()); 46 assertFalse(fakeHttpLayer.hasRequestInfos()); 47 assertFalse(fakeHttpLayer.hasResponseRules()); 48 assertNull(fakeHttpLayer.getDefaultResponse()); 49 50 connectionKeepAliveStrategy = new ConnectionKeepAliveStrategy() { 51 @Override public long getKeepAliveDuration(HttpResponse httpResponse, HttpContext httpContext) { 52 return 0; 53 } 54 }; 55 requestDirector = new DefaultRequestDirector(null, null, null, connectionKeepAliveStrategy, null, null, null, null, null, null, null, null); 56 } 57 58 @After tearDown_EnsureStaticStateIsReset()59 public void tearDown_EnsureStaticStateIsReset() throws Exception { 60 Robolectric.addPendingHttpResponse(200, "a happy response body"); 61 } 62 63 @Test shouldGetHttpResponseFromExecute()64 public void shouldGetHttpResponseFromExecute() throws Exception { 65 Robolectric.addPendingHttpResponse(new TestHttpResponse(200, "a happy response body")); 66 HttpResponse response = requestDirector.execute(null, new HttpGet("http://example.com"), null); 67 68 assertNotNull(response); 69 assertThat(response.getStatusLine().getStatusCode(), equalTo(200)); 70 assertThat(Strings.fromStream(response.getEntity().getContent()), equalTo("a happy response body")); 71 } 72 73 @Test shouldPreferPendingResponses()74 public void shouldPreferPendingResponses() throws Exception { 75 Robolectric.addPendingHttpResponse(new TestHttpResponse(200, "a happy response body")); 76 77 Robolectric.addHttpResponseRule(HttpGet.METHOD_NAME, "http://some.uri", 78 new TestHttpResponse(200, "a cheery response body")); 79 80 HttpResponse response = requestDirector.execute(null, new HttpGet("http://some.uri"), null); 81 82 assertNotNull(response); 83 assertThat(response.getStatusLine().getStatusCode(), equalTo(200)); 84 assertThat(Strings.fromStream(response.getEntity().getContent()), equalTo("a happy response body")); 85 } 86 87 @Test shouldReturnRequestsByRule()88 public void shouldReturnRequestsByRule() throws Exception { 89 Robolectric.addHttpResponseRule(HttpGet.METHOD_NAME, "http://some.uri", 90 new TestHttpResponse(200, "a cheery response body")); 91 92 HttpResponse response = requestDirector.execute(null, new HttpGet("http://some.uri"), null); 93 94 assertNotNull(response); 95 assertThat(response.getStatusLine().getStatusCode(), equalTo(200)); 96 assertThat(Strings.fromStream(response.getEntity().getContent()), equalTo("a cheery response body")); 97 } 98 99 @Test shouldReturnRequestsByRule_MatchingMethod()100 public void shouldReturnRequestsByRule_MatchingMethod() throws Exception { 101 Robolectric.setDefaultHttpResponse(404, "no such page"); 102 Robolectric.addHttpResponseRule(HttpPost.METHOD_NAME, "http://some.uri", 103 new TestHttpResponse(200, "a cheery response body")); 104 105 HttpResponse response = requestDirector.execute(null, new HttpGet("http://some.uri"), null); 106 107 assertNotNull(response); 108 assertThat(response.getStatusLine().getStatusCode(), equalTo(404)); 109 } 110 111 @Test shouldReturnRequestsByRule_AnyMethod()112 public void shouldReturnRequestsByRule_AnyMethod() throws Exception { 113 Robolectric.addHttpResponseRule("http://some.uri", new TestHttpResponse(200, "a cheery response body")); 114 115 HttpResponse getResponse = requestDirector.execute(null, new HttpGet("http://some.uri"), null); 116 assertNotNull(getResponse); 117 assertThat(getResponse.getStatusLine().getStatusCode(), equalTo(200)); 118 assertThat(Strings.fromStream(getResponse.getEntity().getContent()), equalTo("a cheery response body")); 119 120 HttpResponse postResponse = requestDirector.execute(null, new HttpPost("http://some.uri"), null); 121 assertNotNull(postResponse); 122 assertThat(postResponse.getStatusLine().getStatusCode(), equalTo(200)); 123 assertThat(Strings.fromStream(postResponse.getEntity().getContent()), equalTo("a cheery response body")); 124 } 125 126 @Test shouldReturnRequestsByRule_KeepsTrackOfOpenContentStreams()127 public void shouldReturnRequestsByRule_KeepsTrackOfOpenContentStreams() throws Exception { 128 TestHttpResponse testHttpResponse = new TestHttpResponse(200, "a cheery response body"); 129 Robolectric.addHttpResponseRule("http://some.uri", testHttpResponse); 130 131 assertThat(testHttpResponse.entityContentStreamsHaveBeenClosed(), equalTo(true)); 132 133 HttpResponse getResponse = requestDirector.execute(null, new HttpGet("http://some.uri"), null); 134 InputStream getResponseStream = getResponse.getEntity().getContent(); 135 assertThat(Strings.fromStream(getResponseStream), equalTo("a cheery response body")); 136 assertThat(testHttpResponse.entityContentStreamsHaveBeenClosed(), equalTo(false)); 137 138 HttpResponse postResponse = requestDirector.execute(null, new HttpPost("http://some.uri"), null); 139 InputStream postResponseStream = postResponse.getEntity().getContent(); 140 assertThat(Strings.fromStream(postResponseStream), equalTo("a cheery response body")); 141 assertThat(testHttpResponse.entityContentStreamsHaveBeenClosed(), equalTo(false)); 142 143 getResponseStream.close(); 144 assertThat(testHttpResponse.entityContentStreamsHaveBeenClosed(), equalTo(false)); 145 146 postResponseStream.close(); 147 assertThat(testHttpResponse.entityContentStreamsHaveBeenClosed(), equalTo(true)); 148 } 149 150 @Test shouldReturnRequestsByRule_WithTextResponse()151 public void shouldReturnRequestsByRule_WithTextResponse() throws Exception { 152 Robolectric.addHttpResponseRule("http://some.uri", "a cheery response body"); 153 154 HttpResponse response = requestDirector.execute(null, new HttpGet("http://some.uri"), null); 155 156 assertNotNull(response); 157 assertThat(response.getStatusLine().getStatusCode(), equalTo(200)); 158 assertThat(Strings.fromStream(response.getEntity().getContent()), equalTo("a cheery response body")); 159 } 160 161 @Test clearHttpResponseRules_shouldRemoveAllRules()162 public void clearHttpResponseRules_shouldRemoveAllRules() throws Exception { 163 Robolectric.addHttpResponseRule("http://some.uri", "a cheery response body"); 164 Robolectric.clearHttpResponseRules(); 165 Robolectric.addHttpResponseRule("http://some.uri", "a gloomy response body"); 166 167 HttpResponse response = requestDirector.execute(null, new HttpGet("http://some.uri"), null); 168 169 assertNotNull(response); 170 assertThat(response.getStatusLine().getStatusCode(), equalTo(200)); 171 assertThat(Strings.fromStream(response.getEntity().getContent()), equalTo("a gloomy response body")); 172 } 173 174 @Test clearPendingHttpResponses()175 public void clearPendingHttpResponses() throws Exception { 176 Robolectric.addPendingHttpResponse(200, "earlier"); 177 Robolectric.clearPendingHttpResponses(); 178 Robolectric.addPendingHttpResponse(500, "later"); 179 180 HttpResponse response = requestDirector.execute(null, new HttpGet("http://some.uri"), null); 181 182 assertNotNull(response); 183 assertThat(response.getStatusLine().getStatusCode(), equalTo(500)); 184 assertThat(Strings.fromStream(response.getEntity().getContent()), equalTo("later")); 185 } 186 187 @Test shouldReturnRequestsByRule_WithCustomRequestMatcher()188 public void shouldReturnRequestsByRule_WithCustomRequestMatcher() throws Exception { 189 Robolectric.setDefaultHttpResponse(404, "no such page"); 190 191 Robolectric.addHttpResponseRule(new RequestMatcher() { 192 @Override public boolean matches(HttpRequest request) { 193 return request.getRequestLine().getUri().equals("http://matching.uri"); 194 } 195 }, new TestHttpResponse(200, "a cheery response body")); 196 197 HttpResponse response = requestDirector.execute(null, new HttpGet("http://matching.uri"), null); 198 assertNotNull(response); 199 assertThat(response.getStatusLine().getStatusCode(), equalTo(200)); 200 assertThat(Strings.fromStream(response.getEntity().getContent()), equalTo("a cheery response body")); 201 202 response = requestDirector.execute(null, new HttpGet("http://non-matching.uri"), null); 203 assertNotNull(response); 204 assertThat(response.getStatusLine().getStatusCode(), equalTo(404)); 205 assertThat(Strings.fromStream(response.getEntity().getContent()), equalTo("no such page")); 206 } 207 208 @Test shouldGetHttpResponseFromExecuteSimpleApi()209 public void shouldGetHttpResponseFromExecuteSimpleApi() throws Exception { 210 Robolectric.addPendingHttpResponse(200, "a happy response body"); 211 HttpResponse response = requestDirector.execute(null, new HttpGet("http://example.com"), null); 212 213 assertThat(response.getStatusLine().getStatusCode(), equalTo(200)); 214 assertThat(Strings.fromStream(response.getEntity().getContent()), equalTo("a happy response body")); 215 } 216 217 @Test shouldHandleMultipleInvocations()218 public void shouldHandleMultipleInvocations() throws Exception { 219 Robolectric.addPendingHttpResponse(200, "a happy response body"); 220 Robolectric.addPendingHttpResponse(201, "another happy response body"); 221 222 HttpResponse response1 = requestDirector.execute(null, new HttpGet("http://example.com"), null); 223 HttpResponse response2 = requestDirector.execute(null, new HttpGet("www.example.com"), null); 224 225 assertThat(response1.getStatusLine().getStatusCode(), equalTo(200)); 226 assertThat(Strings.fromStream(response1.getEntity().getContent()), equalTo("a happy response body")); 227 228 assertThat(response2.getStatusLine().getStatusCode(), equalTo(201)); 229 assertThat(Strings.fromStream(response2.getEntity().getContent()), equalTo("another happy response body")); 230 } 231 232 @Test shouldHandleMultipleInvocationsOfExecute()233 public void shouldHandleMultipleInvocationsOfExecute() throws Exception { 234 Robolectric.addPendingHttpResponse(200, "a happy response body"); 235 Robolectric.addPendingHttpResponse(201, "another happy response body"); 236 237 requestDirector.execute(null, new HttpGet("http://example.com"), null); 238 requestDirector.execute(null, new HttpGet("www.example.com"), null); 239 240 HttpUriRequest request1 = (HttpUriRequest) Robolectric.getSentHttpRequest(0); 241 assertThat(request1.getMethod(), equalTo(HttpGet.METHOD_NAME)); 242 assertThat(request1.getURI(), equalTo(URI.create("http://example.com"))); 243 244 HttpUriRequest request2 = (HttpUriRequest) Robolectric.getSentHttpRequest(1); 245 assertThat(request2.getMethod(), equalTo(HttpGet.METHOD_NAME)); 246 assertThat(request2.getURI(), equalTo(URI.create("www.example.com"))); 247 } 248 249 @Test shouldRejectUnexpectedCallsToExecute()250 public void shouldRejectUnexpectedCallsToExecute() throws Exception { 251 try { 252 requestDirector.execute(null, new HttpGet("http://example.com"), null); 253 fail(); 254 } catch (RuntimeException expected) { 255 assertThat(expected.getMessage(), equalTo("Unexpected call to execute, no pending responses are available. See Robolectric.addPendingResponse(). Request was: GET http://example.com")); 256 } 257 } 258 259 @Test shouldRecordExtendedRequestData()260 public void shouldRecordExtendedRequestData() throws Exception { 261 Robolectric.addPendingHttpResponse(200, "a happy response body"); 262 HttpGet httpGet = new HttpGet("http://example.com"); 263 requestDirector.execute(null, httpGet, null); 264 265 assertSame(Robolectric.getSentHttpRequestInfo(0).getHttpRequest(), httpGet); 266 ConnectionKeepAliveStrategy strategy = shadowOf((DefaultRequestDirector) Robolectric.getSentHttpRequestInfo(0).getRequestDirector()).getConnectionKeepAliveStrategy(); 267 assertSame(strategy, connectionKeepAliveStrategy); 268 } 269 270 @Test shouldSupportBasicResponseHandlerHandleResponse()271 public void shouldSupportBasicResponseHandlerHandleResponse() throws Exception { 272 Robolectric.addPendingHttpResponse(200, "OK", new BasicHeader("Content-Type", "text/plain")); 273 274 DefaultHttpClient client = new DefaultHttpClient(); 275 HttpResponse response = client.execute(new HttpGet("http://www.nowhere.org")); 276 277 assertThat(((HttpUriRequest) Robolectric.getSentHttpRequest(0)).getURI(), 278 equalTo(URI.create("http://www.nowhere.org"))); 279 280 Assert.assertNotNull(response); 281 String responseStr = new BasicResponseHandler().handleResponse(response); 282 Assert.assertEquals("OK", responseStr); 283 } 284 285 @Test shouldFindLastRequestMade()286 public void shouldFindLastRequestMade() throws Exception { 287 Robolectric.addPendingHttpResponse(200, "a happy response body"); 288 Robolectric.addPendingHttpResponse(200, "a happy response body"); 289 Robolectric.addPendingHttpResponse(200, "a happy response body"); 290 291 DefaultHttpClient client = new DefaultHttpClient(); 292 client.execute(new HttpGet("http://www.first.org")); 293 client.execute(new HttpGet("http://www.second.org")); 294 client.execute(new HttpGet("http://www.third.org")); 295 296 assertThat(((HttpUriRequest) Robolectric.getLatestSentHttpRequest()).getURI(), 297 equalTo(URI.create("http://www.third.org"))); 298 } 299 300 301 @Test shouldSupportConnectionTimeoutWithExceptions()302 public void shouldSupportConnectionTimeoutWithExceptions() throws Exception { 303 Robolectric.setDefaultHttpResponse(new TestHttpResponse() { 304 @Override 305 public HttpParams getParams() { 306 HttpParams httpParams = super.getParams(); 307 HttpConnectionParams.setConnectionTimeout(httpParams, -1); 308 return httpParams; 309 } 310 }); 311 312 DefaultHttpClient client = new DefaultHttpClient(); 313 try { 314 client.execute(new HttpGet("http://www.nowhere.org")); 315 } catch (ConnectTimeoutException x) { 316 return; 317 } 318 319 fail("Exception should have been thrown"); 320 } 321 322 @Test shouldSupportSocketTimeoutWithExceptions()323 public void shouldSupportSocketTimeoutWithExceptions() throws Exception { 324 Robolectric.setDefaultHttpResponse(new TestHttpResponse() { 325 @Override 326 public HttpParams getParams() { 327 HttpParams httpParams = super.getParams(); 328 HttpConnectionParams.setSoTimeout(httpParams, -1); 329 return httpParams; 330 } 331 }); 332 333 DefaultHttpClient client = new DefaultHttpClient(); 334 try { 335 client.execute(new HttpGet("http://www.nowhere.org")); 336 } catch (ConnectTimeoutException x) { 337 return; 338 } 339 340 fail("Exception should have been thrown"); 341 } 342 343 @Test(expected = IOException.class) shouldSupportRealHttpRequests()344 public void shouldSupportRealHttpRequests() throws Exception { 345 Robolectric.getFakeHttpLayer().interceptHttpRequests(false); 346 DefaultHttpClient client = new DefaultHttpClient(); 347 client.execute(new HttpGet("http://www.this-host-should-not-exist-123456790.org:999")); 348 } 349 350 @Test shouldReturnResponseFromHttpResponseGenerator()351 public void shouldReturnResponseFromHttpResponseGenerator() throws Exception { 352 Robolectric.addPendingHttpResponse(new HttpResponseGenerator() { 353 @Override 354 public HttpResponse getResponse(HttpRequest request) { 355 return new TestHttpResponse(200, "a happy response body"); 356 } 357 }); 358 HttpResponse response = requestDirector.execute(null, new HttpGet("http://example.com"), null); 359 360 assertNotNull(response); 361 assertThat(response.getStatusLine().getStatusCode(), equalTo(200)); 362 assertThat(Strings.fromStream(response.getEntity().getContent()), equalTo("a happy response body")); 363 } 364 365 } 366