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-2022 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 dataNode = buildDataNode(
33             "/parent",[parentLeaf:'parentLeafValue', parentLeafList:['parentLeafListEntry1','parentLeafListEntry2']],[
34             buildDataNode('/parent/child-list[@id=1/2]',[listElementLeaf:'listElement1leafValue'],noChildren),
35             buildDataNode('/parent/child-list[@id=2]',[listElementLeaf:'listElement2leafValue'],noChildren),
36             buildDataNode('/parent/child-object',[childLeaf:'childLeafValue'],
37                     [buildDataNode('/parent/child-object/grand-child-object',[grandChildLeaf:'grandChildLeafValue'],noChildren)]
38             ),
39     ])
40
41     def dataNodeWithAnchor = buildDataNodeWithAnchor(
42             "/parent", 'anchor01',[parentLeaf:'parentLeafValue', parentLeafList:['parentLeafListEntry1','parentLeafListEntry2']],[
43             buildDataNode('/parent/child-list[@id=1/2]',[listElementLeaf:'listElement1leafValue'],noChildren),
44             buildDataNode('/parent/child-list[@id=2]',[listElementLeaf:'listElement2leafValue'],noChildren),
45             buildDataNode('/parent/child-object',[childLeaf:'childLeafValue'],
46                     [buildDataNode('/parent/child-object/grand-child-object',[grandChildLeaf:'grandChildLeafValue'],noChildren)]
47             ),
48     ])
49
50     static def buildDataNode(xpath,  leaves,  children) {
51         return new DataNodeBuilder().withXpath(xpath).withLeaves(leaves).withChildDataNodes(children).build()
52     }
53
54     static def buildDataNodeWithAnchor(xpath, anchorName, leaves,  children) {
55         return new DataNodeBuilder().withXpath(xpath).withAnchor(anchorName).withLeaves(leaves).withChildDataNodes(children).build()
56     }
57
58     def 'Data node structure conversion to map.'() {
59         when: 'data node structure is converted to a map'
60             def result = DataMapUtils.toDataMap(dataNode)
61
62         then: 'root node identifier is null'
63             result.parent == null
64
65         then: 'root node leaves are top level elements'
66             result.parentLeaf == 'parentLeafValue'
67             result.parentLeafList == ['parentLeafListEntry1','parentLeafListEntry2']
68
69         and: 'leaves of child list element are listed as structures under common identifier'
70             result.'child-list'.collect().containsAll(['listElementLeaf': 'listElement1leafValue'],
71                                                       ['listElementLeaf': 'listElement2leafValue'])
72
73         and: 'leaves for child element is populated under its node identifier'
74             result.'child-object'.childLeaf == 'childLeafValue'
75
76         and: 'leaves for grandchild element is populated under its node identifier'
77             result.'child-object'.'grand-child-object'.grandChildLeaf == 'grandChildLeafValue'
78     }
79
80     def 'Data node structure conversion to map with root node identifier.'() {
81         when: 'data node structure is converted to a map with root node identifier'
82             def result = DataMapUtils.toDataMapWithIdentifier(dataNode,dataNode.moduleNamePrefix)
83         then: 'root node leaves are populated under its node identifier'
84             def parentNode = result.parent
85             parentNode.parentLeaf == 'parentLeafValue'
86             parentNode.parentLeafList == ['parentLeafListEntry1','parentLeafListEntry2']
87
88         and: 'leaves for child element is populated under its node identifier'
89             parentNode.'child-object'.childLeaf == 'childLeafValue'
90
91         and: 'leaves for grandchild element is populated under its node identifier'
92             parentNode.'child-object'.'grand-child-object'.grandChildLeaf == 'grandChildLeafValue'
93     }
94
95     def 'Adding prefix to data node identifier.'() {
96         when: 'a valid xPath is passed to the addPrefixToXpath method'
97             def result = new DataMapUtils().getNodeIdentifierWithPrefix(xPath,'sampleModuleName')
98         then: 'the correct modified node identifier is given'
99             assert result == expectedNodeIdentifier
100         where: 'the following parameters are used'
101             scenario                                | xPath                                     | expectedNodeIdentifier
102             'container xpath'                       | '/bookstore'                              | 'sampleModuleName:bookstore'
103             'xpath contains list attribute'         | '/bookstore/categories[@code=1]'          | 'sampleModuleName:categories'
104             'xpath contains list attributes with /' | '/bookstore/categories[@code=1/2]'        | 'sampleModuleName:categories'
105
106     }
107
108     def 'Data node structure with anchor name conversion to map with root node identifier.'() {
109         when: 'data node structure is converted to a map with root node identifier'
110             def result = DataMapUtils.toDataMapWithIdentifierAndAnchor(dataNodeWithAnchor, dataNodeWithAnchor.moduleNamePrefix)
111         then: 'root node leaves are populated under its node identifier'
112             def parentNode = result.get("dataNode").parent
113             parentNode.parentLeaf == 'parentLeafValue'
114             parentNode.parentLeafList == ['parentLeafListEntry1','parentLeafListEntry2']
115
116         and: 'leaves for child element is populated under its node identifier'
117             assert parentNode.'child-object'.childLeaf == 'childLeafValue'
118
119         and: 'leaves for grandchild element is populated under its node identifier'
120             assert parentNode.'child-object'.'grand-child-object'.grandChildLeaf == 'grandChildLeafValue'
121
122         and: 'data node is associated with anchor name'
123             assert result.get('anchorName') == 'anchor01'
124     }
125 }
126