/*
* Copyright 2014, The Sporting Exchange Limited
*
* 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.betfair.cougar.marshalling.impl.databinding.json;
import com.betfair.cougar.api.ResponseCode;
import com.betfair.cougar.core.api.exception.CougarMarshallingException;
import com.betfair.cougar.core.api.exception.CougarServiceException;
import com.betfair.cougar.core.api.exception.CougarValidationException;
import com.betfair.cougar.core.api.fault.CougarFault;
import com.betfair.cougar.core.api.transcription.ParameterType;
import com.betfair.cougar.marshalling.api.databinding.FaultUnMarshaller;
import com.betfair.cougar.marshalling.api.databinding.UnMarshaller;
import com.betfair.cougar.test.CougarTestCase;
import com.betfair.cougar.util.dates.DateTimeUtility;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.mockito.Mockito;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.*;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.when;
public class JSONUnMarshallerTest extends CougarTestCase {
UnMarshaller unMarshaller = new JSONBindingFactory().getUnMarshaller();
private static final ParameterType TEST_DATE_CLASS_PARAMETER_TYPE = new ParameterType(TestDateClass.class, null);
private static final ParameterType TEST_CLASS_PARAMETER_TYPE = new ParameterType(TestClass.class, null);
private static final String UTF8 = "UTF-8";
public void testUnMarshal() {
JSONUnMarshaller unMarshaller = new JSONUnMarshaller(new ObjectMapper());
TestClass test = (TestClass)unMarshaller.unmarshall(new ByteArrayInputStream("{\"message\":\"foo\"}".getBytes()), TestClass.class, UTF8, false);
assertEquals("foo", test.getMessage());
}
public void testUnMarshalExtraField() {
JSONUnMarshaller unMarshaller = new JSONUnMarshaller(new ObjectMapper());
TestClass test = (TestClass)unMarshaller.unmarshall(new ByteArrayInputStream("{\"message\":\"foo\", \"xtra\":\"bar\"}".getBytes()), TestClass.class, UTF8, false);
assertEquals("foo", test.getMessage());
}
public void testUnMarshalParseException() {
JSONUnMarshaller unMarshaller = new JSONUnMarshaller(new ObjectMapper());
try {
unMarshaller.unmarshall(new ByteArrayInputStream("{\"message\":\"foo\"".getBytes()), TestClass.class, UTF8, false);
fail();
} catch (CougarMarshallingException dve) {
assertEquals(ResponseCode.BadRequest, dve.getResponseCode());
}
}
public void testUnMarshallDateByParam() {
testDateByJavaType("2011-03-07T11:02:01.095Z", "2011-03-07T11:02:01.095Z", TEST_DATE_CLASS_PARAMETER_TYPE);
testDateByJavaType("2009-07-05T00:00:00.001Z", "2009-07-05T00:00:00.001Z", TEST_DATE_CLASS_PARAMETER_TYPE);
testDateByJavaType("2009-07-05", "2009-07-05T00:00:00.000Z", TEST_DATE_CLASS_PARAMETER_TYPE);
testDateByJavaType("2009-07-05T00:00:01", "2009-07-05T00:00:01.000Z", TEST_DATE_CLASS_PARAMETER_TYPE);
}
public void testUnMarshalDate() {
TestDateClass test = (TestDateClass)unMarshaller.unmarshall(
new ByteArrayInputStream("{\"date\":\"2011-03-07T11:02:01.095Z\"}".getBytes()),
TestDateClass.class,
UTF8, false);
Date date = DateTimeUtility.parse("2011-03-07T11:02:01.095Z");
assertEquals("Mon Mar 07 11:02:01 UTC 2011", test.getDate().toString());
assertEquals(date, test.getDate());
testDate("2011-03-07T11:02:01.095Z","2011-03-07T11:02:01.095Z");
testDate("2009-07-05T00:00:00.001Z","2009-07-05T00:00:00.001Z");
testDate("2009-07-05","2009-07-05T00:00:00.000Z");
testDate("2009-07-05T00:00:01","2009-07-05T00:00:01.000Z");
}
private void testDate(String in,String out){
TestDateClass test = (TestDateClass)unMarshaller.unmarshall(
new ByteArrayInputStream(("{\"date\":\""+in+"\"}").getBytes()),
TestDateClass.class,
UTF8, false);
Date date=DateTimeUtility.parse(out);
assertEquals(date, test.getDate());
}
public void testListMarshallingByJavaType() {
String[] strings = {
"West Indies",
"England",
"Australia"
};
StringBuilder sb = new StringBuilder("[");
for (int i=0; i<strings.length; i++) {
if (i>0) {
sb.append(",");
}
sb.append("\"");
sb.append(strings[i]);
sb.append("\"");
}
sb.append("]");
ParameterType pt = ParameterType.create(List.class, new Class[] { String.class });
JSONUnMarshaller unMarshaller = new JSONUnMarshaller(new ObjectMapper());
List<String> actual = (List<String>)unMarshaller.unmarshall(new ByteArrayInputStream(sb.toString().getBytes()), pt, UTF8, false);
assertEqualsArray(strings, actual.toArray());
}
public void testMapMarshallingByJavaType() {
Map<String, String> map = new HashMap<>();
//Cricket world cup was on - teams rated
map.put("India", "Very good");
map.put("Australia", "Fair");
map.put("England", "Unlikely");
map.put("South Africa", "Fair");
StringBuilder sb = new StringBuilder("{");
int i=0;
for (String s : map.keySet()) {
if (i++ > 0) {
sb.append(",");
}
sb.append("\"");
sb.append(s);
sb.append("\":");
sb.append("\"");
sb.append(map.get(s));
sb.append("\"");
}
sb.append("}");
ParameterType pt = ParameterType.create(Map.class, new Class[] { String.class, String.class });
JSONUnMarshaller unMarshaller = new JSONUnMarshaller(new ObjectMapper());
Map<String,String> actual = (Map<String,String>)unMarshaller.unmarshall(new ByteArrayInputStream(sb.toString().getBytes()), pt, UTF8, false);
assertEqualsArray(map.keySet().toArray(), actual.keySet().toArray());
assertEqualsArray(map.values().toArray(), actual.values().toArray());
assertEquals(map.keySet().size(), actual.keySet().size());
assertEquals(map.get("India"), actual.get("India"));
}
private void testDateByJavaType(String in,String out, ParameterType pt){
TestDateClass test = (TestDateClass)unMarshaller.unmarshall(
new ByteArrayInputStream(("{\"date\":\""+in+"\"}").getBytes()),
pt,
UTF8, false);
Date date=DateTimeUtility.parse(out);
assertEquals(date, test.getDate());
}
public void testUnMarshalIOExceptionByType() {
JSONUnMarshaller unMarshaller = new JSONUnMarshaller(new ObjectMapper());
final IOException ex = new IOException("NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO");
try {
unMarshaller.unmarshall(new InputStream() {
@Override
public int read() throws IOException {
throw ex;
}
}, TEST_CLASS_PARAMETER_TYPE, UTF8, false);
fail();
} catch (CougarMarshallingException dse) {
assertEquals(ex, dse.getCause());
}
}
public void testUnMarshalIOException() {
JSONUnMarshaller unMarshaller = new JSONUnMarshaller(new ObjectMapper());
final IOException ex = new IOException("NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO");
try {
unMarshaller.unmarshall(new InputStream() {
@Override
public int read() throws IOException {
throw ex;
}
}, TestClass.class, UTF8, false);
fail();
} catch (CougarMarshallingException dse) {
assertEquals(ex, dse.getCause());
}
}
public void testUnMarshallFault() throws IOException {
ObjectMapper mockedOM = Mockito.mock(ObjectMapper.class);
FaultUnMarshaller faultUnMarshaller = new JSONUnMarshaller(mockedOM);
Map<String, Object> params = new HashMap<String, Object>();
params.put("value1", "yellow");
params.put("value2", (byte)100);
Map<String, Object> detailMap = new HashMap<String, Object>();
detailMap.put("trace", new Exception().getStackTrace());
detailMap.put("message", "The rain in spain stays mainly on the plane");
detailMap.put("exceptionname", "SimpleException");
detailMap.put("SimpleException", params);
Map<String, Object> aMap = new HashMap<String, Object>();
aMap.put("faultcode", "Client");
final String expectedFaultString = "DSC-0019";
aMap.put("faultstring", expectedFaultString);
aMap.put("detail", detailMap);
when(mockedOM.readValue(any(Reader.class), eq(HashMap.class))).thenReturn((HashMap)aMap);
CougarFault fault = faultUnMarshaller.unMarshallFault(new ByteArrayInputStream(new byte[]{}), "utf-8");
assertNotNull(fault);
assertEquals(expectedFaultString, fault.getErrorCode());
assertEquals("Client", fault.getFaultCode().name());
List<String[]> faultMessages = fault.getDetail().getFaultMessages();
assertEquals(params.size(), faultMessages.size());
for (String[] pair : faultMessages) {
assertTrue(pair.length == 2);
assertTrue(params.containsKey(pair[0]));
assertEquals(params.get(pair[0]).toString(), pair[1]);
}
}
@JsonIgnoreProperties(ignoreUnknown=true)
public static class TestClass {
private String message;
private RuntimeException ex;
public String getMessage() {
return message;
}
public void setMessage(String msg) {
if (ex != null) {
throw ex;
}
message = msg;
}
}
public static class TestDateClass {
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
private Date date;
}
}