[685] Fix the issue when deserializing a Map which has a wildcard value. Added tests for wildcards on map keys and values, lists and optional.

Signed-off-by: James R. Perkins <jperkins@ibm.com>
diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java b/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java
index cebe6c3..6a6daca 100644
--- a/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java
+++ b/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java
@@ -296,7 +296,7 @@
                                                                    ClassCustomization.empty(),
                                                                    JustReturn.instance(),
                                                                    MAP_KEY_EVENTS);
-        ClassModel valueClassModel = jsonbContext.getMappingContext().getOrCreateClassModel(ReflectionUtils.getRawType(valueType));
+        ClassModel valueClassModel = jsonbContext.getMappingContext().getOrCreateClassModel(ReflectionUtils.resolveRawType(chain, valueType));
         ModelDeserializer<JsonParser> valueProcessor = typeProcessor(chain,
                                                                      valueType,
                                                                      valueClassModel.getClassCustomization(),
diff --git a/src/test/java/org/eclipse/yasson/serializers/TypeDeserializerOnContainersTest.java b/src/test/java/org/eclipse/yasson/serializers/TypeDeserializerOnContainersTest.java
index 4b4d871..7cd1e3f 100644
--- a/src/test/java/org/eclipse/yasson/serializers/TypeDeserializerOnContainersTest.java
+++ b/src/test/java/org/eclipse/yasson/serializers/TypeDeserializerOnContainersTest.java
@@ -79,19 +79,23 @@
     // Container classes for testing
     public static class MapContainer {
         public Map<String, TestInterface> map;
+        public Map<?, ?> questionKeyMap;
+        public Map<String, ?> questionValueMap;
     }
 
     public static class ListContainer {
         public List<TestInterface> list;
+        public List<?> questionList;
     }
 
     public static class ArrayContainer {
         public TestInterface[] array;
     }
 
+    @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
     public static class OptionalContainer {
-        @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
         public Optional<TestInterface> optional;
+        public Optional<?> questionOptional;
     }
 
     public static class ByteArrayContainer {
@@ -115,7 +119,7 @@
 
     @Test
     public void testTypeDeserializerOnMapValues() {
-        final String json = "{\"map\":{\"key1\":{\"value\":\"value1\"},\"key2\":{\"value\":\"value2\"}}}";
+        final String json = "{\"map\":{\"key1\":{\"value\":\"value1\"},\"key2\":{\"value\":\"value2\"}}, \"questionKeyMap\":{\"qKey1\":\"value1\",\"qKey2\":\"value2\"},\"questionValueMap\":{\"key1\":\"qValue1\",\"key2\":\"qValue2\"}}";
 
         final MapContainer result = jsonb.fromJson(json, MapContainer.class);
 
@@ -123,11 +127,21 @@
         Assertions.assertEquals(2, result.map.size(), () -> String.format("Expected two entries got %s", result.map));
         Assertions.assertEquals("DESERIALIZED:value1", result.map.get("key1").getValue());
         Assertions.assertEquals("DESERIALIZED:value2", result.map.get("key2").getValue());
+
+        Assertions.assertNotNull(result.questionKeyMap);
+        Assertions.assertEquals(2, result.questionKeyMap.size(), () -> String.format("Expected two entries got %s", result.questionKeyMap));
+        Assertions.assertEquals("value1", result.questionKeyMap.get("qKey1"));
+        Assertions.assertEquals("value2", result.questionKeyMap.get("qKey2"));
+
+        Assertions.assertNotNull(result.questionValueMap);
+        Assertions.assertEquals(2, result.questionValueMap.size(), () -> String.format("Expected two entries got %s", result.questionValueMap));
+        Assertions.assertEquals("qValue1", result.questionValueMap.get("key1"));
+        Assertions.assertEquals("qValue2", result.questionValueMap.get("key2"));
     }
 
     @Test
     public void testTypeDeserializerOnListElements() {
-        final String json = "{\"list\":[{\"value\":\"value1\"},{\"value\":\"value2\"}]}";
+        final String json = "{\"list\":[{\"value\":\"value1\"},{\"value\":\"value2\"}], \"questionList\": [\"value1\", \"value2\"]}";
 
         final ListContainer result = jsonb.fromJson(json, ListContainer.class);
 
@@ -135,6 +149,11 @@
         Assertions.assertEquals(2, result.list.size(), () -> String.format("Expected two entries got %s", result.list));
         Assertions.assertEquals("DESERIALIZED:value1", result.list.get(0).getValue());
         Assertions.assertEquals("DESERIALIZED:value2", result.list.get(1).getValue());
+
+        Assertions.assertNotNull(result.questionList);
+        Assertions.assertEquals(2, result.questionList.size(), () -> String.format("Expected two entries got %s", result.questionList));
+        Assertions.assertEquals("value1", result.questionList.get(0));
+        Assertions.assertEquals("value2", result.questionList.get(1));
     }
 
     @Test
@@ -151,13 +170,17 @@
 
     @Test
     public void testTypeDeserializerOnOptionalValue() {
-        final String json = "{\"optional\":{\"value\":\"value1\"}}";
+        final String json = "{\"optional\":{\"value\":\"value1\"},\"questionOptional\":\"value2\"}";
 
         final OptionalContainer result = jsonb.fromJson(json, OptionalContainer.class);
 
         Assertions.assertNotNull(result.optional);
         Assertions.assertTrue(result.optional.isPresent(), "Expected value to be present, but the optional was empty.");
         Assertions.assertEquals("DESERIALIZED:value1", result.optional.get().getValue());
+
+        Assertions.assertNotNull(result.questionOptional);
+        Assertions.assertTrue(result.questionOptional.isPresent(), "Expected value to be present, but the optional was empty.");
+        Assertions.assertEquals("value2", result.questionOptional.get());
     }
 
     @Test
diff --git a/src/test/java/org/eclipse/yasson/serializers/TypeSerializerOnContainersTest.java b/src/test/java/org/eclipse/yasson/serializers/TypeSerializerOnContainersTest.java
index a3edc45..89f3ff2 100644
--- a/src/test/java/org/eclipse/yasson/serializers/TypeSerializerOnContainersTest.java
+++ b/src/test/java/org/eclipse/yasson/serializers/TypeSerializerOnContainersTest.java
@@ -12,12 +12,19 @@
 
 package org.eclipse.yasson.serializers;
 
+import java.io.StringReader;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import java.util.function.Supplier;
 
+import jakarta.json.Json;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonReader;
 import jakarta.json.bind.Jsonb;
 import jakarta.json.bind.JsonbBuilder;
+import jakarta.json.bind.JsonbException;
 import jakarta.json.bind.annotation.JsonbTypeSerializer;
 import jakarta.json.bind.serializer.JsonbSerializer;
 import jakarta.json.bind.serializer.SerializationContext;
@@ -66,35 +73,43 @@
 
     // Container classes for testing
     public static class MapContainer {
-        public Map<String, TestInterface> map;
+        public final Map<String, TestInterface> map;
+        public final Map<?, ?> questionKeyMap;
+        public final Map<String, ?> questionValueMap;
 
-        public MapContainer(Map<String, TestInterface> map) {
+        public MapContainer(final Map<String, TestInterface> map, final Map<?, ?> questionKeyMap, final Map<String, ?> questionValueMap) {
             this.map = map;
+            this.questionKeyMap = questionKeyMap;
+            this.questionValueMap = questionValueMap;
         }
     }
 
     public static class ListContainer {
-        public List<TestInterface> list;
+        public final List<TestInterface> list;
+        public final List<?> questionList;
 
-        public ListContainer(List<TestInterface> list) {
+        public ListContainer(final List<TestInterface> list, final List<?> questionList) {
             this.list = list;
+            this.questionList = questionList;
         }
     }
 
     public static class ArrayContainer {
-        public TestInterface[] array;
+        public final TestInterface[] array;
 
         public ArrayContainer(TestInterface[] array) {
             this.array = array;
         }
     }
 
+    @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
     public static class OptionalContainer {
-        @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
-        public Optional<TestInterface> optional;
+        public final Optional<TestInterface> optional;
+        public final Optional<?> questionOptional;
 
-        public OptionalContainer(Optional<TestInterface> optional) {
+        public OptionalContainer(final Optional<TestInterface> optional, final Optional<?> questionOptional) {
             this.optional = optional;
+            this.questionOptional = questionOptional;
         }
     }
 
@@ -118,14 +133,28 @@
         final MapContainer container = new MapContainer(Map.of(
                 "key1", new TestImpl("value1"),
                 "key2", new TestImpl("value2")
-        ));
+        ), Map.of("qKey1", "value1", "qKey2", "value2"),
+                Map.of("key1", "qValue1", "key2", "qValue2")
+        );
 
-        final String json = jsonb.toJson(container);
+        final JsonObject json = toJsonObject(container);
+        final JsonObject map = json.getJsonObject("map");
+        final JsonObject questionKeyMap = json.getJsonObject("questionKeyMap");
+        final JsonObject questionValueMap = json.getJsonObject("questionValueMap");
 
-        Assertions.assertTrue(json.contains("\"key1\":\"SERIALIZED:value1\""),
-                "Expected serialized value1 but got: " + json);
-        Assertions.assertTrue(json.contains("\"key2\":\"SERIALIZED:value2\""),
-                "Expected serialized value2 but got: " + json);
+        Supplier<String> errorMessage = () -> String.format("Expected value not found in %s", map);
+        Assertions.assertEquals("SERIALIZED:value1", map.getString("key1"), errorMessage);
+        Assertions.assertEquals("SERIALIZED:value2", map.getString("key2"), errorMessage);
+
+
+        errorMessage = () -> String.format("Expected value not found in %s", questionKeyMap);
+        Assertions.assertEquals("value1", questionKeyMap.getString("qKey1"), errorMessage);
+        Assertions.assertEquals("value2", questionKeyMap.getString("qKey2"), errorMessage);
+
+
+        errorMessage = () -> String.format("Expected value not found in %s", questionValueMap);
+        Assertions.assertEquals("qValue1", questionValueMap.getString("key1"), errorMessage);
+        Assertions.assertEquals("qValue2", questionValueMap.getString("key2"), errorMessage);
     }
 
     @Test
@@ -133,16 +162,26 @@
         final ListContainer container = new ListContainer(List.of(
                 new TestImpl("value1"),
                 new TestImpl("value2")
-        ));
+        ), List.of("qValue1", "qValue2"));
 
