Create child data node (part 2): NCMP service + REST
[cps.git] / cps-ncmp-rest / src / test / groovy / org / onap / cps / ncmp / rest / controller / NetworkCmProxyControllerSpec.groovy
1 /*
2  *  ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 Pantheon.tech
4  *  Modification Copyright (C) 2021 highstreet technologies GmbH
5  *  Modification Copyright (C) 2021 Nordix Foundation
6  *  ================================================================================
7  *  Licensed under the Apache License, Version 2.0 (the "License");
8  *  you may not use this file except in compliance with the License.
9  *  You may obtain a copy of the License at
10  *
11  *        http://www.apache.org/licenses/LICENSE-2.0
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License.
17  *
18  *  SPDX-License-Identifier: Apache-2.0
19  *  ============LICENSE_END=========================================================
20  */
21
22 package org.onap.cps.ncmp.rest.controller
23
24 import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
25 import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS
26 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
27 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch
28 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
29 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put
30
31 import com.google.gson.Gson
32 import org.onap.cps.ncmp.api.NetworkCmProxyDataService
33 import org.onap.cps.spi.model.DataNodeBuilder
34 import org.spockframework.spring.SpringBean
35 import org.springframework.beans.factory.annotation.Autowired
36 import org.springframework.beans.factory.annotation.Value
37 import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
38 import org.springframework.http.HttpStatus
39 import org.springframework.http.MediaType
40 import org.springframework.test.web.servlet.MockMvc
41 import spock.lang.Specification
42 import spock.lang.Unroll
43
44 @WebMvcTest
45 class NetworkCmProxyControllerSpec extends Specification {
46
47     @Autowired
48     MockMvc mvc
49
50     @SpringBean
51     NetworkCmProxyDataService mockNetworkCmProxyDataService = Mock()
52
53     @Value('${rest.api.ncmp-base-path}')
54     def basePath
55
56     def dataNodeBaseEndpoint
57
58     def setup() {
59         dataNodeBaseEndpoint = "$basePath/v1"
60     }
61
62     def cmHandle = 'some handle'
63     def xpath = 'some xpath'
64
65     @Unroll
66     def 'Query data node by cps path for the given cm handle with #scenario.'() {
67         given: 'service method returns a list containing a data node'
68             def dataNode = new DataNodeBuilder().withXpath('/xpath').build()
69             def cpsPath = 'some cps-path'
70             mockNetworkCmProxyDataService.queryDataNodes(cmHandle, cpsPath, expectedCpsDataServiceOption) >> [dataNode]
71         and: 'the query endpoint'
72             def dataNodeEndpoint = "$dataNodeBaseEndpoint/cm-handles/$cmHandle/nodes/query"
73         when: 'query data nodes API is invoked'
74             def response = mvc.perform(get(dataNodeEndpoint)
75                     .param('cps-path', cpsPath)
76                     .param('include-descendants', includeDescendantsOption))
77                     .andReturn().response
78         then: 'the response contains the the datanode in json format'
79             response.status == HttpStatus.OK.value()
80             def expectedJsonContent = new Gson().toJson(dataNode)
81             response.getContentAsString().contains(expectedJsonContent)
82         where: 'the following options for include descendants are provided in the request'
83             scenario                    | includeDescendantsOption || expectedCpsDataServiceOption
84             'no descendants by default' | ''                       || OMIT_DESCENDANTS
85             'no descendant explicitly'  | 'false'                  || OMIT_DESCENDANTS
86             'descendants'               | 'true'                   || INCLUDE_ALL_DESCENDANTS
87     }
88
89     @Unroll
90     def 'Create data node: #scenario.'() {
91         given: 'json data'
92             def jsonData = 'json data'
93         when: 'post request is performed'
94             def response = mvc.perform(
95                     post("$dataNodeBaseEndpoint/cm-handles/$cmHandle/nodes")
96                             .contentType(MediaType.APPLICATION_JSON)
97                             .content(jsonData)
98                             .param('xpath', reqXpath)
99             ).andReturn().response
100         then: 'the service method is invoked once with expected parameters'
101             1 * mockNetworkCmProxyDataService.createDataNode(cmHandle, usedXpath, jsonData)
102         and: 'response status indicates success'
103             response.status == HttpStatus.CREATED.value()
104         where: 'following parameters were used'
105             scenario             | reqXpath || usedXpath
106             'no xpath parameter' | ''       || '/'
107             'root xpath'         | '/'      || '/'
108             'parent node xpath'  | '/xpath' || '/xpath'
109     }
110
111     def 'Update data node leaves.'() {
112         given: 'json data'
113             def jsonData = 'json data'
114         and: 'the query endpoint'
115             def endpoint = "$dataNodeBaseEndpoint/cm-handles/$cmHandle/nodes"
116         when: 'patch request is performed'
117             def response = mvc.perform(
118                     patch(endpoint)
119                             .contentType(MediaType.APPLICATION_JSON)
120                             .content(jsonData)
121                             .param('xpath', xpath)
122             ).andReturn().response
123         then: 'the service method is invoked once with expected parameters'
124             1 * mockNetworkCmProxyDataService.updateNodeLeaves(cmHandle, xpath, jsonData)
125         and: 'response status indicates success'
126             response.status == HttpStatus.OK.value()
127     }
128
129     def 'Replace data node tree.'() {
130         given: 'json data'
131             def jsonData = 'json data'
132         and: 'the query endpoint'
133             def endpoint = "$dataNodeBaseEndpoint/cm-handles/$cmHandle/nodes"
134         when: 'put request is performed'
135             def response = mvc.perform(
136                     put(endpoint)
137                             .contentType(MediaType.APPLICATION_JSON)
138                             .content(jsonData)
139                             .param('xpath', xpath)
140             ).andReturn().response
141         then: 'the service method is invoked once with expected parameters'
142             1 * mockNetworkCmProxyDataService.replaceNodeTree(cmHandle, xpath, jsonData)
143         and: 'response status indicates success'
144             response.status == HttpStatus.OK.value()
145     }
146
147     def 'Get data node.'() {
148         given: 'the service returns a data node'
149             def xpath = 'some xpath'
150             def dataNode = new DataNodeBuilder().withXpath(xpath).withLeaves(["leaf": "value"]).build()
151             mockNetworkCmProxyDataService.getDataNode(cmHandle, xpath, OMIT_DESCENDANTS) >> dataNode
152         and: 'the query endpoint'
153             def endpoint = "$dataNodeBaseEndpoint/cm-handles/$cmHandle/node"
154         when: 'get request is performed through REST API'
155             def response = mvc.perform(get(endpoint).param('xpath', xpath)).andReturn().response
156         then: 'a success response is returned'
157             response.status == HttpStatus.OK.value()
158         and: 'response contains expected leaf and value'
159             response.contentAsString.contains('"leaf":"value"')
160     }
161 }
162