package org.axonframework.serialization.json;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.axonframework.messaging.MetaData;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import java.io.IOException;
import java.util.*;
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertTrue;
@RunWith(Parameterized.class)
public class MetaDataDeserializerTest {
private final ObjectMapper.DefaultTyping defaultTyping;
private String serializedString;
private String emptySerializedString;
private String serializedContainerString;
private String serializedDataInDataString;
private ObjectMapper objectMapper;
@Parameters(name = "{0}")
public static Collection<ObjectMapper.DefaultTyping> data() {
return Arrays.asList(null,
ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT,
ObjectMapper.DefaultTyping.NON_CONCRETE_AND_ARRAYS,
ObjectMapper.DefaultTyping.NON_FINAL,
ObjectMapper.DefaultTyping.OBJECT_AND_NON_CONCRETE);
}
public MetaDataDeserializerTest(ObjectMapper.DefaultTyping defaultTyping) {
this.defaultTyping = defaultTyping;
}
@Before
public void setup() throws JsonProcessingException {
objectMapper = new ObjectMapper();
this.objectMapper.registerModule(
new SimpleModule("Axon-Jackson Module").addDeserializer(MetaData.class, new MetaDataDeserializer()));
if (defaultTyping != null) {
objectMapper.enableDefaultTyping(defaultTyping);
}
MetaData metaData = new MetaData(Collections.singletonMap("one", "two"));
this.serializedString = objectMapper.writeValueAsString(metaData);
MetaData metaData1 = new MetaData(new HashMap<>());
this.emptySerializedString = objectMapper.writeValueAsString(metaData1);
Container container = new Container("a", metaData, 1);
this.serializedContainerString = objectMapper.writeValueAsString(container);
Map<String, Object> map2 = new HashMap<>();
map2.put("one", metaData);
MetaData dataInData = new MetaData(map2);
Container container2 = new Container("a", dataInData, 1);
this.serializedDataInDataString = objectMapper.writeValueAsString(container2);
}
@Test
public void testMetaDataSerializationWithDefaultTyping() throws IOException {
MetaData deserialized = this.objectMapper.readValue(this.serializedString, MetaData.class);
assertEquals(deserialized.get("one"), "two");
assertEquals(this.serializedString, objectMapper.writeValueAsString(deserialized));
}
@Test
public void testEmptyMetaDataSerializationWithDefaultTyping() throws IOException {
MetaData deserialized = this.objectMapper.readValue(this.emptySerializedString, MetaData.class);
assertTrue(deserialized.entrySet().isEmpty());
assertEquals(this.emptySerializedString, objectMapper.writeValueAsString(deserialized));
}
@Test
public void testMetaDataContainerWithDefaultTyping() throws IOException {
Container deserialized = this.objectMapper.readValue(this.serializedContainerString, Container.class);
assertEquals(deserialized.b.get("one"), "two");
assertEquals(this.serializedContainerString, objectMapper.writeValueAsString(deserialized));
}
@Test
public void testMetaDataContainerWithDataInDataWithDefaultTyping() throws IOException {
Container deserialized = this.objectMapper.readValue(this.serializedDataInDataString, Container.class);
if (defaultTyping != null) {
assertEquals(((MetaData) deserialized.b.get("one")).get("one"), "two");
} else {
// as there is no typing information, Jackson can't know it's a MetaData entry
assertEquals(((Map) deserialized.b.get("one")).get("one"), "two");
}
assertEquals(this.serializedDataInDataString, objectMapper.writeValueAsString(deserialized));
}
public static class Container {
private String a;
private MetaData b;
private Integer c;
@JsonCreator
public Container(
@JsonProperty("a") String a,
@JsonProperty("b") MetaData b,
@JsonProperty("c") Integer c) {
this.a = a;
this.b = b;
this.c = c;
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public MetaData getB() {
return b;
}
public void setB(MetaData b) {
this.b = b;
}
public Integer getC() {
return c;
}
public void setC(Integer c) {
this.c = c;
}
}
}