1/* 2 * Copyright (C) 2010 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.i18n.addressinput; 18 19import com.android.i18n.addressinput.JsonpRequestBuilder.AsyncCallback; 20import com.android.i18n.addressinput.testing.AsyncTestCase; 21 22import java.io.IOException; 23import java.io.InputStream; 24import java.io.OutputStream; 25import java.net.ServerSocket; 26import java.net.Socket; 27import java.net.SocketTimeoutException; 28 29public class JsonpRequestBuilderTest extends AsyncTestCase { 30 private JsonpRequestBuilder builder; 31 32 @Override 33 public void setUp() { 34 builder = new JsonpRequestBuilder(); 35 } 36 37 public void testRequestObject() throws Exception { 38 delayTestFinish(4000); 39 builder.setTimeout(2000); 40 41 String url = HttpServer.execute(1000, "{\"id\": \"data\"}"); 42 43 builder.requestObject(url, new AsyncCallback<JsoMap>() { 44 @Override 45 public void onFailure(Throwable caught) { 46 fail(caught.toString()); 47 } 48 49 @Override 50 public void onSuccess(JsoMap result) { 51 assertNotNull(result); 52 assertEquals("data", result.get("id")); 53 finishTest(); 54 } 55 }); 56 } 57 58 public void testSetTimeout() throws Exception { 59 delayTestFinish(4000); 60 builder.setTimeout(1000); 61 62 String url = HttpServer.execute(2000, "Fubar"); 63 64 builder.requestObject(url, new AsyncCallback<JsoMap>() { 65 @Override 66 public void onFailure(Throwable caught) { 67 assertNotNull(caught); 68 assertTrue(caught instanceof SocketTimeoutException); 69 finishTest(); 70 } 71 72 @Override 73 public void onSuccess(JsoMap result) { 74 fail("The request should have timed out."); 75 } 76 }); 77 } 78 79 public void testUrlEncoding() throws Exception { 80 delayTestFinish(4000); 81 builder.setTimeout(2000); 82 83 String urlBase = HttpServer.execute(1000, "{\"id\": \"data\"}"); 84 String url = urlBase + "address/data/VN/B\u1EAFc K\u1EA1n"; 85 86 builder.requestObject(url, new AsyncCallback<JsoMap>() { 87 @Override 88 public void onFailure(Throwable caught) { 89 fail(caught.toString()); 90 } 91 92 @Override 93 public void onSuccess(JsoMap result) { 94 assertNotNull(result); 95 assertEquals("data", result.get("id")); 96 finishTest(); 97 } 98 }); 99 } 100 101 /** 102 * Simple implementation of an HTTP server. 103 */ 104 private static class HttpServer extends Thread { 105 /** 106 * Start an HTTP server that will serve one request and then terminate. 107 * 108 * @param timeoutMillis 109 * Wait this long before answering a request. 110 * @param response 111 * Reply to any request with this response. 112 * @return The URL to the server. 113 * @throws IOException 114 */ 115 public static String execute(long timeoutMillis, String response) throws IOException { 116 HttpServer server = new HttpServer(timeoutMillis, response); 117 server.start(); 118 return "http://localhost:" + server.serverSocket.getLocalPort() + "/"; 119 } 120 121 @Override 122 public void run() { 123 try { 124 Socket clientSocket = serverSocket.accept(); 125 try { 126 synchronized (this) { 127 wait(waitMillis); 128 } 129 } catch (InterruptedException e) { 130 throw new RuntimeException(e); 131 } 132 InputStream inputStream = clientSocket.getInputStream(); 133 inputStream.read(new byte[1024]); // Discard input. 134 OutputStream outputStream = clientSocket.getOutputStream(); 135 outputStream.write(response); 136 outputStream.close(); 137 inputStream.close(); 138 clientSocket.close(); 139 serverSocket.close(); 140 } catch (IOException e) { 141 throw new RuntimeException(e); 142 } 143 } 144 145 private HttpServer(long waitMillis, String response) throws IOException { 146 this.waitMillis = waitMillis; 147 this.response = (header + response).getBytes(); 148 serverSocket = new ServerSocket(0); 149 } 150 151 private long waitMillis; 152 private byte[] response; 153 private ServerSocket serverSocket; 154 155 private static final String header = "HTTP/1.0 200 OK\nContent-Type: text/plain\n\n"; 156 } 157} 158