-        final String json = jsonb.toJson(container);
+        final JsonObject json = toJsonObject(container);
+        final JsonArray list = json.getJsonArray("list");
+        final JsonArray questionList = json.getJsonArray("questionList");
 
-        Assertions.assertEquals("{\"list\":[\"SERIALIZED:value1\",\"SERIALIZED:value2\"]}", json);
+        Supplier<String> errorMessage = () -> String.format("Expected value not found in %s", list);
+        Assertions.assertEquals(2, list.size(), () -> String.format("Expected a size of 2 in %s", list));
+        Assertions.assertEquals("SERIALIZED:value1", list.getString(0), errorMessage);
+        Assertions.assertEquals("SERIALIZED:value2", list.getString(1), errorMessage);
+
+        errorMessage = () -> String.format("Expected value not found in %s", questionList);
+        Assertions.assertEquals(2, questionList.size(), () -> String.format("Expected a size of 2 in %s", questionList));
+        Assertions.assertEquals("qValue1", questionList.getString(0), errorMessage);
+        Assertions.assertEquals("qValue2", questionList.getString(1), errorMessage);
     }
 
     @Test
     public void testTypeSerializerOnArrayElements() {
-        final ArrayContainer container = new ArrayContainer(new TestInterface[]{
+        final ArrayContainer container = new ArrayContainer(new TestInterface[] {
                 new TestImpl("value1"),
                 new TestImpl("value2")
         });
@@ -154,10 +193,21 @@
 
     @Test
     public void testTypeSerializerOnOptionalValue() {
-        final OptionalContainer container = new OptionalContainer(Optional.of(new TestImpl("value1")));
+        final OptionalContainer container = new OptionalContainer(Optional.of(new TestImpl("value1")), Optional.of("value2"));
 
-        final String json = jsonb.toJson(container);
+        final JsonObject json = toJsonObject(container);
 
-        Assertions.assertEquals("{\"optional\":\"SERIALIZED:value1\"}", json);
+        Assertions.assertEquals("SERIALIZED:value1", json.getString("optional"));
+        Assertions.assertEquals("value2", json.getString("questionOptional"));
+    }
+
+    private JsonObject toJsonObject(final Object object) throws JsonbException {
+        final String value = jsonb.toJson(object);
+        try (
+                StringReader reader = new StringReader(value);
+                JsonReader jsonReader = Json.createReader(reader)
+        ) {
+            return jsonReader.readObject();
+        }
     }
 }