0c8b2227d050fe0b436084a2cc0f3c4e498f0ca5
[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-2022 Nordix Foundation
6  *  Modification Copyright (C) 2021 Bell Canada.
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.ncmp.rest.controller
24
25 import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.PATCH
26 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete
27 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
28 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch
29 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
30 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put
31 import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.CREATE
32 import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.UPDATE
33 import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.DELETE
34
35 import com.fasterxml.jackson.databind.ObjectMapper
36 import org.modelmapper.ModelMapper
37 import org.onap.cps.TestUtils
38 import org.onap.cps.spi.model.ModuleReference
39 import org.onap.cps.utils.JsonObjectMapper
40 import org.onap.cps.ncmp.api.NetworkCmProxyDataService
41 import org.spockframework.spring.SpringBean
42 import org.springframework.beans.factory.annotation.Autowired
43 import org.springframework.beans.factory.annotation.Value
44 import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
45 import org.springframework.http.HttpStatus
46 import org.springframework.http.MediaType
47 import org.springframework.test.web.servlet.MockMvc
48 import spock.lang.Specification
49
50 @WebMvcTest(NetworkCmProxyController)
51 class NetworkCmProxyControllerSpec extends Specification {
52
53     @Autowired
54     MockMvc mvc
55
56     @SpringBean
57     NetworkCmProxyDataService mockNetworkCmProxyDataService = Mock()
58
59     @SpringBean
60     ModelMapper modelMapper = new ModelMapper()
61
62     @SpringBean
63     JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
64
65     @Value('${rest.api.ncmp-base-path}/v1')
66     def ncmpBasePathV1
67
68     def requestBody = '{"some-key":"some-value"}'
69
70     def 'Get Resource Data from pass-through operational.' () {
71         given: 'resource data url'
72             def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-operational" +
73                     "?resourceIdentifier=parent/child&options=(a=1,b=2)"
74         when: 'get data resource request is performed'
75             def response = mvc.perform(
76                     get(getUrl)
77                             .contentType(MediaType.APPLICATION_JSON)
78                     .accept(MediaType.APPLICATION_JSON_VALUE)
79             ).andReturn().response
80         then: 'the NCMP data service is called with getResourceDataOperationalForCmHandle'
81             1 * mockNetworkCmProxyDataService.getResourceDataOperationalForCmHandle('testCmHandle',
82                     'parent/child',
83                     'application/json',
84                     '(a=1,b=2)')
85         and: 'response status is Ok'
86             response.status == HttpStatus.OK.value()
87     }
88
89     def 'Get Resource Data from pass-through running with #scenario value in resource identifier param.' () {
90         given: 'resource data url'
91             def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running" +
92                     "?resourceIdentifier=" + resourceIdentifier + "&options=(a=1,b=2)"
93         and: 'ncmp service returns json object'
94             mockNetworkCmProxyDataService.getResourceDataPassThroughRunningForCmHandle('testCmHandle',
95                     resourceIdentifier,
96                     'application/json',
97                     '(a=1,b=2)') >> '{valid-json}'
98         when: 'get data resource request is performed'
99             def response = mvc.perform(
100                     get(getUrl)
101                             .contentType(MediaType.APPLICATION_JSON)
102                             .accept(MediaType.APPLICATION_JSON_VALUE)
103             ).andReturn().response
104         then: 'response status is Ok'
105             response.status == HttpStatus.OK.value()
106         and: 'response contains valid object body'
107             response.getContentAsString() == '{valid-json}'
108         where: 'tokens are used in the resource identifier parameter'
109             scenario                       | resourceIdentifier
110             '/'                            | 'id/with/slashes'
111             '?'                            | 'idWith?'
112             ','                            | 'idWith,'
113             '='                            | 'idWith='
114             '[]'                           | 'idWith[]'
115             '? needs to be encoded as %3F' | 'idWith%3F'
116     }
117
118     def 'Update resource data from pass-through running.' () {
119         given: 'update resource data url'
120             def updateUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running" +
121                 "?resourceIdentifier=parent/child"
122         when: 'update data resource request is performed'
123             def response = mvc.perform(
124                 put(updateUrl)
125                     .contentType(MediaType.APPLICATION_JSON_VALUE)
126                     .accept(MediaType.APPLICATION_JSON_VALUE).content(requestBody)
127             ).andReturn().response
128         then: 'ncmp service method to update resource is called'
129             1 * mockNetworkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle('testCmHandle',
130                 'parent/child', UPDATE, requestBody, 'application/json;charset=UTF-8')
131         and: 'the response status is OK'
132             response.status == HttpStatus.OK.value()
133     }
134
135     def 'Create Resource Data from pass-through running with #scenario.' () {
136         given: 'resource data url'
137             def url = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running" +
138                     "?resourceIdentifier=parent/child"
139             def requestBody = '{"some-key":"some-value"}'
140         when: 'create resource request is performed'
141             def response = mvc.perform(
142                     post(url)
143                             .contentType(MediaType.APPLICATION_JSON_VALUE)
144                             .accept(MediaType.APPLICATION_JSON_VALUE).content(requestBody)
145             ).andReturn().response
146         then: 'ncmp service method to create resource called'
147             1 * mockNetworkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle('testCmHandle',
148                 'parent/child', CREATE, requestBody, 'application/json;charset=UTF-8')
149         and: 'resource is created'
150             response.status == HttpStatus.CREATED.value()
151     }
152
153     def 'Get module references for the given dataspace and cm handle.' () {
154         given: 'get module references url'
155             def getUrl = "$ncmpBasePathV1/ch/some-cmhandle/modules"
156         when: 'get module resource request is performed'
157             def response =mvc.perform(get(getUrl)).andReturn().response
158         then: 'ncmp service method to get yang resource module references is called'
159             mockNetworkCmProxyDataService.getYangResourcesModuleReferences('some-cmhandle')
160                     >> [new ModuleReference(moduleName: 'some-name1',revision: '2021-10-03')]
161         and: 'response contains an array with the module name and revision'
162             response.getContentAsString() == '[{"moduleName":"some-name1","revision":"2021-10-03"}]'
163         and: 'response returns an OK http code'
164             response.status == HttpStatus.OK.value()
165     }
166
167     def 'Retrieve cm handles.'() {
168         given: 'an endpoint and json data'
169             def searchesEndpoint = "$ncmpBasePathV1/ch/searches"
170             String jsonString = TestUtils.getResourceFileContent('cmhandle-search.json')
171         and: 'the service method is invoked with module names and returns two cm handle ids'
172             mockNetworkCmProxyDataService.executeCmHandleHasAllModulesSearch(['module1', 'module2']) >> ['some-cmhandle-id1', 'some-cmhandle-id2']
173         when: 'the searches api is invoked'
174             def response = mvc.perform(post(searchesEndpoint)
175                     .contentType(MediaType.APPLICATION_JSON)
176                     .content(jsonString)).andReturn().response
177         then: 'response status returns OK'
178             response.status == HttpStatus.OK.value()
179         and: 'the expected response content is returned'
180             response.contentAsString == '{"cmHandles":[{"cmHandleId":"some-cmhandle-id1"},{"cmHandleId":"some-cmhandle-id2"}]}'
181     }
182
183     def 'Call execute cm handle searches with unrecognized condition name.'() {
184         given: 'an endpoint and json data'
185             def searchesEndpoint = "$ncmpBasePathV1/ch/searches"
186             String jsonString = TestUtils.getResourceFileContent('invalid-cmhandle-search.json')
187         when: 'the searches api is invoked'
188             def response = mvc.perform(post(searchesEndpoint)
189                     .contentType(MediaType.APPLICATION_JSON)
190                     .content(jsonString)).andReturn().response
191         then: 'an empty cm handle identifier is returned'
192             response.contentAsString == '{"cmHandles":[]}'
193     }
194
195     def 'Patch resource data in pass-through running datastore.' () {
196         given: 'patch resource data url'
197             def url = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running" +
198                     "?resourceIdentifier=parent/child"
199         when: 'patch data resource request is performed'
200             def response = mvc.perform(
201                     patch(url)
202                             .contentType(MediaType.APPLICATION_JSON)
203                             .accept(MediaType.APPLICATION_JSON).content(requestBody)
204             ).andReturn().response
205         then: 'ncmp service method to update resource is called'
206             1 * mockNetworkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle('testCmHandle',
207                     'parent/child', PATCH, requestBody, 'application/json;charset=UTF-8')
208         and: 'the response status is OK'
209             response.status == HttpStatus.OK.value()
210     }
211
212     def 'Delete resource data in pass-through running datastore.' () {
213         given: 'delete resource data url'
214             def url = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running" +
215                      "?resourceIdentifier=parent/child"
216         when: 'delete data resource request is performed'
217             def response = mvc.perform(
218                 delete(url).contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)).andReturn().response
219         then: 'the ncmp service method to delete resource is called (with null as body)'
220             1 * mockNetworkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle('testCmHandle',
221                 'parent/child', DELETE, null, 'application/json;charset=UTF-8')
222         and: 'the response is No Content'
223             response.status == HttpStatus.NO_CONTENT.value()
224     }
225 }
226