| /* |
| * Copyright (C) 2011 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.google.mockwebserver; |
| |
| import java.io.BufferedReader; |
| import java.io.ByteArrayInputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.net.HttpURLConnection; |
| import java.net.SocketTimeoutException; |
| import java.net.URL; |
| import java.net.URLConnection; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.List; |
| import junit.framework.TestCase; |
| |
| public final class MockWebServerTest extends TestCase { |
| |
| private MockWebServer server = new MockWebServer(); |
| |
| @Override protected void tearDown() throws Exception { |
| server.shutdown(); |
| super.tearDown(); |
| } |
| |
| public void testRecordedRequestAccessors() { |
| List<String> headers = Arrays.asList( |
| "User-Agent: okhttp", |
| "Cookie: s=square", |
| "Cookie: a=android", |
| "X-Whitespace: left", |
| "X-Whitespace:right ", |
| "X-Whitespace: both " |
| ); |
| List<Integer> chunkSizes = Collections.emptyList(); |
| byte[] body = {'A', 'B', 'C'}; |
| String requestLine = "GET / HTTP/1.1"; |
| RecordedRequest request = new RecordedRequest( |
| requestLine, headers, chunkSizes, body.length, body, 0, null); |
| assertEquals("s=square", request.getHeader("cookie")); |
| assertEquals(Arrays.asList("s=square", "a=android"), request.getHeaders("cookie")); |
| assertEquals("left", request.getHeader("x-whitespace")); |
| assertEquals(Arrays.asList("left", "right", "both"), request.getHeaders("x-whitespace")); |
| assertEquals("ABC", request.getUtf8Body()); |
| } |
| |
| public void testDefaultMockResponse() { |
| MockResponse response = new MockResponse(); |
| assertEquals(Arrays.asList("Content-Length: 0"), response.getHeaders()); |
| assertEquals("HTTP/1.1 200 OK", response.getStatus()); |
| } |
| |
| public void testSetBodyAdjustsHeaders() throws IOException { |
| MockResponse response = new MockResponse().setBody("ABC"); |
| assertEquals(Arrays.asList("Content-Length: 3"), response.getHeaders()); |
| InputStream in = response.getBodyStream(); |
| assertEquals('A', in.read()); |
| assertEquals('B', in.read()); |
| assertEquals('C', in.read()); |
| assertEquals(-1, in.read()); |
| assertEquals("HTTP/1.1 200 OK", response.getStatus()); |
| } |
| |
| public void testMockResponseAddHeader() { |
| MockResponse response = new MockResponse() |
| .clearHeaders() |
| .addHeader("Cookie: s=square") |
| .addHeader("Cookie", "a=android"); |
| assertEquals(Arrays.asList("Cookie: s=square", "Cookie: a=android"), |
| response.getHeaders()); |
| } |
| |
| public void testMockResponseSetHeader() { |
| MockResponse response = new MockResponse() |
| .clearHeaders() |
| .addHeader("Cookie: s=square") |
| .addHeader("Cookie: a=android") |
| .addHeader("Cookies: delicious"); |
| response.setHeader("cookie", "r=robot"); |
| assertEquals(Arrays.asList("Cookies: delicious", "cookie: r=robot"), |
| response.getHeaders()); |
| } |
| |
| public void testRegularResponse() throws Exception { |
| server.enqueue(new MockResponse().setBody("hello world")); |
| server.play(); |
| |
| URL url = server.getUrl("/"); |
| HttpURLConnection connection = (HttpURLConnection) url.openConnection(); |
| connection.setRequestProperty("Accept-Language", "en-US"); |
| InputStream in = connection.getInputStream(); |
| BufferedReader reader = new BufferedReader(new InputStreamReader(in)); |
| assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); |
| assertEquals("hello world", reader.readLine()); |
| |
| RecordedRequest request = server.takeRequest(); |
| assertEquals("GET / HTTP/1.1", request.getRequestLine()); |
| assertTrue(request.getHeaders().contains("Accept-Language: en-US")); |
| } |
| |
| public void testRedirect() throws Exception { |
| server.play(); |
| server.enqueue(new MockResponse() |
| .setResponseCode(HttpURLConnection.HTTP_MOVED_TEMP) |
| .addHeader("Location: " + server.getUrl("/new-path")) |
| .setBody("This page has moved!")); |
| server.enqueue(new MockResponse().setBody("This is the new location!")); |
| |
| URLConnection connection = server.getUrl("/").openConnection(); |
| InputStream in = connection.getInputStream(); |
| BufferedReader reader = new BufferedReader(new InputStreamReader(in)); |
| assertEquals("This is the new location!", reader.readLine()); |
| |
| RecordedRequest first = server.takeRequest(); |
| assertEquals("GET / HTTP/1.1", first.getRequestLine()); |
| RecordedRequest redirect = server.takeRequest(); |
| assertEquals("GET /new-path HTTP/1.1", redirect.getRequestLine()); |
| } |
| |
| /** |
| * Test that MockWebServer blocks for a call to enqueue() if a request |
| * is made before a mock response is ready. |
| */ |
| public void testDispatchBlocksWaitingForEnqueue() throws Exception { |
| server.play(); |
| |
| new Thread() { |
| @Override public void run() { |
| try { |
| Thread.sleep(1000); |
| } catch (InterruptedException ignored) { |
| } |
| server.enqueue(new MockResponse().setBody("enqueued in the background")); |
| } |
| }.start(); |
| |
| URLConnection connection = server.getUrl("/").openConnection(); |
| InputStream in = connection.getInputStream(); |
| BufferedReader reader = new BufferedReader(new InputStreamReader(in)); |
| assertEquals("enqueued in the background", reader.readLine()); |
| } |
| |
| public void testNonHexadecimalChunkSize() throws Exception { |
| server.enqueue(new MockResponse() |
| .setBody("G\r\nxxxxxxxxxxxxxxxx\r\n0\r\n\r\n") |
| .clearHeaders() |
| .addHeader("Transfer-encoding: chunked")); |
| server.play(); |
| |
| URLConnection connection = server.getUrl("/").openConnection(); |
| InputStream in = connection.getInputStream(); |
| try { |
| in.read(); |
| fail(); |
| } catch (IOException expected) { |
| } |
| } |
| |
| public void testResponseTimeout() throws Exception { |
| server.enqueue(new MockResponse() |
| .setBody("ABC") |
| .clearHeaders() |
| .addHeader("Content-Length: 4")); |
| server.enqueue(new MockResponse() |
| .setBody("DEF")); |
| server.play(); |
| |
| URLConnection urlConnection = server.getUrl("/").openConnection(); |
| urlConnection.setReadTimeout(1000); |
| InputStream in = urlConnection.getInputStream(); |
| assertEquals('A', in.read()); |
| assertEquals('B', in.read()); |
| assertEquals('C', in.read()); |
| try { |
| in.read(); // if Content-Length was accurate, this would return -1 immediately |
| fail(); |
| } catch (SocketTimeoutException expected) { |
| } |
| |
| URLConnection urlConnection2 = server.getUrl("/").openConnection(); |
| InputStream in2 = urlConnection2.getInputStream(); |
| assertEquals('D', in2.read()); |
| assertEquals('E', in2.read()); |
| assertEquals('F', in2.read()); |
| assertEquals(-1, in2.read()); |
| |
| assertEquals(0, server.takeRequest().getSequenceNumber()); |
| assertEquals(0, server.takeRequest().getSequenceNumber()); |
| } |
| |
| public void testDisconnectAtStart() throws Exception { |
| server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.DISCONNECT_AT_START)); |
| server.enqueue(new MockResponse()); // The jdk's HttpUrlConnection is a bastard. |
| server.enqueue(new MockResponse()); |
| server.play(); |
| try { |
| server.getUrl("/a").openConnection().getInputStream(); |
| } catch (IOException e) { |
| // Expected. |
| } |
| server.getUrl("/b").openConnection().getInputStream(); // Should succeed. |
| } |
| |
| public void testStreamingResponseBody() throws Exception { |
| InputStream responseBody = new ByteArrayInputStream("ABC".getBytes("UTF-8")); |
| server.enqueue(new MockResponse().setBody(responseBody, 3)); |
| server.play(); |
| |
| InputStream in = server.getUrl("/").openConnection().getInputStream(); |
| assertEquals('A', in.read()); |
| assertEquals('B', in.read()); |
| assertEquals('C', in.read()); |
| |
| assertEquals(-1, responseBody.read()); // The body is exhausted. |
| } |
| } |