Merge "Normalize parent xpath when building datanodes in CpsDataService"
[cps.git] / cps-service / src / test / groovy / org / onap / cps / utils / DataMapUtilsSpec.groovy
1 /*
2  *  ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 Pantheon.tech
4  *  Modifications Copyright (C) 2020-2023 Nordix Foundation
5  *  Modifications Copyright (C) 2022 Bell Canada.
6  *  Modifications Copyright (C) 2023 TechMahindra Ltd.
7  *  ================================================================================
8  *  Licensed under the Apache License, Version 2.0 (the "License");
9  *  you may not use this file except in compliance with the License.
10  *  You may obtain a copy of the License at
11  *
12  *        http://www.apache.org/licenses/LICENSE-2.0
13  *  Unless required by applicable law or agreed to in writing, software
14  *  distributed under the License is distributed on an "AS IS" BASIS,
15  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  *  See the License for the specific language governing permissions and
17  *  limitations under the License.
18  *
19  *  SPDX-License-Identifier: Apache-2.0
20  *  ============LICENSE_END=========================================================
21  */
22
23 package org.onap.cps.utils
24
25 import org.onap.cps.spi.model.DataNodeBuilder
26 import spock.lang.Specification
27
28 class DataMapUtilsSpec extends Specification {
29
30     def noChildren = []
31
32     def 'Data node structure conversion to map.'() {
33         when: 'data node structure is converted to a map'
34             def result = DataMapUtils.toDataMap(dataNode)
35         then: 'root node identifier is null'
36             result.parent == null
37         then: 'root node leaves are top level elements'
38             result.parentLeaf == 'parentLeafValue'
39             result.parentLeafList == ['parentLeafListEntry1','parentLeafListEntry2']
40         and: 'leaves of child list element are listed as structures under common identifier'
41             result.'child-list'.collect().containsAll(['listElementLeaf': 'listElement1leafValue'],
42                                                       ['listElementLeaf': 'listElement2leafValue'])
43         and: 'leaves for child element is populated under its node identifier'
44             result.'child-object'.childLeaf == 'childLeafValue'
45         and: 'leaves for grandchild element is populated under its node identifier'
46             result.'child-object'.'grand-child-object'.grandChildLeaf == 'grandChildLeafValue'
47     }
48
49     def 'Data node structure conversion to map with root node identifier.'() {
50         when: 'data node structure is converted to a map with root node identifier'
51             def result = DataMapUtils.toDataMapWithIdentifier(dataNode,dataNode.moduleNamePrefix)
52         then: 'root node leaves are populated under its node identifier'
53             def parentNode = result.parent
54             parentNode.parentLeaf == 'parentLeafValue'
55             parentNode.parentLeafList == ['parentLeafListEntry1','parentLeafListEntry2']
56         and: 'leaves for child element is populated under its node identifier'
57             parentNode.'child-object'.childLeaf == 'childLeafValue'
58         and: 'leaves for grandchild element is populated under its node identifier'
59             parentNode.'child-object'.'grand-child-object'.grandChildLeaf == 'grandChildLeafValue'
60     }
61
62     def 'Adding prefix to data node identifier.'() {
63         when: 'a valid xPath is passed to the addPrefixToXpath method'
64             def result = new DataMapUtils().getNodeIdentifierWithPrefix(xPath,'sampleModuleName')
65         then: 'the correct modified node identifier is given'
66             assert result == expectedNodeIdentifier
67         where: 'the following parameters are used'
68             scenario                                | xPath                                     | expectedNodeIdentifier
69             'container xpath'                       | '/bookstore'                              | 'sampleModuleName:bookstore'
70             'xpath contains list attribute'         | '/bookstore/categories[@code=1]'          | 'sampleModuleName:categories'
71             'xpath contains list attributes with /' | '/bookstore/categories[@code=1/2]'        | 'sampleModuleName:categories'
72
73     }
74
75     def 'Data node structure with anchor name conversion to map with root node identifier.'() {
76         when: 'data node structure is converted to a map with root node identifier'
77             def result = DataMapUtils.toDataMapWithIdentifierAndAnchor(dataNodeWithAnchor, dataNodeWithAnchor.moduleNamePrefix)
78         then: 'root node leaves are populated under its node identifier'
79             def parentNode = result.get("dataNode").parent
80             parentNode.parentLeaf == 'parentLeafValue'
81             parentNode.parentLeafList == ['parentLeafListEntry1','parentLeafListEntry2']
82         and: 'leaves for child element is populated under its node identifier'
83             assert parentNode.'child-object'.childLeaf == 'childLeafValue'
84         and: 'leaves for grandchild element is populated under its node identifier'
85             assert parentNode.'child-object'.'grand-child-object'.grandChildLeaf == 'grandChildLeafValue'
86         and: 'data node is associated with anchor name'
87             assert result.get('anchorName') == 'anchor01'
88     }
89
90     def 'Data node without leaves and without children.'() {
91         given: 'a datanode with no leaves and no children'
92             def dataNodeWithoutData = new DataNodeBuilder().withXpath('some xpath').build()
93         when: 'it is converted to a map'
94             def result = DataMapUtils.toDataMap(dataNodeWithoutData)
95         then: 'an empty object map is returned'
96             result.isEmpty()
97     }
98
99     def dataNode = buildDataNode(
100         "/parent",[parentLeaf:'parentLeafValue', parentLeafList:['parentLeafListEntry1','parentLeafListEntry2']],[
101         buildDataNode('/parent/child-list[@id=1/2]',[listElementLeaf:'listElement1leafValue'],noChildren),
102         buildDataNode('/parent/child-list[@id=2]',[listElementLeaf:'listElement2leafValue'],noChildren),
103         buildDataNode('/parent/child-object',[childLeaf:'childLeafValue'],
104             [buildDataNode('/parent/child-object/grand-child-object',[grandChildLeaf:'grandChildLeafValue'],noChildren)]
105         ),
106     ])
107
108     def dataNodeWithAnchor = buildDataNodeWithAnchor(
109         "/parent", 'anchor01',[parentLeaf:'parentLeafValue', parentLeafList:['parentLeafListEntry1','parentLeafListEntry2']],[
110         buildDataNode('/parent/child-list[@id=1/2]',[listElementLeaf:'listElement1leafValue'],noChildren),
111         buildDataNode('/parent/child-list[@id=2]',[listElementLeaf:'listElement2leafValue'],noChildren),
112         buildDataNode('/parent/child-object',[childLeaf:'childLeafValue'],
113             [buildDataNode('/parent/child-object/grand-child-object',[grandChildLeaf:'grandChildLeafValue'],noChildren)]
114         ),
115     ])
116
117     def buildDataNode(xpath,  leaves,  children) {
118         return new DataNodeBuilder().withXpath(xpath).withLeaves(leaves).withChildDataNodes(children).build()
119     }
120
121     def buildDataNodeWithAnchor(xpath, anchorName, leaves,  children) {
122         return new DataNodeBuilder().withXpath(xpath).withAnchor(anchorName).withLeaves(leaves).withChildDataNodes(children).build()
123     }
124
125 }
126