+ response.getContentAsString() == '[{"moduleName":"some-name1","revision":"2021-10-03"}]'
+ and: 'response returns an OK http code'
+ response.status == HttpStatus.OK.value()
+ }
+
+ def 'Retrieve cm handles.'() {
+ given: 'an endpoint and json data'
+ def searchesEndpoint = "$ncmpBasePathV1/ch/searches"
+ String jsonString = TestUtils.getResourceFileContent('cmhandle-search.json')
+ and: 'the service method is invoked with module names and returns two cm handles'
+ def cmHandle1 = new NcmpServiceCmHandle()
+ cmHandle1.cmHandleId = 'some-cmhandle-id1'
+ cmHandle1.publicProperties = [color:'yellow']
+ def cmHandle2 = new NcmpServiceCmHandle()
+ cmHandle2.cmHandleId = 'some-cmhandle-id2'
+ cmHandle2.publicProperties = [color:'green']
+ mockNetworkCmProxyDataService.executeCmHandleSearch(_) >> [cmHandle1, cmHandle2]
+ when: 'the searches api is invoked'
+ def response = mvc.perform(post(searchesEndpoint)
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(jsonString)).andReturn().response
+ then: 'response status returns OK'
+ response.status == HttpStatus.OK.value()
+ and: 'the expected response content is returned'
+ response.contentAsString == '[{"cmHandle":"some-cmhandle-id1","publicCmHandleProperties":[{"color":"yellow"}],"state":null},{"cmHandle":"some-cmhandle-id2","publicCmHandleProperties":[{"color":"green"}],"state":null}]'
+ }
+
+ def 'Get complete Cm Handle details by Cm Handle id.'() {
+ given: 'an endpoint and a cm handle'
+ def cmHandleDetailsEndpoint = "$ncmpBasePathV1/ch/some-cm-handle"
+ and: 'an existing ncmp service cm handle'
+ def cmHandleId = 'some-cm-handle'
+ def dmiProperties = [ prop:'some DMI property' ]
+ def publicProperties = [ "public prop":'some public property' ]
+ def compositeState = compositeStateTestObject()
+ def ncmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: cmHandleId, dmiProperties: dmiProperties, publicProperties: publicProperties, compositeState: compositeState)
+ and: 'the service method is invoked with the cm handle id'
+ 1 * mockNetworkCmProxyDataService.getNcmpServiceCmHandle('some-cm-handle') >> ncmpServiceCmHandle
+ when: 'the cm handle details api is invoked'
+ def response = mvc.perform(get(cmHandleDetailsEndpoint)).andReturn().response
+ then: 'the correct response is returned'
+ response.status == HttpStatus.OK.value()
+ and: 'the response contains the public properties'
+ assertContainsPublicProperties(response)
+ and: 'the response contains the cm handle state'
+ assertContainsState(response)
+ and: 'the content does not contain dmi properties'
+ !response.contentAsString.contains("some DMI property")
+ }
+
+ def 'Get Cm Handle public properties by Cm Handle id.' () {
+ given: 'a cm handle properties endpoint'
+ def cmHandlePropertiesEndpoint = "$ncmpBasePathV1/ch/some-cm-handle/properties"
+ and: 'some cm handle public properties'
+ def publicProperties = [ 'public prop':'some public property' ]
+ and: 'the service method is invoked with the cm handle id returning the cm handle public properties'
+ 1 * mockNetworkCmProxyDataService.getCmHandlePublicProperties('some-cm-handle') >> publicProperties
+ when: 'the cm handle properties api is invoked'
+ def response = mvc.perform(get(cmHandlePropertiesEndpoint)).andReturn().response
+ then: 'the correct response is returned'
+ response.status == HttpStatus.OK.value()
+ and: 'the response contains the public properties'
+ assertContainsPublicProperties(response)
+ }
+
+ def 'Get Cm Handle composite state by Cm Handle id.' () {
+ given: 'a cm handle state endpoint'
+ def cmHandlePropertiesEndpoint = "$ncmpBasePathV1/ch/some-cm-handle/state"
+ and: 'some cm handle composite state'
+ def compositeState = compositeStateTestObject()
+ and: 'the service method is invoked with the cm handle id returning the cm handle composite state'
+ 1 * mockNetworkCmProxyDataService.getCmHandleCompositeState('some-cm-handle') >> compositeState
+ when: 'the cm handle state api is invoked'
+ def response = mvc.perform(get(cmHandlePropertiesEndpoint)).andReturn().response
+ then: 'the correct response is returned'
+ response.status == HttpStatus.OK.value()
+ and: 'the response contains the cm handle state'
+ assertContainsState(response)
+ }
+
+ def 'Call execute cm handle searches with unrecognized condition name.'() {
+ given: 'an endpoint and json data'
+ def searchesEndpoint = "$ncmpBasePathV1/ch/searches"
+ String jsonString = TestUtils.getResourceFileContent('invalid-cmhandle-search.json')
+ and: 'the service method is invoked with module names and returns two cm handles'
+ def cmHandel1 = new NcmpServiceCmHandle()
+ cmHandel1.cmHandleId = 'some-cmhandle-id1'
+ cmHandel1.publicProperties = [color:'yellow']
+ def cmHandel2 = new NcmpServiceCmHandle()
+ cmHandel2.cmHandleId = 'some-cmhandle-id2'
+ cmHandel2.publicProperties = [color:'green']
+ mockNetworkCmProxyDataService.executeCmHandleSearch(_) >> [cmHandel1, cmHandel2]
+ when: 'the searches api is invoked'
+ def response = mvc.perform(post(searchesEndpoint)
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(jsonString)).andReturn().response
+ then: 'an empty cm handle identifier is returned'
+ response.contentAsString == '[{"cmHandle":"some-cmhandle-id1","publicCmHandleProperties":[{"color":"yellow"}],"state":null},{"cmHandle":"some-cmhandle-id2","publicCmHandleProperties":[{"color":"green"}],"state":null}]'
+ }
+
+ def 'Query for cm handles matching query parameters'() {
+ given: 'an endpoint and json data'
+ def searchesEndpoint = "$ncmpBasePathV1/ch/id-searches"
+ and: 'the service method is invoked with module names and returns cm handle ids'
+ 1 * mockNetworkCmProxyDataService.executeCmHandleIdSearch(_) >> ['some-cmhandle-id1', 'some-cmhandle-id2']
+ when: 'the searches api is invoked'
+ def response = mvc.perform(post(searchesEndpoint)
+ .contentType(MediaType.APPLICATION_JSON)
+ .content('{}')).andReturn().response
+ then: 'cm handle ids are returned'
+ response.contentAsString == '["some-cmhandle-id1","some-cmhandle-id2"]'
+ }
+
+ def 'Query for cm handles with invalid request payload'() {
+ when: 'the searches api is invoked'
+ def searchesEndpoint = "$ncmpBasePathV1/ch/id-searches"
+ def invalidInputData = '{invalidJson}'
+ def response = mvc.perform(post(searchesEndpoint)
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(invalidInputData)).andReturn().response
+ then: 'BAD_REQUEST is returned'
+ response.getStatus() == 400
+ }
+
+ def 'Patch resource data in pass-through running datastore.' () {
+ given: 'patch resource data url'
+ def url = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running" +
+ "?resourceIdentifier=parent/child"
+ when: 'patch data resource request is performed'
+ def response = mvc.perform(
+ patch(url)
+ .contentType(MediaType.APPLICATION_JSON)
+ .accept(MediaType.APPLICATION_JSON).content(requestBody)
+ ).andReturn().response
+ then: 'ncmp service method to update resource is called'
+ 1 * mockNetworkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle('testCmHandle',
+ 'parent/child', PATCH, requestBody, 'application/json;charset=UTF-8')
+ and: 'the response status is OK'
+ response.status == HttpStatus.OK.value()
+ }
+
+ def 'Delete resource data in pass-through running datastore.' () {
+ given: 'delete resource data url'
+ def url = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running" +
+ "?resourceIdentifier=parent/child"
+ when: 'delete data resource request is performed'
+ def response = mvc.perform(
+ delete(url).contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)).andReturn().response
+ then: 'the ncmp service method to delete resource is called (with null as body)'
+ 1 * mockNetworkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle('testCmHandle',
+ 'parent/child', DELETE, null, 'application/json;charset=UTF-8')
+ and: 'the response is No Content'
+ response.status == HttpStatus.NO_CONTENT.value()
+ }
+
+ def 'Get resource data from DMI with valid topic i.e. async request for #scenario'() {
+ given: 'resource data url'
+ def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:${datastoreInUrl}" +
+ "?resourceIdentifier=parent/child&options=(a=1,b=2)&topic=my-topic-name"
+ when: 'get data resource request is performed'
+ def response = mvc.perform(
+ get(getUrl)
+ .contentType(MediaType.APPLICATION_JSON)
+ .accept(MediaType.APPLICATION_JSON_VALUE)
+ ).andReturn().response
+ then: 'async request id is generated'
+ assert response.contentAsString.contains("requestId")
+ where: 'the following parameters are used'
+ scenario | datastoreInUrl
+ ':passthrough-operational' | 'passthrough-operational'
+ ':passthrough-running' | 'passthrough-running'
+ }
+
+ def 'Get module definitions based on cmHandleId.' () {
+ when: 'get module definition request is performed'
+ def response = mvc.perform(get("$ncmpBasePathV1/ch/some-cmhandle/modules/definitions"))
+ .andReturn().response
+ then: 'ncmp service method to get module definitions is called'
+ mockNetworkCmProxyDataService.getModuleDefinitionsByCmHandleId('some-cmhandle')
+ >> [new ModuleDefinition('sampleModuleName', '2021-10-03',
+ 'module sampleModuleName{ sample module content }')]
+ and: 'response contains an array with the module name, revision and content'
+ response.getContentAsString() == '[{"moduleName":"sampleModuleName","revision":"2021-10-03","content":"module sampleModuleName{ sample module content }"}]'