package br.com.caelum.vraptor.deserialization; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.io.ByteArrayInputStream; import java.io.InputStream; import org.junit.Before; import org.junit.Test; import com.thoughtworks.xstream.annotations.XStreamAlias; import br.com.caelum.vraptor.http.ParameterNameProvider; import br.com.caelum.vraptor.resource.DefaultResourceClass; import br.com.caelum.vraptor.resource.DefaultResourceMethod; import br.com.caelum.vraptor.resource.ResourceMethod; import br.com.caelum.vraptor.serialization.xstream.XStreamBuilderImpl; public class XStreamXmlDeserializerTest { private XStreamXMLDeserializer deserializer; private ResourceMethod bark; private ParameterNameProvider provider; private ResourceMethod jump; private DefaultResourceMethod woof; private DefaultResourceMethod dropDead; private DefaultResourceMethod annotated; private DefaultResourceMethod walk; @Before public void setUp() throws Exception { provider = mock(ParameterNameProvider.class); deserializer = new XStreamXMLDeserializer(provider, XStreamBuilderImpl.cleanInstance()); DefaultResourceClass resourceClass = new DefaultResourceClass(DogController.class); DefaultResourceClass resourcePersonClass = new DefaultResourceClass(PersonController.class); woof = new DefaultResourceMethod(resourceClass, DogController.class.getDeclaredMethod("woof")); bark = new DefaultResourceMethod(resourceClass, DogController.class.getDeclaredMethod("bark", Dog.class)); jump = new DefaultResourceMethod(resourceClass, DogController.class.getDeclaredMethod("jump", Dog.class, Integer.class)); dropDead = new DefaultResourceMethod(resourceClass, DogController.class.getDeclaredMethod("dropDead", Integer.class, Dog.class)); annotated = new DefaultResourceMethod(resourceClass, DogController.class.getDeclaredMethod("annotated", DogWithAnnotations.class)); walk = new DefaultResourceMethod(resourcePersonClass, PersonController.class.getDeclaredMethod("walk", Person.class)); } static class Person { private String name; private Dog dog; } static class PersonController { public void walk(Person person){} } @XStreamAlias("dogAnnotated") static class DogWithAnnotations { @XStreamAlias("nameAnnotated") private String name; @XStreamAlias("ageAnnotated") private Integer age; } static class Dog { private String name; private Integer age; } static class DogController { public void woof() { } public void bark(Dog dog) { } public void jump(Dog dog, Integer times) { } public void dropDead(Integer times, Dog dog) { } public void annotated(DogWithAnnotations dog){ } } @Test(expected=IllegalArgumentException.class) public void shouldNotAcceptMethodsWithoutArguments() throws Exception { deserializer.deserialize(new ByteArrayInputStream(new byte[0]), woof); } @Test public void shouldBeAbleToDeserializeAPersonWithDog() throws Exception { InputStream stream = new ByteArrayInputStream("<person><name>Renan</name><dog><name>Brutus</name><age>7</age></dog></person>".getBytes()); when(provider.parameterNamesFor(walk.getMethod())).thenReturn(new String[] {"person"}); Object[] deserialized = deserializer.deserialize(stream, walk); assertThat(deserialized.length, is(1)); assertThat(deserialized[0], is(instanceOf(Person.class))); Person person = (Person) deserialized[0]; assertThat(person.name, is("Renan")); assertThat(person.dog.name, is("Brutus")); assertThat(person.dog.age, is(7)); } @Test public void shouldBeAbleToDeserializeADog() throws Exception { InputStream stream = new ByteArrayInputStream("<dog><name>Brutus</name><age>7</age></dog>".getBytes()); when(provider.parameterNamesFor(bark.getMethod())).thenReturn(new String[] {"dog"}); Object[] deserialized = deserializer.deserialize(stream, bark); assertThat(deserialized.length, is(1)); assertThat(deserialized[0], is(instanceOf(Dog.class))); Dog dog = (Dog) deserialized[0]; assertThat(dog.name, is("Brutus")); assertThat(dog.age, is(7)); } @Test public void shouldBeAbleToDeserializeADogWhenMethodHasMoreThanOneArgument() throws Exception { InputStream stream = new ByteArrayInputStream("<dog><name>Brutus</name><age>7</age></dog>".getBytes()); when(provider.parameterNamesFor(jump.getMethod())).thenReturn(new String[] {"dog", "times"}); Object[] deserialized = deserializer.deserialize(stream, jump); assertThat(deserialized.length, is(2)); assertThat(deserialized[0], is(instanceOf(Dog.class))); Dog dog = (Dog) deserialized[0]; assertThat(dog.name, is("Brutus")); assertThat(dog.age, is(7)); } @Test public void shouldBeAbleToDeserializeADogWhenMethodHasMoreThanOneArgumentAndTheXmlIsTheLastOne() throws Exception { InputStream stream = new ByteArrayInputStream("<dog><name>Brutus</name><age>7</age></dog>".getBytes()); when(provider.parameterNamesFor(dropDead.getMethod())).thenReturn(new String[] {"times", "dog"}); Object[] deserialized = deserializer.deserialize(stream, dropDead); assertThat(deserialized.length, is(2)); assertThat(deserialized[1], is(instanceOf(Dog.class))); Dog dog = (Dog) deserialized[1]; assertThat(dog.name, is("Brutus")); assertThat(dog.age, is(7)); } @Test public void shouldBeAbleToDeserializeADogNamedDifferently() throws Exception { InputStream stream = new ByteArrayInputStream("<pet><name>Brutus</name><age>7</age></pet>".getBytes()); when(provider.parameterNamesFor(bark.getMethod())).thenReturn(new String[] {"pet"}); Object[] deserialized = deserializer.deserialize(stream, bark); assertThat(deserialized.length, is(1)); assertThat(deserialized[0], is(instanceOf(Dog.class))); Dog dog = (Dog) deserialized[0]; assertThat(dog.name, is("Brutus")); assertThat(dog.age, is(7)); } @Test public void shouldBeAbleToDeserializeADogWhenAliasConfiguredByAnnotations() { InputStream stream = new ByteArrayInputStream("<dogAnnotated><nameAnnotated>Lubi</nameAnnotated><ageAnnotated>8</ageAnnotated></dogAnnotated>".getBytes()); when(provider.parameterNamesFor(annotated.getMethod())).thenReturn(new String[] {"dog"}); Object[] deserialized = deserializer.deserialize(stream, annotated); assertThat(deserialized.length, is(1)); assertThat(deserialized[0], is(instanceOf(DogWithAnnotations.class))); DogWithAnnotations dog = (DogWithAnnotations) deserialized[0]; assertThat(dog.name, is("Lubi")); assertThat(dog.age, is(8)); } }