Merge "Increase minimum coverage"
[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 import spock.lang.Unroll
34
35 class CpsDataServiceImplSpec extends Specification {
36     def mockCpsDataPersistenceService = Mock(CpsDataPersistenceService)
37     def mockCpsAdminService = Mock(CpsAdminService)
38     def mockCpsModuleService = Mock(CpsModuleService)
39     def mockYangTextSchemaSourceSetCache = Mock(YangTextSchemaSourceSetCache)
40
41     def objectUnderTest = new CpsDataServiceImpl()
42
43     def setup() {
44         objectUnderTest.cpsDataPersistenceService = mockCpsDataPersistenceService
45         objectUnderTest.cpsAdminService = mockCpsAdminService
46         objectUnderTest.cpsModuleService = mockCpsModuleService
47         objectUnderTest.yangTextSchemaSourceSetCache = mockYangTextSchemaSourceSetCache
48     }
49
50     def dataspaceName = 'some dataspace'
51     def anchorName = 'some anchor'
52     def schemaSetName = 'some schema set'
53
54     def 'Saving json data.'() {
55         given: 'that the admin service will return an anchor'
56             def anchor = Anchor.builder().name(anchorName).schemaSetName(schemaSetName).build()
57             mockCpsAdminService.getAnchor(dataspaceName, anchorName) >> anchor
58         and: 'the schema source set cache returns a schema source set'
59             def mockYangTextSchemaSourceSet = Mock(YangTextSchemaSourceSet)
60             mockYangTextSchemaSourceSetCache.get(dataspaceName, schemaSetName) >> mockYangTextSchemaSourceSet
61         and: 'the schema source sets returns the test-tree schema context'
62             def yangResourceNameToContent = TestUtils.getYangResourcesAsMap('test-tree.yang')
63             def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourceNameToContent).getSchemaContext()
64             mockYangTextSchemaSourceSet.getSchemaContext() >> schemaContext
65         when: 'save data method is invoked with test-tree json data'
66             def jsonData = TestUtils.getResourceFileContent('test-tree.json')
67             objectUnderTest.saveData(dataspaceName, anchorName, jsonData)
68         then: 'the persistence service method is invoked with correct parameters'
69             1 * mockCpsDataPersistenceService.storeDataNode(dataspaceName, anchorName,
70                     { dataNode -> dataNode.xpath == '/test-tree' })
71     }
72
73     def 'Saving child data fragment under existing node.'() {
74         given: 'that the admin service will return an anchor'
75             def anchor = Anchor.builder().name(anchorName).schemaSetName(schemaSetName).build()
76             mockCpsAdminService.getAnchor(dataspaceName, anchorName) >> anchor
77         and: 'the schema source set cache returns a schema source set'
78             def mockYangTextSchemaSourceSet = Mock(YangTextSchemaSourceSet)
79             mockYangTextSchemaSourceSetCache.get(dataspaceName, schemaSetName) >> mockYangTextSchemaSourceSet
80         and: 'the schema source sets returns the test-tree schema context'
81             def yangResourceNameToContent = TestUtils.getYangResourcesAsMap('test-tree.yang')
82             def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourceNameToContent).getSchemaContext()
83             mockYangTextSchemaSourceSet.getSchemaContext() >> schemaContext
84         when: 'save data method is invoked with test-tree json data'
85             def jsonData = '{"branch": [{"name": "New"}]}'
86             objectUnderTest.saveData(dataspaceName, anchorName, '/test-tree',jsonData)
87         then: 'the persistence service method is invoked with correct parameters'
88             1 * mockCpsDataPersistenceService.addChildDataNode(dataspaceName, anchorName,'/test-tree',
89                     { dataNode -> dataNode.xpath == '/test-tree/branch[@name=\'New\']' })
90     }
91
92     @Unroll
93     def 'Get data node with option #fetchDescendantsOption.'() {
94         def xpath = '/xpath'
95         def dataNode = new DataNodeBuilder().withXpath(xpath).build()
96         given: 'persistence service returns data for get data request'
97             mockCpsDataPersistenceService.getDataNode(dataspaceName, anchorName, xpath, fetchDescendantsOption) >> dataNode
98         expect: 'service returns same data if uses same parameters'
99             objectUnderTest.getDataNode(dataspaceName, anchorName, xpath, fetchDescendantsOption) == dataNode
100         where: 'all fetch options are supported'
101             fetchDescendantsOption << FetchDescendantsOption.values()
102     }
103
104     @Unroll
105     def 'Update data node leaves: #scenario.'() {
106         given: 'that the admin service will return an anchor'
107             def anchor = Anchor.builder().name(anchorName).schemaSetName(schemaSetName).build()
108             mockCpsAdminService.getAnchor(dataspaceName, anchorName) >> anchor
109         and: 'the schema source set cache returns a schema source set'
110             def mockYangTextSchemaSourceSet = Mock(YangTextSchemaSourceSet)
111             mockYangTextSchemaSourceSetCache.get(dataspaceName, schemaSetName) >> mockYangTextSchemaSourceSet
112         and: 'the schema source sets returns the test-tree schema context'
113             def yangResourceNameToContent = TestUtils.getYangResourcesAsMap('test-tree.yang')
114             def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourceNameToContent).getSchemaContext()
115             mockYangTextSchemaSourceSet.getSchemaContext() >> schemaContext
116         when: 'update data method is invoked with json data #jsonData and parent node xpath #parentNodeXpath'
117             objectUnderTest.updateNodeLeaves(dataspaceName, anchorName, parentNodeXpath, jsonData)
118         then: 'the persistence service method is invoked with correct parameters'
119             1 * mockCpsDataPersistenceService.updateDataLeaves(dataspaceName, anchorName, nodeXpath, leaves)
120         where: 'following parameters were used'
121             scenario         | parentNodeXpath | jsonData                         | nodeXpath                           | leaves
122             'top level node' | '/'             | '{ "test-tree": {"branch": []}}' | '/test-tree'                        | Collections.emptyMap()
123             'level 2 node'   | '/test-tree'    | '{"branch": [{"name":"Name"}]}'  | '/test-tree/branch[@name=\'Name\']' | ['name': 'Name']
124     }
125
126     @Unroll
127     def 'Replace data node: #scenario.'() {
128         given: 'that the admin service will return an anchor'
129             def anchor = Anchor.builder().name(anchorName).schemaSetName(schemaSetName).build()
130             mockCpsAdminService.getAnchor(dataspaceName, anchorName) >> anchor
131         and: 'the schema source set cache returns a schema source set'
132             def mockYangTextSchemaSourceSet = Mock(YangTextSchemaSourceSet)
133             mockYangTextSchemaSourceSetCache.get(dataspaceName, schemaSetName) >> mockYangTextSchemaSourceSet
134         and: 'the schema source sets returns the test-tree schema context'
135             def yangResourceNameToContent = TestUtils.getYangResourcesAsMap('test-tree.yang')
136             def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourceNameToContent).getSchemaContext()
137             mockYangTextSchemaSourceSet.getSchemaContext() >> schemaContext
138         when: 'replace data method is invoked with json data #jsonData and parent node xpath #parentNodeXpath'
139             objectUnderTest.replaceNodeTree(dataspaceName, anchorName, parentNodeXpath, jsonData)
140         then: 'the persistence service method is invoked with correct parameters'
141             1 * mockCpsDataPersistenceService.replaceDataNodeTree(dataspaceName, anchorName,
142                     { dataNode -> dataNode.xpath == nodeXpath })
143         where: 'following parameters were used'
144             scenario         | parentNodeXpath | jsonData                         | nodeXpath
145             'top level node' | '/'             | '{ "test-tree": {"branch": []}}' | '/test-tree'
146             'level 2 node'   | '/test-tree'    | '{"branch": [{"name":"Name"}]}'  | '/test-tree/branch[@name=\'Name\']'
147     }
148 }