Investigate and update Spock version
[cps.git] / cps-service / src / test / groovy / org / onap / cps / api / impl / CpsDataServiceImplSpec.groovy
1 /*
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 Nordix Foundation
4  *  Modifications Copyright (C) 2021 Pantheon.tech
5  *  ================================================================================
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *  SPDX-License-Identifier: Apache-2.0
18  *  ============LICENSE_END=========================================================
19  */
20
21 package org.onap.cps.api.impl
22
23 import org.onap.cps.TestUtils
24 import org.onap.cps.api.CpsAdminService
25 import org.onap.cps.api.CpsModuleService
26 import org.onap.cps.spi.CpsDataPersistenceService
27 import org.onap.cps.spi.FetchDescendantsOption
28 import org.onap.cps.spi.model.Anchor
29 import org.onap.cps.spi.model.DataNodeBuilder
30 import org.onap.cps.yang.YangTextSchemaSourceSet
31 import org.onap.cps.yang.YangTextSchemaSourceSetBuilder
32 import spock.lang.Specification
33
34 class CpsDataServiceImplSpec extends Specification {
35     def mockCpsDataPersistenceService = Mock(CpsDataPersistenceService)
36     def mockCpsAdminService = Mock(CpsAdminService)
37     def mockCpsModuleService = Mock(CpsModuleService)
38     def mockYangTextSchemaSourceSetCache = Mock(YangTextSchemaSourceSetCache)
39
40     def objectUnderTest = new CpsDataServiceImpl()
41
42     def setup() {
43         objectUnderTest.cpsDataPersistenceService = mockCpsDataPersistenceService
44         objectUnderTest.cpsAdminService = mockCpsAdminService
45         objectUnderTest.cpsModuleService = mockCpsModuleService
46         objectUnderTest.yangTextSchemaSourceSetCache = mockYangTextSchemaSourceSetCache
47     }
48
49     def dataspaceName = 'some dataspace'
50     def anchorName = 'some anchor'
51     def schemaSetName = 'some schema set'
52
53     def 'Saving json data.'() {
54         given: 'that the admin service will return an anchor'
55             def anchor = Anchor.builder().name(anchorName).schemaSetName(schemaSetName).build()
56             mockCpsAdminService.getAnchor(dataspaceName, anchorName) >> anchor
57         and: 'the schema source set cache returns a schema source set'
58             def mockYangTextSchemaSourceSet = Mock(YangTextSchemaSourceSet)
59             mockYangTextSchemaSourceSetCache.get(dataspaceName, schemaSetName) >> mockYangTextSchemaSourceSet
60         and: 'the schema source sets returns the test-tree schema context'
61             def yangResourceNameToContent = TestUtils.getYangResourcesAsMap('test-tree.yang')
62             def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourceNameToContent).getSchemaContext()
63             mockYangTextSchemaSourceSet.getSchemaContext() >> schemaContext
64         when: 'save data method is invoked with test-tree json data'
65             def jsonData = TestUtils.getResourceFileContent('test-tree.json')
66             objectUnderTest.saveData(dataspaceName, anchorName, jsonData)
67         then: 'the persistence service method is invoked with correct parameters'
68             1 * mockCpsDataPersistenceService.storeDataNode(dataspaceName, anchorName,
69                     { dataNode -> dataNode.xpath == '/test-tree' })
70     }
71
72     def 'Saving child data fragment under existing node.'() {
73         given: 'that the admin service will return an anchor'
74             def anchor = Anchor.builder().name(anchorName).schemaSetName(schemaSetName).build()
75             mockCpsAdminService.getAnchor(dataspaceName, anchorName) >> anchor
76         and: 'the schema source set cache returns a schema source set'
77             def mockYangTextSchemaSourceSet = Mock(YangTextSchemaSourceSet)
78             mockYangTextSchemaSourceSetCache.get(dataspaceName, schemaSetName) >> mockYangTextSchemaSourceSet
79         and: 'the schema source sets returns the test-tree schema context'
80             def yangResourceNameToContent = TestUtils.getYangResourcesAsMap('test-tree.yang')
81             def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourceNameToContent).getSchemaContext()
82             mockYangTextSchemaSourceSet.getSchemaContext() >> schemaContext
83         when: 'save data method is invoked with test-tree json data'
84             def jsonData = '{"branch": [{"name": "New"}]}'
85             objectUnderTest.saveData(dataspaceName, anchorName, '/test-tree',jsonData)
86         then: 'the persistence service method is invoked with correct parameters'
87             1 * mockCpsDataPersistenceService.addChildDataNode(dataspaceName, anchorName,'/test-tree',
88                     { dataNode -> dataNode.xpath == '/test-tree/branch[@name=\'New\']' })
89     }
90
91     def 'Get data node with option #fetchDescendantsOption.'() {
92         def xpath = '/xpath'
93         def dataNode = new DataNodeBuilder().withXpath(xpath).build()
94         given: 'persistence service returns data for get data request'
95             mockCpsDataPersistenceService.getDataNode(dataspaceName, anchorName, xpath, fetchDescendantsOption) >> dataNode
96         expect: 'service returns same data if uses same parameters'
97             objectUnderTest.getDataNode(dataspaceName, anchorName, xpath, fetchDescendantsOption) == dataNode
98         where: 'all fetch options are supported'
99             fetchDescendantsOption << FetchDescendantsOption.values()
100     }
101
102     def 'Update data node leaves: #scenario.'() {
103         given: 'that the admin service will return an anchor'
104             def anchor = Anchor.builder().name(anchorName).schemaSetName(schemaSetName).build()
105             mockCpsAdminService.getAnchor(dataspaceName, anchorName) >> anchor
106         and: 'the schema source set cache returns a schema source set'
107             def mockYangTextSchemaSourceSet = Mock(YangTextSchemaSourceSet)
108             mockYangTextSchemaSourceSetCache.get(dataspaceName, schemaSetName) >> mockYangTextSchemaSourceSet
109         and: 'the schema source sets returns the test-tree schema context'
110             def yangResourceNameToContent = TestUtils.getYangResourcesAsMap('test-tree.yang')
111             def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourceNameToContent).getSchemaContext()
112             mockYangTextSchemaSourceSet.getSchemaContext() >> schemaContext
113         when: 'update data method is invoked with json data #jsonData and parent node xpath #parentNodeXpath'
114             objectUnderTest.updateNodeLeaves(dataspaceName, anchorName, parentNodeXpath, jsonData)
115         then: 'the persistence service method is invoked with correct parameters'
116             1 * mockCpsDataPersistenceService.updateDataLeaves(dataspaceName, anchorName, nodeXpath, leaves)
117         where: 'following parameters were used'
118             scenario         | parentNodeXpath | jsonData                         | nodeXpath                           | leaves
119             'top level node' | '/'             | '{ "test-tree": {"branch": []}}' | '/test-tree'                        | Collections.emptyMap()
120             'level 2 node'   | '/test-tree'    | '{"branch": [{"name":"Name"}]}'  | '/test-tree/branch[@name=\'Name\']' | ['name': 'Name']
121     }
122
123     def 'Replace data node: #scenario.'() {
124         given: 'that the admin service will return an anchor'
125             def anchor = Anchor.builder().name(anchorName).schemaSetName(schemaSetName).build()
126             mockCpsAdminService.getAnchor(dataspaceName, anchorName) >> anchor
127         and: 'the schema source set cache returns a schema source set'
128             def mockYangTextSchemaSourceSet = Mock(YangTextSchemaSourceSet)
129             mockYangTextSchemaSourceSetCache.get(dataspaceName, schemaSetName) >> mockYangTextSchemaSourceSet
130         and: 'the schema source sets returns the test-tree schema context'
131             def yangResourceNameToContent = TestUtils.getYangResourcesAsMap('test-tree.yang')
132             def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourceNameToContent).getSchemaContext()
133             mockYangTextSchemaSourceSet.getSchemaContext() >> schemaContext
134         when: 'replace data method is invoked with json data #jsonData and parent node xpath #parentNodeXpath'
135             objectUnderTest.replaceNodeTree(dataspaceName, anchorName, parentNodeXpath, jsonData)
136         then: 'the persistence service method is invoked with correct parameters'
137             1 * mockCpsDataPersistenceService.replaceDataNodeTree(dataspaceName, anchorName,
138                     { dataNode -> dataNode.xpath == nodeXpath })
139         where: 'following parameters were used'
140             scenario         | parentNodeXpath | jsonData                         | nodeXpath
141             'top level node' | '/'             | '{ "test-tree": {"branch": []}}' | '/test-tree'
142             'level 2 node'   | '/test-tree'    | '{"branch": [{"name":"Name"}]}'  | '/test-tree/branch[@name=\'Name\']'
143     }
144 }