3333import static org .hamcrest .CoreMatchers .equalTo ;
3434import static org .hamcrest .CoreMatchers .notNullValue ;
3535import static org .hamcrest .MatcherAssert .assertThat ;
36+ import static org .hamcrest .Matchers .containsString ;
3637import static org .hamcrest .Matchers .hasKey ;
38+ import static org .junit .jupiter .api .Assertions .assertThrows ;
3739
3840class PluginModelTests {
3941
@@ -75,14 +77,14 @@ final void testSerialization_empty_plugin_to_YAML() throws JsonGenerationExcepti
7577
7678 final String serialized = mapper .writeValueAsString (pluginModel );
7779
78- InputStream inputStream = PluginModelTests .class .getResourceAsStream ("plugin_model_null .yaml" );
80+ InputStream inputStream = PluginModelTests .class .getResourceAsStream ("plugin_model_with_empty_object .yaml" );
7981
8082 assertThat (serialized , notNullValue ());
8183 assertThat (serialized , equalTo (convertInputStreamToString (inputStream )));
8284 }
8385
8486 @ ParameterizedTest
85- @ ValueSource (strings = {"plugin_model_empty.yaml" , "plugin_model_not_present.yaml" , "plugin_model_null .yaml" })
87+ @ ValueSource (strings = {"plugin_model_with_empty_object .yaml" })
8688 final void deserialize_with_empty_inner (final String resourceName ) throws IOException {
8789 final InputStream inputStream = PluginModelTests .class .getResourceAsStream (resourceName );
8890
@@ -94,6 +96,17 @@ final void deserialize_with_empty_inner(final String resourceName) throws IOExce
9496 assertThat (pluginModel .getPluginSettings ().size (), equalTo (0 ));
9597 }
9698
99+ @ Test
100+ final void deserialize_with_no_value_returns_null_settings () throws IOException {
101+ final InputStream inputStream = PluginModelTests .class .getResourceAsStream ("plugin_model_not_present.yaml" );
102+
103+ final ObjectMapper mapper = new ObjectMapper (new YAMLFactory ());
104+
105+ final PluginModel pluginModel = mapper .readValue (inputStream , PluginModel .class );
106+ assertThat (pluginModel .getPluginName (), equalTo ("customPlugin" ));
107+ assertThat (pluginModel .getPluginSettings (), equalTo (null ));
108+ }
109+
97110 @ Test
98111 final void testUsingCustomSerializerWithPluginSettings_noExceptions () throws JsonGenerationException , JsonMappingException , IOException {
99112 final PluginModel pluginModel = new PluginModel ("customPlugin" , validPluginSettings ());
@@ -141,10 +154,28 @@ final void testUsingCustomDeserializer_with_array() throws JsonParseException, J
141154 assertThat (readValue .listOfPlugins .get (1 ).getPluginSettings ().get ("key2" ), equalTo ("value2" ));
142155 }
143156
157+ @ Test
158+ final void testUsingCustomDeserializer_with_array_of_three_preserves_all_entries () throws JsonParseException , JsonMappingException , IOException {
159+ InputStream inputStream = PluginModelTests .class .getResourceAsStream ("/list_of_plugins_multiple_fields.yaml" );
160+
161+ final ObjectMapper mapper = new ObjectMapper (new YAMLFactory ());
162+
163+ final PluginHolder readValue = mapper .readValue (inputStream , PluginHolder .class );
164+ assertThat (readValue , notNullValue ());
165+ assertThat (readValue .listOfPlugins , notNullValue ());
166+ assertThat (readValue .listOfPlugins .size (), equalTo (3 ));
167+ assertThat (readValue .listOfPlugins .get (0 ).getPluginName (), equalTo ("customPluginA" ));
168+ assertThat (readValue .listOfPlugins .get (0 ).getPluginSettings ().get ("key1" ), equalTo ("value1" ));
169+ assertThat (readValue .listOfPlugins .get (1 ).getPluginName (), equalTo ("customPluginB" ));
170+ assertThat (readValue .listOfPlugins .get (1 ).getPluginSettings ().get ("key2" ), equalTo ("value2" ));
171+ assertThat (readValue .listOfPlugins .get (2 ).getPluginName (), equalTo ("customPluginC" ));
172+ assertThat (readValue .listOfPlugins .get (2 ).getPluginSettings ().get ("key3" ), equalTo ("value3" ));
173+ }
174+
144175 @ Test
145176 final void testRoundTrip_withEmptyObject () throws IOException {
146177 final InputStream inputStream = PluginModelTests .class .getResourceAsStream ("plugin_model_with_empty_object.yaml" );
147- final ObjectMapper mapper = new ObjectMapper (new YAMLFactory (). enable ( YAMLGenerator . Feature . USE_PLATFORM_LINE_BREAKS ) );
178+ final ObjectMapper mapper = new ObjectMapper (new YAMLFactory ());
148179
149180 final PluginModel pluginModel1 = mapper .readValue (inputStream , PluginModel .class );
150181 assertThat (pluginModel1 .getPluginName (), equalTo ("customPlugin" ));
@@ -161,63 +192,76 @@ final void testRoundTrip_withEmptyObject() throws IOException {
161192 @ Test
162193 final void testRoundTrip_withNullValue () throws IOException {
163194 final InputStream inputStream = PluginModelTests .class .getResourceAsStream ("plugin_model_with_null.yaml" );
164- final ObjectMapper mapper = new ObjectMapper (new YAMLFactory (). enable ( YAMLGenerator . Feature . USE_PLATFORM_LINE_BREAKS ) );
195+ final ObjectMapper mapper = new ObjectMapper (new YAMLFactory ());
165196
166- // null input -> deserializes to empty settings
197+ // explicit null input -> deserializes with null settings (preserves null)
167198 final PluginModel pluginModel1 = mapper .readValue (inputStream , PluginModel .class );
168199 assertThat (pluginModel1 .getPluginName (), equalTo ("customPlugin" ));
169- assertThat (pluginModel1 .getPluginSettings (). size () , equalTo (0 ));
200+ assertThat (pluginModel1 .getPluginSettings (), equalTo (null ));
170201
171- // empty settings -> serializes as {}
202+ // null settings -> serializes back as null (round-trip preserved)
172203 final String serialized = mapper .writeValueAsString (pluginModel1 );
173- assertThat (serialized .contains ("{} " ), equalTo (true ));
204+ assertThat (serialized .contains ("null " ), equalTo (true ));
174205
175206 final PluginModel pluginModel2 = mapper .readValue (serialized , PluginModel .class );
176207 assertThat (pluginModel2 .getPluginName (), equalTo ("customPlugin" ));
177- assertThat (pluginModel2 .getPluginSettings (). size () , equalTo (0 ));
208+ assertThat (pluginModel2 .getPluginSettings (), equalTo (null ));
178209 }
179210
180211 @ Test
181212 final void testRoundTrip_withEmptyValue () throws IOException {
182213 final InputStream inputStream = PluginModelTests .class .getResourceAsStream ("plugin_model_with_empty_value.yaml" );
183- final ObjectMapper mapper = new ObjectMapper (new YAMLFactory (). enable ( YAMLGenerator . Feature . USE_PLATFORM_LINE_BREAKS ) );
214+ final ObjectMapper mapper = new ObjectMapper (new YAMLFactory ());
184215
185- // empty value (no value after colon) -> deserializes to empty settings
216+ // no- value (customPlugin:) -> same as null -> deserializes with null settings
186217 final PluginModel pluginModel1 = mapper .readValue (inputStream , PluginModel .class );
187218 assertThat (pluginModel1 .getPluginName (), equalTo ("customPlugin" ));
188- assertThat (pluginModel1 .getPluginSettings (). size () , equalTo (0 ));
219+ assertThat (pluginModel1 .getPluginSettings (), equalTo (null ));
189220
190- // empty settings -> serializes as {}
221+ // null settings -> serializes back as null (round-trip preserved)
191222 final String serialized = mapper .writeValueAsString (pluginModel1 );
192- assertThat (serialized .contains ("{} " ), equalTo (true ));
223+ assertThat (serialized .contains ("null " ), equalTo (true ));
193224
194225 final PluginModel pluginModel2 = mapper .readValue (serialized , PluginModel .class );
195226 assertThat (pluginModel2 .getPluginName (), equalTo ("customPlugin" ));
196- assertThat (pluginModel2 .getPluginSettings (). size () , equalTo (0 ));
227+ assertThat (pluginModel2 .getPluginSettings (), equalTo (null ));
197228 }
198229
199230 @ Test
200231 final void testDeserialize_emptyString_throwsException () throws IOException {
201232 final InputStream inputStream = PluginModelTests .class .getResourceAsStream ("plugin_model_empty_string.yaml" );
202233 final ObjectMapper mapper = new ObjectMapper (new YAMLFactory ());
203234
204- final JsonMappingException exception = org . junit . jupiter . api . Assertions . assertThrows (
235+ final JsonMappingException exception = assertThrows (
205236 JsonMappingException .class ,
206237 () -> mapper .readValue (inputStream , PluginModel .class )
207238 );
208- assertThat (exception .getMessage (), org . hamcrest . Matchers . containsString ("Empty string is not allowed" ));
239+ assertThat (exception .getMessage (), containsString ("Empty string is not allowed" ));
209240 }
210241
211242 @ Test
212243 final void testDeserialize_nonEmptyString_throwsException () throws IOException {
213244 final String yaml = "customPlugin: someStringValue" ;
214245 final ObjectMapper mapper = new ObjectMapper (new YAMLFactory ());
215246
216- final JsonMappingException exception = org . junit . jupiter . api . Assertions . assertThrows (
247+ final JsonMappingException exception = assertThrows (
217248 JsonMappingException .class ,
218249 () -> mapper .readValue (yaml , PluginModel .class )
219250 );
220- assertThat (exception .getMessage (), org .hamcrest .Matchers .containsString ("String values not allowed" ));
251+ assertThat (exception .getMessage (), containsString ("String values not allowed" ));
252+ }
253+
254+ @ ParameterizedTest
255+ @ ValueSource (strings = {"plugin_model_number_value.yaml" , "plugin_model_boolean_value.yaml" , "plugin_model_array_value.yaml" })
256+ final void testDeserialize_invalidTokenType_throwsException (final String resourceName ) throws IOException {
257+ final InputStream inputStream = PluginModelTests .class .getResourceAsStream (resourceName );
258+ final ObjectMapper mapper = new ObjectMapper (new YAMLFactory ());
259+
260+ final JsonMappingException exception = assertThrows (
261+ JsonMappingException .class ,
262+ () -> mapper .readValue (inputStream , PluginModel .class )
263+ );
264+ assertThat (exception .getMessage (), containsString ("Unexpected value for plugin" ));
221265 }
222266
223267 static Map <String , Object > validPluginSettings () {
0 commit comments