re base code
[sdc.git] / catalog-be / src / test / java / org / openecomp / sdc / be / components / merge / property / PropertyDataValueMergeBusinessLogicTest.java
1 package org.openecomp.sdc.be.components.merge.property;
2
3 import com.fasterxml.jackson.core.type.TypeReference;
4 import com.fasterxml.jackson.databind.ObjectMapper;
5 import com.google.common.collect.Maps;
6 import fj.data.Either;
7 import org.junit.Before;
8 import org.junit.Test;
9 import org.junit.runner.RunWith;
10 import org.mockito.Mock;
11 import org.mockito.junit.MockitoJUnitRunner;
12 import org.openecomp.sdc.be.components.utils.PropertyDataDefinitionBuilder;
13 import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
14 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
15 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
16 import org.openecomp.sdc.be.model.DataTypeDefinition;
17 import org.openecomp.sdc.be.model.PropertyDefinition;
18 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
19 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
20
21 import java.io.IOException;
22 import java.util.*;
23 import java.util.function.Function;
24 import java.util.stream.Collectors;
25 import java.util.stream.Stream;
26
27 import static org.assertj.core.api.Assertions.assertThat;
28 import static org.junit.Assert.assertEquals;
29 import static org.junit.Assert.assertTrue;
30 import static org.mockito.Mockito.when;
31
32 @RunWith(MockitoJUnitRunner.class)
33 public class PropertyDataValueMergeBusinessLogicTest {
34
35     private ObjectMapper mapper = new ObjectMapper();
36     
37     private PropertyDataValueMergeBusinessLogic testInstance;
38
39     @Mock
40     private ApplicationDataTypeCache applicationDataTypeCache;
41
42     @Before
43     public void setUp() throws Exception {
44         PropertyValueMerger propertyValueMerger = new PropertyValueMerger();
45         
46         testInstance = new PropertyDataValueMergeBusinessLogic(propertyValueMerger, applicationDataTypeCache);
47     }
48
49     @Test
50     public void mergeProperties_emptyOldAndNewValues() throws Exception {
51         PropertyDataDefinition oldProp = createProp("prop1", ToscaPropertyType.STRING.getType(), null, null);
52         PropertyDataDefinition newProp = createProp("prop1", ToscaPropertyType.STRING.getType(), null, null);
53         testMergeProps(oldProp, newProp, null);
54     }
55
56     @Test
57     public void mergeProperties_emptyOldValue() throws Exception {
58         PropertyDataDefinition oldProp = createProp("prop1", ToscaPropertyType.STRING.getType(), null, null);
59         PropertyDataDefinition newProp = createProp("prop1", ToscaPropertyType.STRING.getType(), null, "newVal");
60         testMergeProps(oldProp, newProp, "newVal");
61     }
62
63     @Test
64     public void mergeSimpleStringType_copyOldValueIfNoNewValue() throws Exception {
65         PropertyDataDefinition oldProp = createProp("prop1", ToscaPropertyType.STRING.getType(), null, "val1");
66         PropertyDataDefinition newProp = createProp("prop1", ToscaPropertyType.STRING.getType(), null, null);
67         testMergeProps(oldProp, newProp, "val1");
68     }
69
70     @Test
71     public void mergeSimpleStringType_dontCopyOldValIfHasNewVal() throws Exception {
72         PropertyDataDefinition oldProp = createProp("prop1", ToscaPropertyType.STRING.getType(), null, "val1");
73         PropertyDataDefinition newProp = createProp("prop1", ToscaPropertyType.STRING.getType(), null, "newVal");
74         testMergeProps(oldProp, newProp, "newVal");
75     }
76
77     @Test
78     public void mergeSimpleIntType_copyOldValueIfNoNewValue() throws Exception {
79         PropertyDataDefinition oldProp = createProp("prop1", ToscaPropertyType.INTEGER.getType(), null, "44");
80         PropertyDataDefinition newProp = createProp("prop1", ToscaPropertyType.INTEGER.getType(), null, null);
81         testMergeProps(oldProp, newProp, "44");
82     }
83
84     @Test
85     public void mergeSimpleIntType_dontCopyOldValIfHasNewVal() throws Exception {
86         PropertyDataDefinition oldProp = createProp("prop1", ToscaPropertyType.INTEGER.getType(), null, "44");
87         PropertyDataDefinition newProp = createProp("prop1", ToscaPropertyType.INTEGER.getType(), null, "45");
88         testMergeProps(oldProp, newProp, "45");
89     }
90
91     @Test
92     public void mergeSimpleBooleanType_copyOldValueIfNoNewValue() throws Exception {
93         PropertyDataDefinition oldProp = createProp("prop1", ToscaPropertyType.BOOLEAN.getType(), null, "false");
94         PropertyDataDefinition newProp = createProp("prop1", ToscaPropertyType.BOOLEAN.getType(), null, null);
95         testMergeProps(oldProp, newProp, "false");
96     }
97
98     @Test
99     public void mergeSimpleBooleanType_dontCopyOldValIfHasNewVal() throws Exception {
100         PropertyDataDefinition oldProp = createProp("prop1", ToscaPropertyType.BOOLEAN.getType(), null, "false");
101         PropertyDataDefinition newProp = createProp("prop1", ToscaPropertyType.BOOLEAN.getType(), null, "true");
102         testMergeProps(oldProp, newProp, "true");
103     }
104
105     @Test
106     public void mergeSimpleListType_copyOldValuesByIndex() throws Exception {
107         PropertyDataDefinition oldProp = createProp("prop1", ToscaPropertyType.LIST.getType(), "string", "[\"a\", \"b\"]");
108         PropertyDataDefinition newProp = createProp("prop1", ToscaPropertyType.LIST.getType(), "string", "[\"x\", \"\"]");
109         testMergeProps(oldProp, newProp, "[\"x\",\"b\"]");
110     }
111     
112     @Test
113     public void mergeSimpleListType_differentSize() throws Exception {
114         PropertyDataDefinition oldProp = createProp("prop1", ToscaPropertyType.LIST.getType(), "string", "[\"a\", \"b\", \"c\"]");
115         PropertyDataDefinition newProp = createProp("prop1", ToscaPropertyType.LIST.getType(), "string", "[\"x\", \"\"]");
116         testMergeProps(oldProp, newProp, "[\"x\",\"\"]");
117     }
118
119     @Test
120     public void mergeSimpleListType_jsonList() throws Exception {
121         PropertyDataDefinition oldProp = createProp("prop1", ToscaPropertyType.LIST.getType(), "json", "[[\"a\", \"b\"], \"c\"]");
122         PropertyDataDefinition newProp = createProp("prop1", ToscaPropertyType.LIST.getType(), "json", "[[\"a\"], \"d\"]");
123         testMergeProps(oldProp, newProp, "[[\"a\"],\"d\"]");
124     }
125
126     /**                                   
127      * Old property:                       New property:                           Expected:                           
128      *   {                                  {                                       {                                 
129      *     "mac_range_plan": "y",             "mac_range_plan": "",                   "mac_range_plan": "y",          
130      *     "mac_count_required": {            "mac_count_required": {                 "mac_count_required": {         
131      *       "is_required": true,               "is_required": false,                   "is_required": false,         
132      *       "count": 44                        "mac_address": "myAddress"              "mac_address": "myAddress"    
133      *     }                                  }                                       }                               
134      *   }                                  }                                       }                                 
135      *                                                                                                                
136      */
137     @Test
138     public void mergeComplexType() throws Exception {
139         PropertyDataDefinition oldProp = createProp("prop1", "myType", null, "{\"mac_range_plan\":\"y\", \"mac_count_required\":{\"is_required\":true,\"count\":44}}");
140         PropertyDataDefinition newProp = createProp("prop1", "myType", null, "{\"mac_range_plan\":\"\",  \"mac_count_required\":{\"is_required\":false, \"mac_address\":\"myAddress\"}}");
141         
142         DataTypeDefinition myType = new DataTypeDefinition();
143         myType.setName("myType");
144       
145         PropertyDefinition mac_range_plan = new PropertyDefinition();
146         mac_range_plan.setName("mac_range_plan");
147         mac_range_plan.setType("string");
148
149         PropertyDefinition mac_count_required = new PropertyDefinition();
150         mac_count_required.setName("mac_count_required");
151         mac_count_required.setType("map");
152         
153         myType.setProperties(Arrays.asList(mac_range_plan, mac_count_required));
154         Map<String, DataTypeDefinition> dataTypes = Collections.singletonMap(myType.getName(), myType);
155
156         when(applicationDataTypeCache.getAll()).thenReturn(Either.left(dataTypes));
157         
158         testInstance.mergePropertyValue(oldProp, newProp, Collections.emptyList());
159         
160         assertEquals("myType", "{\"mac_range_plan\":\"y\",\"mac_count_required\":{\"is_required\":false,\"mac_address\":\"myAddress\"}}", newProp.getValue());
161     }
162     
163     
164     
165     
166     /**                                                                                    Expected property:
167      * Old property:                            New property:                                {
168      *   {                                        {                                            "mac_range_plan": "n",
169      *     "mac_range_plan": "y",   "               "mac_range_plan": "n",                     "mymap": {
170      *     "mymap": {                                   "mymap": {                                     "mac_count_required": {      
171      *            "mac_count_required": {                       "mac_count_required": {                               "is_required": false,
172      *              "is_required": true,                          "is_required": false                        "count": 44                 
173      *              "count": 44                                     },                                             },
174      *            },                                            "host":"localhost",                                "host":"localhost",
175      *            "backup-mode":"daily",                        "ip":"127.0.0.1"                                   "ip":"127.0.0.1"
176      *            "ip":"0.0.0.0"                        }                                          }                            
177      *     }                                      }                                          }
178      *   }                                                                                      
179      *                                                                                       
180      */
181     @Test
182     public void mergeComplexType_containingMapWithComplexType() throws Exception {
183         PropertyDataDefinition oldProp = createProp("prop1", "myType", null, "{\"mac_range_plan\":\"y\",\"mymap\": {\"mac_count_required\": {\"is_required\":true,\"count\":44},\"backup-mode\":\"daily\",\"ip\":\"0.0.0.0\"}}");
184         PropertyDataDefinition newProp = createProp("prop1", "myType", null, "{\"mac_range_plan\":\"n\",\"mymap\": {\"mac_count_required\": {\"is_required\":false},\"host\":\"localhost\",\"ip\":\"127.0.0.1\"}}");
185         
186         DataTypeDefinition myType = new DataTypeDefinition();
187         myType.setName("myType");
188       
189         PropertyDefinition mac_range_plan = new PropertyDefinition();
190         mac_range_plan.setName("mac_range_plan");
191         mac_range_plan.setType("string");
192         
193         PropertyDefinition mymap = new PropertyDefinition();
194         mymap.setName("mymap");
195         mymap.setType("map");
196
197         PropertyDefinition mac_count_required = new PropertyDefinition();
198         mac_count_required.setName("mac_count_required");
199         mac_count_required.setType("MacType");
200         
201         SchemaDefinition entrySchema = new SchemaDefinition();
202         entrySchema.setProperty(mac_count_required);
203         mymap.setSchema(entrySchema);
204         
205         myType.setProperties(Arrays.asList(mac_range_plan, mymap, mac_count_required));
206         Map<String, DataTypeDefinition> dataTypes = Collections.singletonMap(myType.getName(), myType);
207
208         when(applicationDataTypeCache.getAll()).thenReturn(Either.left(dataTypes));
209         
210         testInstance.mergePropertyValue(oldProp, newProp, Collections.emptyList());
211         
212         assertEquals("myType", "{\"mac_range_plan\":\"n\",\"mymap\":{\"ip\":\"127.0.0.1\",\"mac_count_required\":{\"is_required\":false,\"count\":44},\"host\":\"localhost\"}}", newProp.getValue());
213     }
214
215
216     /*                                                               
217      *  Old Property:                      New Property:                          Expected:          
218      *  [                                  [                                      [                      
219      *    {                                   {                                      {                   
220      *      "prop1": "val1",                    "prop2": {                             "prop2": {        
221      *      "prop2": {                            "prop3": false                         "prop3": false  
222      *        "prop3": true,                    }                                      }                 
223      *        "prop4": 44                     }                                      }                   
224      *      }                              ]                                      ]                      
225      *    },                                                         
226      *    {
227      *      "prop1": "val2",
228      *      "prop2": {
229      *        "prop3": true
230      *      }
231      *    }
232      *  ]
233      *  
234      */
235     @Test
236     public void mergeListOfComplexType_differentSize() throws Exception {
237         PropertyDataDefinition oldProp = createProp("prop1", "list", "myType", "[{\"prop1\":\"val1\", \"prop2\":{\"prop3\":true,\"prop4\":44}}, " +
238                                                                                        "{\"prop1\":\"val2\", \"prop2\":{\"prop3\":true}}]");
239         PropertyDataDefinition newProp = createProp("prop1", "list", "myType", "[{\"prop2\":{\"prop3\":false}}]");
240
241         Map<String, DataTypeDefinition> dataTypes = buildDataTypes();
242         when(applicationDataTypeCache.getAll()).thenReturn(Either.left(dataTypes));
243         testInstance.mergePropertyValue(oldProp, newProp, Collections.emptyList());
244         assertEquals("myType", "[{\"prop2\":{\"prop3\":false}}]", newProp.getValue());
245     }
246     
247     
248     /*
249      *  Old Property:                     New Property:                 Expected:
250      *  [                                 [                             [
251      *    {                                 {                            {
252      *      "prop1": "val1",                  "prop1": "",                 "prop1": "val1",
253      *      "prop2": {                        "prop2": {                   "prop2": {
254      *        "prop3": true,                    "prop4": 45                  "prop3": true
255      *        "prop4": 44                     }                              "prop4": 45
256      *      }                               },                             }                       
257      *    },                                {                            },                        
258      *    {                                                              {                         
259      *      "prop1": "val2",                  "prop2": {                   "prop1": "val2",                        
260      *      "prop2": {                          "prop3": false             "prop2": {              
261      *        "prop3": true                   }                              "prop3": false        
262      *      }                               }                              }                       
263      *    }                               ]                              }                         
264      *  ]                                                              ]                           
265      *                                                                                             
266      */                                                                                            
267     @Test
268     public void mergeListOfComplexType() throws Exception {
269         PropertyDataDefinition oldProp = createProp("lprop", "list", "myType", "[{\"prop1\":\"val1\", \"prop2\":{\"prop3\":true,\"prop4\":44}}, " +
270                                                                                 "{\"prop1\":\"val2\", \"prop2\":{\"prop3\":true}}]");
271         PropertyDataDefinition newProp = createProp("lprop", "list", "myType", "[{\"prop1\":\"\", \"prop2\":{\"prop4\":45}}, {\"prop2\":{\"prop3\":false}}]");
272
273         
274         DataTypeDefinition myType = new DataTypeDefinition();
275         myType.setName("myType");
276         
277         Map<String, DataTypeDefinition> dataTypes = buildDataTypes();
278         when(applicationDataTypeCache.getAll()).thenReturn(Either.left(dataTypes));
279         testInstance.mergePropertyValue(oldProp, newProp, Collections.emptyList());
280         assertEquals("lprop",  "[{\"prop2\":{\"prop4\":45,\"prop3\":true},\"prop1\":\"val1\"},{\"prop2\":{\"prop3\":false},\"prop1\":\"val2\"}]", newProp.getValue());
281     }
282     
283     
284     
285     /*
286      * Old Property:                          New Property:                               Expected:                          
287      * {                                      {                                           {
288      *   "lprop": [                             "lprop": [                                  "lprop": [
289      *     {                                      {                                           {
290      *       "prop1": "val1",                       "prop2": [                                  "prop1": "val1",
291      *       "prop2": [                               {                                         "prop2": [
292      *         {                                        "prop3": true                             {
293      *           "prop3": true,                       },                                            "prop3": true,
294      *           "prop4": 44                              {                                             "prop4": 44
295      *         },                                           "prop4":69                                },
296      *         {                                          }                                               {
297      *           "prop3": false,                    ]                                               "prop3": false,
298      *           "prop4": 96                      },                                                "prop4": 69
299      *         }                                  {                                               }
300      *       ]                                      "prop1": "val1",                            ]
301      *     },                                       "prop2": [                                },
302      *     {                                          {                                       {
303      *       "prop1": "val2",                           "prop3": false                          "prop1": "val1",
304      *       "prop2": [                               }                                         "prop2": [
305      *         {                                    ]                                             {
306      *           "prop3": true                    }                                                 "prop3": false
307      *         }                                ],                                                }
308      *       ]                                  "prop5": "value05"                              ]
309      *     }                                  }                                               }
310      *   ],                                                                                 ],
311      *   "prop5": "value5"                                                                  "prop5": "value05"
312      * }                                                                                  }   
313      *
314      *
315      */                                                                                            
316     @Test
317     public void mergeComplexType_containsListOfComplexType() throws Exception {
318         PropertyDataDefinition oldProp = createProp("complexProp", "complexType", null, 
319                 "{\"lprop\":[{\"prop1\":\"val1\",\"prop2\":[{\"prop3\":true,\"prop4\":44},{\"prop3\":false,\"prop4\":96}]}," + 
320                 "{\"prop1\":\"val2\",\"prop2\":[{\"prop3\":true}]}],\"prop5\":\"value5\"} ");
321         PropertyDataDefinition newProp = createProp("complexProp", "complexType", null,
322                 "{\"lprop\":[{\"prop2\":[{\"prop3\":true},{\"prop4\":69}]},{\"prop1\":\"val1\",\"prop2\":[{\"prop3\":false}]}],\"prop5\":\"value05\"}");
323
324         DataTypeDefinition complexType = new DataTypeDefinition();
325         complexType.setName("complexType");
326
327         PropertyDefinition lprop = new PropertyDefinition(createProp("lprop", "list", "myType", null));
328
329         PropertyDefinition prop5 = new PropertyDefinition();
330         prop5.setName("prop5");
331         prop5.setType("string");
332         
333         DataTypeDefinition complexProp = new DataTypeDefinition();
334         complexProp.setName("complexType");
335         complexType.setProperties(Arrays.asList(lprop, prop5));
336         
337         DataTypeDefinition myType = new DataTypeDefinition();
338         myType.setName("myType");
339
340         PropertyDefinition prop1 = new PropertyDefinition();
341         prop1.setName("prop1");
342         prop1.setType("string");
343         
344         DataTypeDefinition myInnerType = new DataTypeDefinition();
345         myInnerType.setName("myInnerType");
346
347         PropertyDefinition prop2 = new PropertyDefinition(createProp("prop2", "list", "myInnerType", null));
348
349         PropertyDefinition prop3 = new PropertyDefinition();
350         prop3.setName("prop3");
351         prop3.setType("boolean");
352
353         PropertyDefinition prop4 = new PropertyDefinition();
354         prop4.setName("prop4");
355         prop4.setType("integer");
356
357         complexType.setProperties(Arrays.asList(lprop, prop5));
358         myType.setProperties(Arrays.asList(prop1, prop2));
359         myInnerType.setProperties(Arrays.asList(prop3, prop4));
360         
361         Map<String, DataTypeDefinition> dataTypes = Stream.of(complexType, myType, myInnerType)
362                                                            .collect(Collectors.toMap(DataTypeDefinition::getName, Function.identity()));
363         
364         when(applicationDataTypeCache.getAll()).thenReturn(Either.left(dataTypes));
365         
366         testInstance.mergePropertyValue(oldProp, newProp, Collections.emptyList());
367         
368         assertEquals("complexProp", 
369                 "{\"lprop\":[{\"prop2\":[{\"prop4\":44,\"prop3\":true},{\"prop4\":69,\"prop3\":false}],\"prop1\":\"val1\"},{\"prop2\":[{\"prop3\":false}],\"prop1\":\"val1\"}],\"prop5\":\"value05\"}",
370                 newProp.getValue());
371     }
372     
373     
374     @Test
375     public void mergeMapType_differentSize() throws Exception {
376         PropertyDataDefinition oldProp = createProp("prop1", "map", "string", "{\"prop1\":\"val1\", \"prop2\":\"val2\", \"prop3\":\"val3\"}");
377         PropertyDataDefinition newProp = createProp("prop1", "map", "string", "{\"prop1\":\"valY\", \"prop2\":\"\"}");
378         
379         HashMap<String, String> expected = Maps.newHashMap();
380         expected.put("prop1", "valY");
381         expected.put("prop2", "val2");
382         verifyMapMerge(getMergedMapProp(oldProp, newProp, Collections.emptyList()), expected);
383     }
384     
385     
386     @Test
387     public void mergeMapType() throws Exception {
388         PropertyDataDefinition oldProp = createProp("prop1", "map", "string", "{\"prop1\":\"val1\", \"prop2\":\"val2\", \"prop3\":\"\", \"prop4\":\"val4\"}");
389         PropertyDataDefinition newProp = createProp("prop1", "map", "string", "{\"prop1\":\"valY\", \"prop2\":\"\", \"prop3\":\"val3\", \"prop5\":\"val5\"}");
390         
391         
392         HashMap<String, String> expected = Maps.newHashMap();
393         expected.put("prop1", "valY");
394         expected.put("prop2", "val2");
395         expected.put("prop3", "val3");
396         expected.put("prop5", "val5");
397         verifyMapMerge(getMergedMapProp(oldProp, newProp, Collections.emptyList()), expected);
398     }
399
400     @Test
401     public void mergeMapTypeWhenNewValueIsEmpty() throws Exception {
402         PropertyDataDefinition oldProp = createProp("prop1", "map", "string", "{\"prop1\":\"val1\", \"prop2\":\"val2\", \"prop3\":\"val3\"}");
403         PropertyDataDefinition newProp = createProp("prop1", "map", "string", null);
404         HashMap<String, String> expected = Maps.newHashMap();
405         expected.put("prop1", "val1");
406         expected.put("prop2", "val2");
407         expected.put("prop3", "val3");
408         verifyMapMerge(getMergedMapProp(oldProp, newProp, Collections.singletonList("input1")), expected);
409     }
410
411     @Test
412     public void mergeGetInputValue() throws Exception {
413         PropertyDataDefinition oldProp = createGetInputProp("prop1", "string", null, "input1");
414         PropertyDataDefinition newProp = createProp("prop1", "string", null, "");
415         testMergeProps(oldProp, newProp, oldProp.getValue(), Collections.singletonList("input1"));
416         assertEquals(oldProp.getGetInputValues(), newProp.getGetInputValues());
417     }
418
419     @Test
420     public void mergeGetInputValue_valueIsNull_InNewProp() throws Exception {
421         PropertyDataDefinition oldProp = createGetInputProp("prop1", "string", null, "input1");
422         PropertyDataDefinition newProp = createProp("prop1", "string", null, null);
423         testMergeProps(oldProp, newProp,"{\"get_input\":\"input1\"}", Collections.singletonList("input1"));
424         assertGetInputValues(newProp, "input1");
425     }
426
427     /*
428      * Old property:                      New property:                       Expected:              
429      * [                                  [                                   [                          
430      *   {                                  {                                   {                         
431      *     "mac_range_plan": {                "mac_count_required": {           "mac_range_plan": {     
432      *       "get_input": "input1"              "is_required": true               "get_input": "input1" 
433      *     },                                 }                                 },                      
434      *     "mac_count_required": {          }                                   "mac_count_required": {                                    
435      *       "is_required": true,                                                 "is_required": true         
436      *       "count": {                   inputs: intput1, input2               }                             
437      *         "get_input": "input2"      ]                                   }                               
438      *       }                                                                                                
439      *     }                                                                  inputs: input2                    
440      *   }                                                                  ]                                 
441      *                                                                        
442      *   inputs: intput1, input2                                                                            
443      * ]                                                                                                    
444      * 
445      * 
446      * 
447      */
448     @Test
449     public void mergeComplexGetInputValue() throws Exception {
450         PropertyDataDefinition oldProp = new PropertyDataDefinitionBuilder().addGetInputValue("input1").addGetInputValue("input2").setName("prop1").setType("myType").setValue("{\"mac_range_plan\":{\"get_input\": \"input1\"}, \"mac_count_required\":{\"is_required\":true,\"count\":{\"get_input\": \"input2\"}}}").build();
451         PropertyDataDefinition newProp = new PropertyDataDefinitionBuilder().addGetInputValue("input2").setName("prop1").setType("myType").setValue("{\"mac_count_required\":{\"is_required\":true}}").build();
452         testMergeProps(oldProp, newProp,"{\"mac_range_plan\":{},\"mac_count_required\":{\"is_required\":true}}", Collections.singletonList("input2"));
453         assertGetInputValues(newProp, "input2");
454     }
455
456     @Test
457     public void mergeListValueWithMultipleGetInputs() throws Exception {
458         PropertyDataDefinition oldProp = new PropertyDataDefinitionBuilder()
459                 .addGetInputValue("input1").addGetInputValue("input2").addGetInputValue("input3")
460                 .setName("prop1")
461                 .setType("list").setSchemaType("string")
462                 .setValue("[{\"get_input\": \"input2\"},{\"get_input\": \"input3\"},{\"get_input\": \"input1\"}]")
463                 .build();
464
465         PropertyDataDefinition newProp = new PropertyDataDefinitionBuilder()
466                 .addGetInputValue("input3")
467                 .addGetInputValue("input5")
468                 .setName("prop1")
469                 .setType("list").setSchemaType("string")
470                 .setValue("[{\"get_input\": \"input5\"}, {\"get_input\": \"input3\"}]")
471                 .build();
472
473         testMergeProps(oldProp, newProp,"[{\"get_input\":\"input5\"},{\"get_input\":\"input3\"}]");
474         assertGetInputValues(newProp, "input3", "input5");
475     }
476
477     private void assertGetInputValues(PropertyDataDefinition newProp, String ... expectedInputNames) {
478         assertTrue(newProp.isGetInputProperty());
479         assertEquals(newProp.getGetInputValues().size(), expectedInputNames.length);
480         for (int i = 0; i < expectedInputNames.length; i++) {
481             String expectedInputName = expectedInputNames[i];
482             GetInputValueDataDefinition getInputValueDataDefinition = newProp.getGetInputValues().get(i);
483             assertEquals(getInputValueDataDefinition.getInputName(), expectedInputName);
484         }
485     }
486     
487     private void testMergeProps(PropertyDataDefinition oldProp, PropertyDataDefinition newProp, String expectedValue) {
488         testMergeProps(oldProp, newProp, expectedValue, Collections.emptyList());
489     }
490
491     private void testMergeProps(PropertyDataDefinition oldProp, PropertyDataDefinition newProp, String expectedValue,  List<String> getInputsToMerge) {
492         when(applicationDataTypeCache.getAll()).thenReturn(Either.left(Collections.emptyMap()));
493         testInstance.mergePropertyValue(oldProp, newProp, getInputsToMerge);
494         assertEquals(expectedValue, newProp.getValue());
495     }
496
497
498     private String getMergedMapProp(PropertyDataDefinition oldProp, PropertyDataDefinition newProp, List<String> getInputsToMerge) {
499         when(applicationDataTypeCache.getAll()).thenReturn(Either.left(Collections.emptyMap()));
500         testInstance.mergePropertyValue(oldProp, newProp, getInputsToMerge);
501         return newProp.getValue();
502     }
503
504     private void verifyMapMerge(String newValue, Map<String, String> expectedValues) {
505         Map<String, String> values = convertJsonToMap(newValue);
506         assertThat(values).isNotNull();
507         assertThat(values).containsAllEntriesOf(expectedValues);
508     }
509
510     private PropertyDataDefinition createProp(String name, String type, String innerType, String val) {
511         return new PropertyDataDefinitionBuilder()
512                 .setType(type)
513                 .setSchemaType(innerType)
514                 .setValue(val)
515                 .setName(name)
516                 .build();
517     }
518
519     private PropertyDataDefinition createGetInputProp(String name, String type, String innerType, String inputName) {
520         String val = String.format("{\"get_input\":\"%s\"}", inputName);
521         return new PropertyDataDefinitionBuilder()
522                 .setType(type)
523                 .setSchemaType(innerType)
524                 .setValue(val)
525                 .addGetInputValue(inputName)
526                 .setName(name)
527                 .build();
528
529     }
530
531     private Map<String, String> convertJsonToMap(String jsonString) {
532         try {
533             return mapper.readValue(jsonString, new TypeReference<Map<String, String>>(){});
534         } catch (IOException e) {
535             return null;
536         }
537     }
538
539     private Map<String, DataTypeDefinition> buildDataTypes() {
540         DataTypeDefinition myType = new DataTypeDefinition();
541         myType.setName("myType");
542         DataTypeDefinition myInnerType = new DataTypeDefinition();
543         myInnerType.setName("myInnerType");
544
545         PropertyDefinition prop1 = new PropertyDefinition();
546         prop1.setName("prop1");
547         prop1.setType("string");
548
549         PropertyDefinition prop2 = new PropertyDefinition();
550         prop2.setName("prop2");
551         prop2.setType("myInnerType");
552
553         PropertyDefinition prop3 = new PropertyDefinition();
554         prop3.setName("prop3");
555
556         PropertyDefinition prop4 = new PropertyDefinition();
557         prop4.setName("prop4");
558
559         myType.setProperties(Arrays.asList(prop1, prop2));
560         myInnerType.setProperties(Arrays.asList(prop3, prop4));
561
562         return Stream.of(myType, myInnerType).collect(Collectors.toMap(DataTypeDefinition::getName, Function.identity()));
563     }
564
565
566 }