package ninja.bodyparser;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.ObjectMapper;
import ninja.Context;
import ninja.exceptions.BadRequestException;
import org.hamcrest.CoreMatchers;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
/**
* Unit tests for the Json body parser.
*
* @author Thibault Meyer
*/
@RunWith(MockitoJUnitRunner.class)
public class BodyParserEngineJsonTest {
private static final String DATA_FIRSTNAME = "John";
private static final String DATA_LASTNAME = "Do";
private static final Integer DATA_BIRTHYEAR = 1664;
private static final String DATA_LASTSEEN = "2015-03-15 15:45:00";
private static final String PARSER_DATEFORMAT = "yyyy-MM-dd hh:mm:ss";
private static final String PARSER_DATETZ = "GMT";
@Mock
private Context context;
@Test
public void testValidJsonBody() {
final String jsonDocument = String.format("{\"firstName\":\"%s\", \"lastName\":\"%s\", \"birthYear\":%d, \"lastSeen\":\"%s\"}",
BodyParserEngineJsonTest.DATA_FIRSTNAME,
BodyParserEngineJsonTest.DATA_LASTNAME,
BodyParserEngineJsonTest.DATA_BIRTHYEAR,
BodyParserEngineJsonTest.DATA_LASTSEEN);
final InputStream is = new ByteArrayInputStream(jsonDocument.getBytes());
final ObjectMapper jsonObjMapper = new ObjectMapper();
final BodyParserEngineJson bodyParserEngineJson = new BodyParserEngineJson(jsonObjMapper);
SimpleTestForm testForm = null;
try {
Mockito.when(context.getInputStream()).thenReturn(is);
} catch (IOException ignore) {
}
try {
testForm = bodyParserEngineJson.invoke(context, SimpleTestForm.class);
} catch (BadRequestException ignore) {
} finally {
try {
is.close();
} catch (IOException ignore) {
}
}
final Calendar cal = Calendar.getInstance();
final SimpleDateFormat dateFormat = new SimpleDateFormat(BodyParserEngineJsonTest.PARSER_DATEFORMAT);
dateFormat.setTimeZone(TimeZone.getTimeZone(BodyParserEngineJsonTest.PARSER_DATETZ));
try {
cal.setTime(dateFormat.parse(BodyParserEngineJsonTest.DATA_LASTSEEN));
} catch (ParseException ignore) {
}
cal.setTimeZone(TimeZone.getTimeZone(BodyParserEngineJsonTest.PARSER_DATETZ));
assertTrue(testForm != null);
assertThat(testForm.firstName, equalTo(BodyParserEngineJsonTest.DATA_FIRSTNAME));
assertThat(testForm.lastName, equalTo(BodyParserEngineJsonTest.DATA_LASTNAME));
assertThat(testForm.birthYear, CoreMatchers.equalTo(BodyParserEngineJsonTest.DATA_BIRTHYEAR));
assertTrue(testForm.lastSeen != null);
assertTrue(testForm.lastSeen.compareTo(cal) == 0);
}
@Test
public void testEmptyJsonBody() {
final String jsonDocument = "";
final InputStream is = new ByteArrayInputStream(jsonDocument.getBytes());
final ObjectMapper jsonObjMapper = new ObjectMapper();
final BodyParserEngineJson bodyParserEngineJson = new BodyParserEngineJson(jsonObjMapper);
boolean badRequestThrown = false;
try {
Mockito.when(context.getInputStream()).thenReturn(is);
} catch (IOException ignore) {
}
try {
bodyParserEngineJson.invoke(context, SimpleTestForm.class);
} catch (BadRequestException ignore) {
badRequestThrown = true;
} finally {
try {
is.close();
} catch (IOException ignore) {
}
}
assertTrue(badRequestThrown);
}
@Test
public void testInvalidJsonBody() {
final String jsonDocument = String.format("{\"firstName\":\"%s\", \"lastName\":\"%s\", \"birthYear\":%d, \"lastSeen\":\"%s\"",
BodyParserEngineJsonTest.DATA_FIRSTNAME,
BodyParserEngineJsonTest.DATA_LASTNAME,
BodyParserEngineJsonTest.DATA_BIRTHYEAR,
BodyParserEngineJsonTest.DATA_LASTSEEN);
final InputStream is = new ByteArrayInputStream(jsonDocument.getBytes());
final ObjectMapper jsonObjMapper = new ObjectMapper();
final BodyParserEngineJson bodyParserEngineJson = new BodyParserEngineJson(jsonObjMapper);
boolean badRequestThrown = false;
try {
Mockito.when(context.getInputStream()).thenReturn(is);
} catch (IOException ignore) {
}
try {
bodyParserEngineJson.invoke(context, SimpleTestForm.class);
} catch (BadRequestException ignore) {
badRequestThrown = true;
} finally {
try {
is.close();
} catch (IOException ignore) {
}
}
assertTrue(badRequestThrown);
}
@Test
public void testJsonBodyWithFullSpacesAndEndOfLines() {
final String jsonDocument = String.format(" \n\n\n { \n \"firstName\" \n : \"%s\", \"lastName\"\n : \"%s\", \"birthYear\":%d,\n \"lastSeen\":\"%s\"} ",
BodyParserEngineJsonTest.DATA_FIRSTNAME,
BodyParserEngineJsonTest.DATA_LASTNAME,
BodyParserEngineJsonTest.DATA_BIRTHYEAR,
BodyParserEngineJsonTest.DATA_LASTSEEN);
final InputStream is = new ByteArrayInputStream(jsonDocument.getBytes());
final ObjectMapper jsonObjMapper = new ObjectMapper();
final BodyParserEngineJson bodyParserEngineJson = new BodyParserEngineJson(jsonObjMapper);
SimpleTestForm testForm = null;
try {
Mockito.when(context.getInputStream()).thenReturn(is);
} catch (IOException ignore) {
}
try {
testForm = bodyParserEngineJson.invoke(context, SimpleTestForm.class);
} catch (BadRequestException ignore) {
} finally {
try {
is.close();
} catch (IOException ignore) {
}
}
final Calendar cal = Calendar.getInstance();
final SimpleDateFormat dateFormat = new SimpleDateFormat(BodyParserEngineJsonTest.PARSER_DATEFORMAT);
dateFormat.setTimeZone(TimeZone.getTimeZone(BodyParserEngineJsonTest.PARSER_DATETZ));
try {
cal.setTime(dateFormat.parse(BodyParserEngineJsonTest.DATA_LASTSEEN));
} catch (ParseException ignore) {
}
cal.setTimeZone(TimeZone.getTimeZone(BodyParserEngineJsonTest.PARSER_DATETZ));
assertTrue(testForm != null);
assertThat(testForm.firstName, equalTo(BodyParserEngineJsonTest.DATA_FIRSTNAME));
assertThat(testForm.lastName, equalTo(BodyParserEngineJsonTest.DATA_LASTNAME));
assertThat(testForm.birthYear, CoreMatchers.equalTo(BodyParserEngineJsonTest.DATA_BIRTHYEAR));
assertTrue(testForm.lastSeen != null);
assertTrue(testForm.lastSeen.compareTo(cal) == 0);
}
@Test
public void testJsonBodyWithMissingVariables() {
final String jsonDocument = String.format("{\"firstName\":\"%s\", \"lastName\":\"%s\"}",
BodyParserEngineJsonTest.DATA_FIRSTNAME,
BodyParserEngineJsonTest.DATA_LASTNAME);
final InputStream is = new ByteArrayInputStream(jsonDocument.getBytes());
final ObjectMapper jsonObjMapper = new ObjectMapper();
final BodyParserEngineJson bodyParserEngineJson = new BodyParserEngineJson(jsonObjMapper);
SimpleTestForm testForm = null;
try {
Mockito.when(context.getInputStream()).thenReturn(is);
} catch (IOException ignore) {
}
try {
testForm = bodyParserEngineJson.invoke(context, SimpleTestForm.class);
} catch (BadRequestException ignore) {
} finally {
try {
is.close();
} catch (IOException ignore) {
}
}
assertTrue(testForm != null);
assertThat(testForm.firstName, equalTo(BodyParserEngineJsonTest.DATA_FIRSTNAME));
assertThat(testForm.lastName, equalTo(BodyParserEngineJsonTest.DATA_LASTNAME));
assertTrue(testForm.birthYear == null);
assertTrue(testForm.lastSeen == null);
}
/**
* Simple form used during unit tests.
*
* @author Thibault Meyer
*/
private static final class SimpleTestForm {
public String firstName;
public String lastName;
public Integer birthYear;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = BodyParserEngineJsonTest.PARSER_DATEFORMAT, timezone = BodyParserEngineJsonTest.PARSER_DATETZ)
public java.util.Calendar lastSeen;
}
}