Merge "Data fragment update by xpath - parsing and validation"
[cps.git] / cps-service / src / test / groovy / org / onap / cps / model / DataNodeBuilderSpec.groovy
1 /*
2  *  ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 Pantheon.tech
4  *  ================================================================================
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  *
16  *  SPDX-License-Identifier: Apache-2.0
17  *  ============LICENSE_END=========================================================
18  */
19
20 package org.onap.cps.model
21
22 import org.onap.cps.TestUtils
23 import org.onap.cps.spi.model.DataNodeBuilder
24 import org.onap.cps.utils.YangUtils
25 import org.onap.cps.yang.YangTextSchemaSourceSetBuilder
26 import spock.lang.Specification
27
28 class DataNodeBuilderSpec extends Specification {
29
30     Map<String, Map<String, Object>> expectedLeavesByXpathMap = [
31             '/test-tree'                             : [],
32             '/test-tree/branch[@name=\'Left\']'      : [name: 'Left'],
33             '/test-tree/branch[@name=\'Left\']/nest' : [name: 'Small', birds: ['Sparrow', 'Robin', 'Finch']],
34             '/test-tree/branch[@name=\'Right\']'     : [name: 'Right'],
35             '/test-tree/branch[@name=\'Right\']/nest': [name: 'Big', birds: ['Owl', 'Raven', 'Crow']]
36     ]
37
38     def 'Converting NormalizedNode (tree) to a DataNode (tree).'() {
39         given: 'the schema context for expected model'
40             def yangResourceNameToContent = TestUtils.getYangResourcesAsMap('test-tree.yang')
41             def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourceNameToContent) getSchemaContext()
42         and: 'the json data parsed into normalized node object'
43             def jsonData = TestUtils.getResourceFileContent('test-tree.json')
44             def normalizedNode = YangUtils.parseJsonData(jsonData, schemaContext)
45         when: 'the normalized node is converted to a data node'
46             def result = new DataNodeBuilder().withNormalizedNodeTree(normalizedNode).build()
47             def mappedResult = TestUtils.getFlattenMapByXpath(result)
48         then: '5 DataNode objects with unique xpath were created in total'
49             mappedResult.size() == 5
50         and: 'all expected xpaths were built'
51             mappedResult.keySet().containsAll(expectedLeavesByXpathMap.keySet())
52         and: 'each data node contains the expected attributes'
53             mappedResult.each {
54                 xpath, dataNode -> assertLeavesMaps(dataNode.getLeaves(), expectedLeavesByXpathMap[xpath])
55             }
56     }
57
58     def 'Converting NormalizedNode (tree) to a DataNode (tree) for known parent node.'() {
59         given: 'a schema context for expected model'
60             def yangResourceNameToContent = TestUtils.getYangResourcesAsMap('test-tree.yang')
61             def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourceNameToContent) getSchemaContext()
62         and: 'the json data parsed into normalized node object'
63             def jsonData = '{ "branch": [{ "name": "Branch", "nest": { "name": "Nest", "birds": ["bird"] } }] }'
64             def normalizedNode = YangUtils.parseJsonData(jsonData, schemaContext, "/test-tree")
65         when: 'the normalized node is converted to a data node with parent node xpath defined'
66             def result = new DataNodeBuilder()
67                     .withNormalizedNodeTree(normalizedNode)
68                     .withParentNodeXpath("/test-tree")
69                     .build()
70             def mappedResult = TestUtils.getFlattenMapByXpath(result)
71         then: '2 DataNode objects with unique xpath were created in total'
72             mappedResult.size() == 2
73         and: 'all expected xpaths were built'
74             mappedResult.keySet()
75                     .containsAll(['/test-tree/branch[@name=\'Branch\']', '/test-tree/branch[@name=\'Branch\']/nest'])
76     }
77
78     def static assertLeavesMaps(actualLeavesMap, expectedLeavesMap) {
79         expectedLeavesMap.each { key, value ->
80             {
81                 def actualValue = actualLeavesMap[key]
82                 if (value instanceof Collection<?> && actualValue instanceof Collection<?>) {
83                     assert value.size() == actualValue.size()
84                     assert value.containsAll(actualValue)
85                 } else {
86                     assert value == actualValue
87                 }
88             }
89         }
90     }
91
92 }