package ninja.bodyparser; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.dataformat.xml.XmlMapper; 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 Xml body parser. * * @author Thibault Meyer */ @RunWith(MockitoJUnitRunner.class) public class BodyParserEngineXmlTest { 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 testValidXmlBody() { final String xmlDocument = String.format("<form><firstName>%s</firstName><lastName>%s</lastName><birthYear>%d</birthYear><lastSeen>%s</lastSeen></form>", BodyParserEngineXmlTest.DATA_FIRSTNAME, BodyParserEngineXmlTest.DATA_LASTNAME, BodyParserEngineXmlTest.DATA_BIRTHYEAR, BodyParserEngineXmlTest.DATA_LASTSEEN); final InputStream is = new ByteArrayInputStream(xmlDocument.getBytes()); final XmlMapper xmlObjMapper = new XmlMapper(); final BodyParserEngineXml bodyParserEngineXml = new BodyParserEngineXml(xmlObjMapper); SimpleTestForm testForm = null; try { Mockito.when(context.getInputStream()).thenReturn(is); } catch (IOException ignore) { } try { testForm = bodyParserEngineXml.invoke(context, SimpleTestForm.class); } catch (BadRequestException ignore) { } finally { try { is.close(); } catch (IOException ignore) { } } final Calendar cal = Calendar.getInstance(); final SimpleDateFormat dateFormat = new SimpleDateFormat(BodyParserEngineXmlTest.PARSER_DATEFORMAT); dateFormat.setTimeZone(TimeZone.getTimeZone(BodyParserEngineXmlTest.PARSER_DATETZ)); try { cal.setTime(dateFormat.parse(BodyParserEngineXmlTest.DATA_LASTSEEN)); } catch (ParseException ignore) { } cal.setTimeZone(TimeZone.getTimeZone(BodyParserEngineXmlTest.PARSER_DATETZ)); assertTrue(testForm != null); assertThat(testForm.firstName, equalTo(BodyParserEngineXmlTest.DATA_FIRSTNAME)); assertThat(testForm.lastName, equalTo(BodyParserEngineXmlTest.DATA_LASTNAME)); assertThat(testForm.birthYear, CoreMatchers.equalTo(BodyParserEngineXmlTest.DATA_BIRTHYEAR)); assertTrue(testForm.lastSeen != null); assertTrue(testForm.lastSeen.compareTo(cal) == 0); } @Test public void testXmlBodyWithMissingVariables() { final String xmlDocument = String.format("<form><firstName>%s</firstName><lastName>%s</lastName></form>", BodyParserEngineXmlTest.DATA_FIRSTNAME, BodyParserEngineXmlTest.DATA_LASTNAME); final InputStream is = new ByteArrayInputStream(xmlDocument.getBytes()); final XmlMapper xmlObjMapper = new XmlMapper(); final BodyParserEngineXml bodyParserEngineXml = new BodyParserEngineXml(xmlObjMapper); SimpleTestForm testForm = null; try { Mockito.when(context.getInputStream()).thenReturn(is); } catch (IOException ignore) { } try { testForm = bodyParserEngineXml.invoke(context, SimpleTestForm.class); } catch (BadRequestException ignore) { } finally { try { is.close(); } catch (IOException ignore) { } } assertTrue(testForm != null); assertThat(testForm.firstName, equalTo(BodyParserEngineXmlTest.DATA_FIRSTNAME)); assertThat(testForm.lastName, equalTo(BodyParserEngineXmlTest.DATA_LASTNAME)); assertTrue(testForm.birthYear == null); assertTrue(testForm.lastSeen == null); } @Test public void testEmptyXmlBody() { final String xmlDocument = ""; final InputStream is = new ByteArrayInputStream(xmlDocument.getBytes()); final XmlMapper xmlObjMapper = new XmlMapper(); final BodyParserEngineXml bodyParserEngineXml = new BodyParserEngineXml(xmlObjMapper); boolean badRequestThrown = false; try { Mockito.when(context.getInputStream()).thenReturn(is); } catch (IOException ignore) { } try { bodyParserEngineXml.invoke(context, SimpleTestForm.class); } catch (BadRequestException ignore) { badRequestThrown = true; } finally { try { is.close(); } catch (IOException ignore) { } } assertTrue(badRequestThrown); } @Test public void testInvalidXmlBadCloseBody() { final String xmlDocument = String.format("<form><firstName>%s</firstName><lastName>%s</lastName><birthYear>%d</birthYear><lastSeen>%s</lastSeen></>", BodyParserEngineXmlTest.DATA_FIRSTNAME, BodyParserEngineXmlTest.DATA_LASTNAME, BodyParserEngineXmlTest.DATA_BIRTHYEAR, BodyParserEngineXmlTest.DATA_LASTSEEN); final InputStream is = new ByteArrayInputStream(xmlDocument.getBytes()); final XmlMapper xmlObjMapper = new XmlMapper(); final BodyParserEngineXml bodyParserEngineXml = new BodyParserEngineXml(xmlObjMapper); boolean badRequestThrown = false; try { Mockito.when(context.getInputStream()).thenReturn(is); } catch (IOException ignore) { } try { bodyParserEngineXml.invoke(context, SimpleTestForm.class); } catch (BadRequestException ignore) { badRequestThrown = true; } finally { try { is.close(); } catch (IOException ignore) { } } assertTrue(badRequestThrown); } @Test public void testInvalidXmlMissingRootBody() { final String xmlDocument = String.format("<firstName>%s</firstName><lastName>%s</lastName><birthYear>%d</birthYear><lastSeen>%s</lastSeen>", BodyParserEngineXmlTest.DATA_FIRSTNAME, BodyParserEngineXmlTest.DATA_LASTNAME, BodyParserEngineXmlTest.DATA_BIRTHYEAR, BodyParserEngineXmlTest.DATA_LASTSEEN); final InputStream is = new ByteArrayInputStream(xmlDocument.getBytes()); final XmlMapper xmlObjMapper = new XmlMapper(); final BodyParserEngineXml bodyParserEngineXml = new BodyParserEngineXml(xmlObjMapper); boolean badRequestThrown = false; try { Mockito.when(context.getInputStream()).thenReturn(is); } catch (IOException ignore) { } try { bodyParserEngineXml.invoke(context, SimpleTestForm.class); } catch (BadRequestException ignore) { badRequestThrown = true; } finally { try { is.close(); } catch (IOException ignore) { } } assertTrue(badRequestThrown); } /** * 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 = BodyParserEngineXmlTest.PARSER_DATEFORMAT, timezone = BodyParserEngineXmlTest.PARSER_DATETZ) public Calendar lastSeen; } }