package com.goebl.david; import java.io.ByteArrayInputStream; import java.net.HttpURLConnection; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import junit.framework.TestCase; import org.json.JSONArray; import org.json.JSONObject; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyObject; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; public class TestWebbUtils_Mock extends TestCase { private Webb webb; public void setUp() throws Exception { super.setUp(); webb = Webb.create(); // not necessary to mock this } public void testAddRequestProperties() throws Exception { Date now = new Date(); Calendar calendar = Calendar.getInstance(); calendar.setTime(now); String dateStr = WebbUtils.getRfc1123DateFormat().format(now); HttpURLConnection connection = mock(HttpURLConnection.class); Map<String, Object> map = new HashMap<String, Object>(); map.put("date", now); map.put("calendar", calendar); map.put("int", 4711); map.put("bool", true); WebbUtils.addRequestProperties(connection, map); verify(connection).addRequestProperty("date", dateStr); verify(connection).addRequestProperty("calendar", dateStr); verify(connection).addRequestProperty("int", "4711"); verify(connection).addRequestProperty("bool", "true"); } public void testAddRequestProperties_Empty() throws Exception { HttpURLConnection connection = mock(HttpURLConnection.class); doThrow(new RuntimeException()).when(connection).addRequestProperty(anyString(), anyString()); WebbUtils.addRequestProperties(connection, null); } public void testAddRequestProperty() throws Exception { HttpURLConnection connection = mock(HttpURLConnection.class); WebbUtils.addRequestProperty(connection, "name1", "value1"); WebbUtils.addRequestProperty(connection, "name2", "value2"); verify(connection).addRequestProperty("name1", "value1"); verify(connection).addRequestProperty("name2", "value2"); } public void testEnsureRequestProperty() throws Exception { Map<String,List<String>> headers = new HashMap<String, List<String>>(); HttpURLConnection connection = mock(HttpURLConnection.class); when(connection.getRequestProperties()).thenReturn(headers); WebbUtils.ensureRequestProperty(connection, "name", "value"); verify(connection).addRequestProperty("name", "value"); } public void testGetPayloadAsBytesAndSetContentType_Form() throws Exception { Request request = new Request(webb, null, null); request.payload = null; request.params = new LinkedHashMap<String, Object>(); request.params.put("abc", 123); request.params.put("email", "abc@def.com"); HttpURLConnection connection = mock(HttpURLConnection.class); byte[] payload = WebbUtils.getPayloadAsBytesAndSetContentType(connection, request, false, -1); assertArrayEquals("abc=123&email=abc%40def.com".getBytes("UTF-8"), payload); verify(connection).setFixedLengthStreamingMode(payload.length); verify(connection).addRequestProperty(Const.HDR_CONTENT_TYPE, Const.APP_FORM); } public void testGetPayloadAsBytesAndSetContentType_null() throws Exception { Request request = new Request(webb, null, null); request.payload = null; HttpURLConnection connection = mock(HttpURLConnection.class); byte[] payload = WebbUtils.getPayloadAsBytesAndSetContentType(connection, request, false, -1); assertNull(payload); verify(connection, never()).setFixedLengthStreamingMode(anyInt()); verify(connection, never()).addRequestProperty(eq(Const.HDR_CONTENT_TYPE), anyString()); } public void testGetPayloadAsBytesAndSetContentType_JSONObject() throws Exception { Request request = new Request(webb, null, null); JSONObject json = new JSONObject(); json.put("int", 1); json.put("bool", true); json.put("str", "a string"); request.payload = json; byte[] expected = json.toString().getBytes("UTF-8"); HttpURLConnection connection = mock(HttpURLConnection.class); byte[] payload = WebbUtils.getPayloadAsBytesAndSetContentType(connection, request, false, -1); assertArrayEquals(expected, payload); verify(connection).setFixedLengthStreamingMode(expected.length); verify(connection).addRequestProperty(Const.HDR_CONTENT_TYPE, Const.APP_JSON); } public void testGetPayloadAsBytesAndSetContentType_JSONArray() throws Exception { Request request = new Request(webb, null, null); JSONArray json = new JSONArray(); json.put(1); json.put(true); json.put("a string"); request.payload = json; byte[] expected = json.toString().getBytes("UTF-8"); HttpURLConnection connection = mock(HttpURLConnection.class); byte[] payload = WebbUtils.getPayloadAsBytesAndSetContentType(connection, request, false, -1); assertArrayEquals(expected, payload); verify(connection).setFixedLengthStreamingMode(expected.length); verify(connection).addRequestProperty(Const.HDR_CONTENT_TYPE, Const.APP_JSON); } public void testGetPayloadAsBytesAndSetContentType_String() throws Exception { Request request = new Request(webb, null, null); String strPayload = "\"München 1 Maß 10 €\""; request.payload = strPayload; byte[] expected = strPayload.getBytes("UTF-8"); HttpURLConnection connection = mock(HttpURLConnection.class); byte[] payload = WebbUtils.getPayloadAsBytesAndSetContentType(connection, request, false, -1); assertArrayEquals(expected, payload); verify(connection).setFixedLengthStreamingMode(expected.length); verify(connection).addRequestProperty(Const.HDR_CONTENT_TYPE, Const.TEXT_PLAIN); } public void testGetPayloadAsBytesAndSetContentType_bytes() throws Exception { Request request = new Request(webb, null, null); String strPayload = "\"München 1 Maß 10 €\""; request.payload = strPayload.getBytes("UTF-8"); byte[] expected = strPayload.getBytes("UTF-8"); HttpURLConnection connection = mock(HttpURLConnection.class); byte[] payload = WebbUtils.getPayloadAsBytesAndSetContentType(connection, request, false, -1); assertArrayEquals(expected, payload); verify(connection).setFixedLengthStreamingMode(expected.length); verify(connection).addRequestProperty(Const.HDR_CONTENT_TYPE, Const.APP_BINARY); } public void testParseResponseBody() throws Exception { // String Response response = mock(Response.class); String expected = "München 1 Maß 10 €"; byte[] payloadInBytes = expected.getBytes("UTF-8"); ByteArrayInputStream payload = new ByteArrayInputStream(payloadInBytes); WebbUtils.parseResponseBody(String.class, response, payload); verify(response).setBody(expected); // byte[] response = mock(Response.class); payload.reset(); WebbUtils.parseResponseBody(Const.BYTE_ARRAY_CLASS, response, payload); verify(response).setBody(payloadInBytes); // void response = mock(Response.class); WebbUtils.parseResponseBody(Void.class, response, null); verify(response, never()).setBody(anyObject()); } public void testParseErrorBody() throws Exception { Response response = mock(Response.class); HttpURLConnection connection = mock(HttpURLConnection.class); response.connection = connection; String expected = "München 1 Maß 10 €"; byte[] payloadInBytes = expected.getBytes("UTF-8"); ByteArrayInputStream payload = new ByteArrayInputStream(payloadInBytes); // this call should not eat any of the getContentType() return values WebbUtils.parseErrorResponse(String.class, null, null); // without NPE it's OK! assertNull(response.errorBody); when(connection.getContentType()).thenReturn( Const.APP_BINARY, // 1 null, // 2 Const.APP_JSON, // 3 Const.APP_JSON, // 4 "text/plain; charset=UTF-8"); // 5 // (1) we expect a byte[] and Content-Type = app/bin => should be byte[] WebbUtils.parseErrorResponse(Const.BYTE_ARRAY_CLASS, response, payload); assertNotNull(response.errorBody); assertArrayEquals(payloadInBytes, (byte[]) response.errorBody); response.errorBody = null; payload.reset(); // (2) we expect a byte[] and Content-Type is null => should be byte[] WebbUtils.parseErrorResponse(Const.BYTE_ARRAY_CLASS, response, payload); assertNotNull(response.errorBody); assertArrayEquals(payloadInBytes, (byte[]) response.errorBody); response.errorBody = null; payload.reset(); // (3) we expect a String and Content-Type is JSON => should be String JSONObject jsonObject = new JSONObject(); jsonObject.put("msg", expected); payload = new ByteArrayInputStream(jsonObject.toString().getBytes(Const.UTF8)); WebbUtils.parseErrorResponse(String.class, response, payload); assertNotNull(response.errorBody); assertEquals(jsonObject.toString(), (String) response.errorBody); response.errorBody = null; payload.reset(); // (4) we expect JSON and Content-Type is JSON => should return JSON WebbUtils.parseErrorResponse(JSONObject.class, response, payload); assertNotNull(response.errorBody); assertEquals(JSONObject.class, response.errorBody.getClass()); assertEquals(jsonObject.toString(), ((JSONObject) response.errorBody).toString()); response.errorBody = null; payload.reset(); // (5) we expect JSON and Content-Type is text => should return String WebbUtils.parseErrorResponse(JSONObject.class, response, payload); assertNotNull(response.errorBody); assertEquals(String.class, response.errorBody.getClass()); assertEquals(jsonObject.toString(), response.errorBody); } private void assertArrayEquals(byte[] expected, byte[] bytes) { assertEquals("array length mismatch", expected.length, bytes.length); for (int i = 0; i < expected.length; i++) { if (expected[i] != bytes[i]) { fail(String.format("array different at index %d expected: %d, is: %d", i, expected[i], bytes[i])); } } } }