From 00832eb5e79d77c8dff2c1031093e55073f84294 Mon Sep 17 00:00:00 2001 From: Connor Borden Date: Wed, 4 Aug 2021 11:28:09 -0700 Subject: [PATCH] add flag to SerializationConfig to disable READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE config --- .../internal/config/SerializationConfig.java | 10 +++ .../SerializationMapperCreator.java | 6 +- .../SerializationMapperCreatorTest.java | 67 +++++++++++++++++++ 3 files changed, 82 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/taboola/rest/api/internal/config/SerializationConfig.java b/src/main/java/com/taboola/rest/api/internal/config/SerializationConfig.java index 9f8adde..32a212a 100644 --- a/src/main/java/com/taboola/rest/api/internal/config/SerializationConfig.java +++ b/src/main/java/com/taboola/rest/api/internal/config/SerializationConfig.java @@ -6,10 +6,12 @@ public class SerializationConfig { private Map, Class> mixins; private boolean shouldIgnoreAnySetterAnnotation; + private boolean shouldDisableReadUnknownEnumValuesAsDefaultValue; public SerializationConfig() { mixins = new HashMap<>(); shouldIgnoreAnySetterAnnotation = false; + shouldDisableReadUnknownEnumValuesAsDefaultValue = false; } public SerializationConfig setMixins(Map, Class> mixins) { @@ -22,6 +24,11 @@ public SerializationConfig setShouldIgnoreAnySetterAnnotation() { return this; } + public SerializationConfig setShouldDisableReadUnknownEnumValuesAsDefaultValue() { + this.shouldDisableReadUnknownEnumValuesAsDefaultValue = true; + return this; + } + public Map, Class> getMixins() { return mixins; } @@ -29,6 +36,9 @@ public Map, Class> getMixins() { public boolean shouldIgnoreAnySetterAnnotation() { return shouldIgnoreAnySetterAnnotation; } + public boolean shouldDisableReadUnknownEnumValuesAsDefaultValue() { + return shouldDisableReadUnknownEnumValuesAsDefaultValue; + } @Override public String toString() { diff --git a/src/main/java/com/taboola/rest/api/internal/serialization/SerializationMapperCreator.java b/src/main/java/com/taboola/rest/api/internal/serialization/SerializationMapperCreator.java index 827f105..4ea62c9 100644 --- a/src/main/java/com/taboola/rest/api/internal/serialization/SerializationMapperCreator.java +++ b/src/main/java/com/taboola/rest/api/internal/serialization/SerializationMapperCreator.java @@ -12,7 +12,11 @@ public static ObjectMapper createObjectMapper(SerializationConfig serializationC objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - objectMapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE, true); + + if (!serializationConfig.shouldDisableReadUnknownEnumValuesAsDefaultValue()) { + objectMapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE, true); + } + serializationConfig.getMixins().forEach(objectMapper::addMixIn); if (serializationConfig.shouldIgnoreAnySetterAnnotation()) { diff --git a/src/test/java/com/taboola/rest/api/internal/serialization/SerializationMapperCreatorTest.java b/src/test/java/com/taboola/rest/api/internal/serialization/SerializationMapperCreatorTest.java index 9be805d..ab54955 100644 --- a/src/test/java/com/taboola/rest/api/internal/serialization/SerializationMapperCreatorTest.java +++ b/src/test/java/com/taboola/rest/api/internal/serialization/SerializationMapperCreatorTest.java @@ -1,10 +1,12 @@ package com.taboola.rest.api.internal.serialization; import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonEnumDefaultValue; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import com.fasterxml.jackson.databind.exc.InvalidFormatException; import com.taboola.rest.api.internal.config.SerializationConfig; import org.junit.Assert; @@ -68,10 +70,73 @@ public void createObjectMapper_serializationConfigWithIgnoreAnySetterAndApiObjec Assert.assertNull("Name is parsed incorrectly", sampleApi.name); } + @Test + public void createObjectMapper_defaultSerializationConfigAndApiObjectHasValidEnum_enumParsedCorrectly() throws IOException { + SerializationConfig serializationConfig = new SerializationConfig(); + ObjectMapper objectMapper = SerializationMapperCreator.createObjectMapper(serializationConfig); + + SampleApi sampleApi = objectMapper.readValue("{ \"letter\": \"B\" }", SampleApi.class); + + Assert.assertEquals("Unknown enum is parsed incorrectly", SampleEnum.B, sampleApi.letter); + } + + @Test + public void createObjectMapper_defaultSerializationConfigAndApiObjectHasInvalidEnum_defaultValueUsedOnSerialization() throws IOException { + SerializationConfig serializationConfig = new SerializationConfig(); + ObjectMapper objectMapper = SerializationMapperCreator.createObjectMapper(serializationConfig); + + SampleApi sampleApi = objectMapper.readValue("{ \"letter\": \"D\" }", SampleApi.class); + + Assert.assertEquals("Unknown enum is parsed incorrectly", SampleEnum.UNKNOWN, sampleApi.letter); + } + + @Test + public void createObjectMapper_defaultSerializationConfigAndApiObjectHasEmptyEnumValue_defaultValueUsedOnSerialization() throws IOException { + SerializationConfig serializationConfig = new SerializationConfig(); + ObjectMapper objectMapper = SerializationMapperCreator.createObjectMapper(serializationConfig); + + SampleApi sampleApi = objectMapper.readValue("{ \"letter\": \"D\" }", SampleApi.class); + + Assert.assertEquals("Unknown enum is parsed incorrectly", SampleEnum.UNKNOWN, sampleApi.letter); + } + + @Test + public void createObjectMapper_serializationConfigWithReadUnknownEnumsDisabledAndApiObjectHasValidEnum_enumParsedCorrectly() throws IOException { + SerializationConfig serializationConfig = new SerializationConfig().setShouldDisableReadUnknownEnumValuesAsDefaultValue(); + ObjectMapper objectMapper = SerializationMapperCreator.createObjectMapper(serializationConfig); + + SampleApi sampleApi = objectMapper.readValue("{ \"letter\": \"B\" }", SampleApi.class); + + Assert.assertEquals("Unknown enum is parsed incorrectly", SampleEnum.B, sampleApi.letter); + } + + @Test(expected = InvalidFormatException.class) + public void createObjectMapper_serializationConfigWithReadUnknownEnumsDisabledAndApiObjectHasInvalidEnum_InvalidFormatExceptionIsThrown() throws IOException { + SerializationConfig serializationConfig = new SerializationConfig().setShouldDisableReadUnknownEnumValuesAsDefaultValue(); + ObjectMapper objectMapper = SerializationMapperCreator.createObjectMapper(serializationConfig); + + objectMapper.readValue("{ \"letter\": \"D\" }", SampleApi.class); + } + + @Test(expected = InvalidFormatException.class) + public void createObjectMapper_serializationConfigWithReadUnknownEnumsDisabledAndApiObjectHasEmptyEnumValue_InvalidFormatExceptionIsThrown() throws IOException { + SerializationConfig serializationConfig = new SerializationConfig().setShouldDisableReadUnknownEnumValuesAsDefaultValue(); + ObjectMapper objectMapper = SerializationMapperCreator.createObjectMapper(serializationConfig); + + objectMapper.readValue("{ \"letter\": \"\" }", SampleApi.class); + } + + private enum SampleEnum { + A, B, @JsonEnumDefaultValue UNKNOWN + } + private static class SampleApi { @JsonProperty("id") int id; + @JsonProperty("letter") + SampleEnum letter; + @JsonProperty("name") String name; @@ -79,6 +144,8 @@ private static class SampleApi { public void handlerUnknownSetter(String field, Object value) throws Exception { throw new Exception("unknown field"); } + + } private abstract class SampleMixIn {