Merge "Address Sonar Qube issues"
[cps.git] / cps-ncmp-service / src / test / groovy / org / onap / cps / ncmp / api / impl / NetworkCmProxyDataServiceImplSpec.groovy
1 /*
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 Nordix Foundation
4  *  Modifications Copyright (C) 2021 Pantheon.tech
5  *  Modifications Copyright (C) 2021 Bell Canada
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  *
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.api.impl
24
25 import com.fasterxml.jackson.core.JsonProcessingException
26 import com.fasterxml.jackson.databind.ObjectMapper
27 import org.onap.cps.api.CpsAdminService
28 import org.onap.cps.api.CpsDataService
29 import org.onap.cps.api.CpsModuleService
30 import org.onap.cps.api.CpsQueryService
31 import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration
32 import org.onap.cps.ncmp.api.impl.exception.NcmpException
33 import org.onap.cps.ncmp.api.impl.operation.DmiOperations
34 import org.onap.cps.ncmp.api.models.CmHandle
35 import org.onap.cps.ncmp.api.models.DmiPluginRegistration
36 import org.onap.cps.ncmp.api.models.PersistenceCmHandle
37 import org.onap.cps.ncmp.utils.TestUtils
38 import org.onap.cps.spi.FetchDescendantsOption
39 import org.onap.cps.spi.exceptions.DataNodeNotFoundException
40 import org.onap.cps.spi.exceptions.DataValidationException
41 import org.onap.cps.spi.model.DataNode
42 import org.onap.cps.spi.model.ModuleReference
43 import org.springframework.http.HttpStatus
44 import org.springframework.http.ResponseEntity
45 import spock.lang.Shared
46 import spock.lang.Specification
47
48 class NetworkCmProxyDataServiceImplSpec extends Specification {
49
50     @Shared
51     def persistenceCmHandle = new CmHandle()
52     @Shared
53     def cmHandlesArray = ['cmHandle001']
54
55     def mockCpsDataService = Mock(CpsDataService)
56     def mockCpsQueryService = Mock(CpsQueryService)
57     def mockDmiOperations = Mock(DmiOperations)
58     def mockCpsModuleService = Mock(CpsModuleService)
59     def mockCpsAdminService = Mock(CpsAdminService)
60     def mockDmiProperties = Mock(NcmpConfiguration.DmiProperties)
61     def spyObjectMapper = Spy(ObjectMapper)
62
63     def objectUnderTest = new NetworkCmProxyDataServiceImpl(mockDmiOperations, mockCpsModuleService,
64             mockCpsDataService, mockCpsQueryService, mockCpsAdminService, spyObjectMapper)
65
66     def cmHandle = 'some handle'
67     def noTimestamp = null
68     def cmHandleXPath = "/dmi-registry/cm-handles[@id='testCmHandle']"
69     def cmHandleForModelSync = new PersistenceCmHandle(id:'some cm handle', dmiServiceName: 'some service name')
70     def expectedDataspaceName = 'NFP-Operational'
71
72
73     def 'Get data node.'() {
74         when: 'queryDataNodes is invoked'
75             objectUnderTest.getDataNode(cmHandle, 'some xpath', fetchDescendantsOption)
76         then: 'the persistence data service is called once with the correct parameters'
77             1 * mockCpsDataService.getDataNode(expectedDataspaceName, cmHandle, 'some xpath', fetchDescendantsOption)
78         where: 'all fetch descendants options are supported'
79             fetchDescendantsOption << FetchDescendantsOption.values()
80     }
81
82     def 'Query data nodes by cps path with #fetchDescendantsOption.'() {
83         given: 'a cm Handle and a cps path'
84             def cpsPath = '/cps-path'
85         when: 'queryDataNodes is invoked'
86             objectUnderTest.queryDataNodes(cmHandle, cpsPath, fetchDescendantsOption)
87         then: 'the persistence query service is called once with the correct parameters'
88             1 * mockCpsQueryService.queryDataNodes(expectedDataspaceName, cmHandle, cpsPath, fetchDescendantsOption)
89         where: 'all fetch descendants options are supported'
90             fetchDescendantsOption << FetchDescendantsOption.values()
91     }
92
93     def 'Create full data node: #scenario.'() {
94         given: 'a cm handle and root xpath'
95             def jsonData = 'some json'
96         when: 'createDataNode is invoked'
97             objectUnderTest.createDataNode(cmHandle, xpath, jsonData)
98         then: 'the CPS service method is invoked once with the expected parameters'
99             1 * mockCpsDataService.saveData(expectedDataspaceName, cmHandle, jsonData, noTimestamp)
100         where: 'following parameters were used'
101             scenario           | xpath
102             'no xpath'         | ''
103             'root level xpath' | '/'
104     }
105
106     def 'Create child data node.'() {
107         given: 'a cm handle and parent node xpath'
108             def jsonData = 'some json'
109             def xpath = '/test-node'
110         when: 'createDataNode is invoked'
111             objectUnderTest.createDataNode(cmHandle, xpath, jsonData)
112         then: 'the CPS service method is invoked once with the expected parameters'
113             1 * mockCpsDataService.saveData(expectedDataspaceName, cmHandle, xpath, jsonData, noTimestamp)
114     }
115
116     def 'Add list-node elements.'() {
117         given: 'a cm handle and parent node xpath'
118             def jsonData = 'some json'
119             def xpath = '/test-node'
120         when: 'addListNodeElements is invoked'
121             objectUnderTest.addListNodeElements(cmHandle, xpath, jsonData)
122         then: 'the CPS service method is invoked once with the expected parameters'
123             1 * mockCpsDataService.saveListNodeData(expectedDataspaceName, cmHandle, xpath, jsonData, noTimestamp)
124     }
125
126     def 'Update data node leaves.'() {
127         given: 'a cm Handle and a cps path'
128             def xpath = '/xpath'
129             def jsonData = 'some json'
130         when: 'updateNodeLeaves is invoked'
131             objectUnderTest.updateNodeLeaves(cmHandle, xpath, jsonData)
132         then: 'the persistence service is called once with the correct parameters'
133             1 * mockCpsDataService.updateNodeLeaves(expectedDataspaceName, cmHandle, xpath, jsonData, noTimestamp)
134     }
135
136     def 'Replace data node tree.'() {
137         given: 'a cm Handle and a cps path'
138             def xpath = '/xpath'
139             def jsonData = 'some json'
140         when: 'replaceNodeTree is invoked'
141             objectUnderTest.replaceNodeTree(cmHandle, xpath, jsonData)
142         then: 'the persistence service is called once with the correct parameters'
143             1 * mockCpsDataService.replaceNodeTree(expectedDataspaceName, cmHandle, xpath, jsonData, noTimestamp)
144     }
145
146     def 'Register or re-register a DMI Plugin with #scenario cm handles.'() {
147         given: 'a registration '
148             NetworkCmProxyDataServiceImpl objectUnderTest = getObjectUnderTestWithModelSyncDisabled()
149             def dmiPluginRegistration = new DmiPluginRegistration()
150             dmiPluginRegistration.dmiPlugin = 'my-server'
151             persistenceCmHandle.cmHandleID = '123'
152             persistenceCmHandle.cmHandleProperties = [name1: 'value1', name2: 'value2']
153             dmiPluginRegistration.createdCmHandles = createdCmHandles
154             dmiPluginRegistration.updatedCmHandles = updatedCmHandles
155             dmiPluginRegistration.removedCmHandles = removedCmHandles
156             def expectedJsonData = '{"cm-handles":[{"id":"123","dmi-service-name":"my-server","additional-properties":[{"name":"name1","value":"value1"},{"name":"name2","value":"value2"}]}]}'
157         when: 'registration is updated'
158             objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
159         then: 'the CPS save list node data is invoked with the expected parameters'
160             expectedCallsToSaveNode * mockCpsDataService.saveListNodeData('NCMP-Admin', 'ncmp-dmi-registry',
161                 '/dmi-registry', expectedJsonData, noTimestamp)
162         and: 'update Node and Child Data Nodes is invoked with correct parameters'
163             expectedCallsToUpdateNode * mockCpsDataService.updateNodeLeavesAndExistingDescendantLeaves('NCMP-Admin',
164                 'ncmp-dmi-registry', '/dmi-registry', expectedJsonData, noTimestamp)
165         and : 'delete list data node is invoked with the correct parameters'
166             expectedCallsToDeleteListDataNode * mockCpsDataService.deleteListNodeData('NCMP-Admin',
167                 'ncmp-dmi-registry', "/dmi-registry/cm-handles[@id='cmHandle001']", noTimestamp)
168
169         where:
170             scenario                        | createdCmHandles      | updatedCmHandles      | removedCmHandles || expectedCallsToSaveNode   | expectedCallsToUpdateNode | expectedCallsToDeleteListDataNode
171             'create'                        | [persistenceCmHandle] | []                    | []               || 1                         | 0                         | 0
172             'update'                        | []                    | [persistenceCmHandle] | []               || 0                         | 1                         | 0
173             'delete'                        | []                    | []                    | cmHandlesArray   || 0                         | 0                         | 1
174             'create, update and delete'     | [persistenceCmHandle] | [persistenceCmHandle] | cmHandlesArray   || 1                         | 1                         | 1
175             'no valid data'                 | null                  | null                  |  null            || 0                         | 0                         | 0
176     }
177
178     def 'Register a DMI Plugin for the given cmHandle without additional properties.'() {
179         given: 'a registration without cmHandle properties '
180             NetworkCmProxyDataServiceImpl objectUnderTest = getObjectUnderTestWithModelSyncDisabled()
181             def dmiPluginRegistration = new DmiPluginRegistration()
182             dmiPluginRegistration.dmiPlugin = 'my-server'
183             persistenceCmHandle.cmHandleID = '123'
184             persistenceCmHandle.cmHandleProperties = null
185             dmiPluginRegistration.createdCmHandles = [persistenceCmHandle]
186             def expectedJsonData = '{"cm-handles":[{"id":"123","dmi-service-name":"my-server","additional-properties":[]}]}'
187         when: 'registration is updated'
188             objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
189         then: 'the CPS save list node data is invoked with the expected parameters'
190             1 * mockCpsDataService.saveListNodeData('NCMP-Admin', 'ncmp-dmi-registry',
191                 '/dmi-registry', expectedJsonData, noTimestamp)
192     }
193
194     def 'Register a DMI Plugin with JSON processing errors during #scenario.'() {
195         given: 'a registration without cmHandle properties '
196             NetworkCmProxyDataServiceImpl objectUnderTest = getObjectUnderTestWithModelSyncDisabled()
197             def dmiPluginRegistration = new DmiPluginRegistration()
198             dmiPluginRegistration.createdCmHandles = createdCmHandles
199             dmiPluginRegistration.updatedCmHandles = updatedCmHandles
200         and: 'an JSON processing exception occurs'
201             spyObjectMapper.writeValueAsString(_) >> { throw (new JsonProcessingException('')) }
202         when: 'registration is updated'
203             objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
204         then: 'a data validation exception is thrown'
205             thrown(DataValidationException)
206         where:
207             scenario | createdCmHandles      | updatedCmHandles
208             'create' | [persistenceCmHandle] | []
209             'update' | []                    | [persistenceCmHandle]
210     }
211
212     def 'Register a DMI Plugin with no data found during delete.'() {
213         given: 'a registration without cmHandle properties '
214             NetworkCmProxyDataServiceImpl objectUnderTest = getObjectUnderTestWithModelSyncDisabled()
215             def dmiPluginRegistration = new DmiPluginRegistration()
216             dmiPluginRegistration.removedCmHandles = ['some cm handle']
217         and: 'an JSON processing exception occurs'
218             mockCpsDataService.deleteListNodeData(*_) >>  { throw (new DataNodeNotFoundException('','')) }
219         when: 'registration is updated'
220             objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
221         then: 'no exception is thrown'
222             noExceptionThrown()
223     }
224
225     def 'Get resource data for pass-through operational from dmi.'() {
226         given: 'data node representing cmHandle and its properties'
227             def cmHandleDataNode = getCmHandleDataNodeForTest(true)
228         and: 'data node is got from data service'
229             mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
230                 cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode
231         and: 'resource data is got from DMI'
232             mockDmiOperations.getResourceDataOperationalFromDmi('testDmiService',
233                 'testCmHandle',
234                 'testResourceId',
235                 'testFieldQuery',
236                 5,
237                 'testAcceptParam',
238                 '{"operation":"read","cmHandleProperties":{"testName":"testValue"}}') >> new ResponseEntity<>('result-json', HttpStatus.OK)
239         when: 'get resource data is called'
240             def response = objectUnderTest.getResourceDataOperationalForCmHandle('testCmHandle',
241             'testResourceId',
242             'testAcceptParam',
243             'testFieldQuery',
244             5)
245         then: 'dmi returns ok response'
246             response == 'result-json'
247     }
248
249     def 'Get resource data for pass-through operational from dmi threw parsing exception.'() {
250         given: 'data node representing cmHandle and its properties'
251             def cmHandleDataNode = getCmHandleDataNodeForTest(true)
252         and: 'cps data service returns valid cmHandle data node'
253             mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
254                     cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode
255         and: 'objectMapper not able to parse object'
256             def mockObjectMapper = Mock(ObjectMapper)
257             objectUnderTest.objectMapper = mockObjectMapper
258             mockObjectMapper.writeValueAsString(_) >> { throw new JsonProcessingException('testException') }
259         when: 'get resource data is called'
260             def response = objectUnderTest.getResourceDataOperationalForCmHandle('testCmHandle',
261                     'testResourceId',
262                     'testAcceptParam',
263                     'testFieldQuery',
264                     5)
265         then: 'exception is thrown with the expected details'
266             def exceptionThrown = thrown(NcmpException.class)
267             exceptionThrown.details == 'testException'
268     }
269
270     def 'Get resource data for pass-through operational from dmi return NOK response.'() {
271         given: 'data node representing cmHandle and its properties'
272             def cmHandleDataNode = getCmHandleDataNodeForTest(true)
273         and: 'cps data service returns valid cmHandle data node'
274             mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
275                     cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode
276         and: 'dmi returns NOK response'
277             mockDmiOperations.getResourceDataOperationalFromDmi('testDmiService',
278                     'testCmHandle',
279                     'testResourceId',
280                     'testFieldQuery',
281                     5,
282                     'testAcceptParam',
283                     '{"operation":"read","cmHandleProperties":{"testName":"testValue"}}')
284                     >> new ResponseEntity<>('NOK-json', HttpStatus.NOT_FOUND)
285         when: 'get resource data is called'
286             def response = objectUnderTest.getResourceDataOperationalForCmHandle('testCmHandle',
287                     'testResourceId',
288                     'testAcceptParam',
289                     'testFieldQuery',
290                     5)
291         then: 'exception is thrown'
292             def exceptionThrown = thrown(NcmpException.class)
293         and: 'details contains the original response'
294             exceptionThrown.details.contains('NOK-json')
295     }
296
297     def 'Get resource data for pass-through running from dmi.'() {
298         given: 'data node representing cmHandle and its properties'
299             def cmHandleDataNode = getCmHandleDataNodeForTest(true)
300         and: 'cpsDataService returns valid dataNode'
301             mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
302                     cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode
303         and: 'dmi returns valid response and data'
304             mockDmiOperations.getResourceDataPassThroughRunningFromDmi('testDmiService',
305                     'testCmHandle',
306                     'testResourceId',
307                     'testFieldQuery',
308                     5,
309                     'testAcceptParam',
310                     '{"operation":"read","cmHandleProperties":{"testName":"testValue"}}') >> new ResponseEntity<>('{result-json}', HttpStatus.OK)
311         when: 'get resource data is called'
312             def response = objectUnderTest.getResourceDataPassThroughRunningForCmHandle('testCmHandle',
313                     'testResourceId',
314                     'testAcceptParam',
315                     'testFieldQuery',
316                     5)
317         then: 'get resource data returns expected response'
318             response == '{result-json}'
319     }
320
321     def 'Get resource data for pass-through running from dmi threw parsing exception.'() {
322         given: 'data node representing cmHandle and its properties'
323             def cmHandleDataNode = getCmHandleDataNodeForTest(true)
324         and: 'cpsDataService returns valid dataNode'
325             mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
326                     cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode
327         and: 'objectMapper not able to parse object'
328             def mockObjectMapper = Mock(ObjectMapper)
329             objectUnderTest.objectMapper = mockObjectMapper
330             mockObjectMapper.writeValueAsString(_) >> { throw new JsonProcessingException('testException') }
331         when: 'get resource data is called'
332             def response = objectUnderTest.getResourceDataPassThroughRunningForCmHandle('testCmHandle',
333                     'testResourceId',
334                     'testAcceptParam',
335                     'testFieldQuery',
336                     5)
337         then: 'exception is thrown with the expected details'
338             def exceptionThrown = thrown(NcmpException.class)
339             exceptionThrown.details == 'testException'
340     }
341
342     def 'Get resource data for pass-through running from dmi return NOK response.'() {
343         given: 'data node representing cmHandle and its properties'
344             def cmHandleDataNode = getCmHandleDataNodeForTest(true)
345         and: 'cpsDataService returns valid dataNode'
346             mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
347                     cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode
348         and: 'dmi returns NOK response'
349             mockDmiOperations.getResourceDataPassThroughRunningFromDmi('testDmiService',
350                     'testCmHandle',
351                     'testResourceId',
352                     'testFieldQuery',
353                     5,
354                     'testAcceptParam',
355                     '{"operation":"read","cmHandleProperties":{"testName":"testValue"}}')
356                     >> new ResponseEntity<>('NOK-json', HttpStatus.NOT_FOUND)
357         when: 'get resource data is called'
358             def response = objectUnderTest.getResourceDataPassThroughRunningForCmHandle('testCmHandle',
359                     'testResourceId',
360                     'testAcceptParam',
361                     'testFieldQuery',
362                     5)
363         then: 'exception is thrown'
364             def exceptionThrown = thrown(NcmpException.class)
365         and: 'details contains the original response'
366             exceptionThrown.details.contains('NOK-json')
367     }
368
369     def 'Write resource data for pass-through running from dmi using POST #scenario cm handle properties.'() {
370         given: 'data node representing cmHandle #scenario cm handle properties'
371             def cmHandleDataNode = getCmHandleDataNodeForTest(includeCmHandleProperties)
372         and: 'cpsDataService returns valid cm-handle datanode'
373             mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
374                     cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode
375         when: 'get resource data is called'
376             objectUnderTest.createResourceDataPassThroughRunningForCmHandle('testCmHandle',
377                     'testResourceId',
378                     '{some-json}', 'application/json')
379         then: 'dmi called with correct data'
380             1 * mockDmiOperations.createResourceDataPassThroughRunningFromDmi('testDmiService',
381                 'testCmHandle',
382                 'testResourceId',
383                 '{"operation":"create","dataType":"application/json","data":"{some-json}","cmHandleProperties":'
384                 + expectedJsonForCmhandleProperties+ '}')
385                 >> { new ResponseEntity<>(HttpStatus.OK) }
386         where:
387             scenario  | includeCmHandleProperties || expectedJsonForCmhandleProperties
388             'with'    | true                       || '{"testName":"testValue"}'
389             'without' | false                      || '{}'
390     }
391
392     def 'Write resource data for pass-through running from dmi using POST "not found" response (from DMI).'() {
393         given: 'data node representing cmHandle and its properties'
394             def cmHandleDataNode = getCmHandleDataNodeForTest(true)
395         and: 'cpsDataService returns valid dataNode'
396             mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
397                     cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode
398         and: 'dmi throws exception'
399             mockDmiOperations.createResourceDataPassThroughRunningFromDmi(_ as String, _ as String, _ as String, _ as String)
400                     >> { new ResponseEntity<>(HttpStatus.NOT_FOUND) }
401         when: 'get resource data is called'
402             objectUnderTest.createResourceDataPassThroughRunningForCmHandle('testCmHandle',
403                     'testResourceId',
404                     '{some-json}', 'application/json')
405         then: 'exception is thrown'
406             def exceptionThrown = thrown(NcmpException.class)
407         and: 'details contains (not found) error code: 404'
408             exceptionThrown.details.contains('404')
409     }
410
411     def 'Sync model for a (new) cm handle with #scenario'() {
412         given: 'DMI Plug-in returns a list of module references'
413             getModulesForCmHandle()
414             def knownModule1 = new ModuleReference('module1', '1')
415             def knownOtherModule = new ModuleReference('some other module', 'some revision')
416         and: 'CPS-Core returns list of known modules'
417             mockCpsModuleService.getYangResourceModuleReferences(_) >> [knownModule1, knownOtherModule]
418         and: 'DMI-Plugin returns resource(s) for "new" module(s)'
419             def moduleResources = new ResponseEntity<String>(sdncReponseBody, HttpStatus.OK)
420             mockDmiOperations.getResourceFromDmiWithJsonData(_, _, _, 'moduleResources') >> moduleResources
421         when: 'module Sync is triggered'
422             objectUnderTest.createAnchorAndSyncModel(cmHandleForModelSync)
423         then: 'the CPS module service is called once with the correct parameters'
424             1 * mockCpsModuleService.createSchemaSetFromModules(expectedDataspaceName, cmHandleForModelSync.getId(), expectedYangResourceToContentMap, [knownModule1])
425         and: 'admin service create anchor method has been called with correct parameters'
426             1 * mockCpsAdminService.createAnchor(expectedDataspaceName, cmHandleForModelSync.getId(), cmHandleForModelSync.getId())
427         where: 'the following responses are received from SDNC'
428             scenario             | sdncReponseBody                                                                        || expectedYangResourceToContentMap
429             'one unknown module' | '[{"moduleName" : "someModule", "revision" : "1","yangSource": "[some yang source]"}]' || [someModule: 'some yang source']
430             'no unknown module'  | '[]'                                                                                   || [:]
431     }
432
433
434     def 'Getting Yang Resources.'() {
435         when: 'yang resources is called'
436             objectUnderTest.getYangResourcesModuleReferences('some cm handle')
437         then: 'CPS module services is invoked for the correct dataspace and cm handle'
438             1 * mockCpsModuleService.getYangResourcesModuleReferences('NFP-Operational','some cm handle')
439     }
440
441     def getModulesForCmHandle() {
442         def jsonData = TestUtils.getResourceFileContent('cmHandleModules.json')
443         mockDmiProperties.getAuthUsername() >> 'someUser'
444         mockDmiProperties.getAuthPassword() >> 'somePassword'
445         def moduleReferencesFromCmHandleAsJson = new ResponseEntity<String>(jsonData, HttpStatus.OK)
446         mockDmiOperations.getResourceFromDmi(_, cmHandleForModelSync.getId(), 'modules') >> moduleReferencesFromCmHandleAsJson
447     }
448
449     def getObjectUnderTestWithModelSyncDisabled() {
450         def objectUnderTest = Spy(new NetworkCmProxyDataServiceImpl(mockDmiOperations, mockCpsModuleService,
451                 mockCpsDataService, mockCpsQueryService, mockCpsAdminService, spyObjectMapper))
452         objectUnderTest.createAnchorAndSyncModel(_) >> null
453         return objectUnderTest
454     }
455
456     def getCmHandleDataNodeForTest(boolean includeCmHandleProperties) {
457         def cmHandleDataNode = new DataNode()
458         cmHandleDataNode.leaves = ['dmi-service-name': 'testDmiService']
459         if (includeCmHandleProperties) {
460             def cmHandlePropertyDataNode = new DataNode()
461             cmHandlePropertyDataNode.leaves = ['name': 'testName', 'value': 'testValue']
462             cmHandleDataNode.childDataNodes = [cmHandlePropertyDataNode]
463         }
464         return cmHandleDataNode
465     }
466
467 }