X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=cps-rest%2Fsrc%2Ftest%2Fgroovy%2Forg%2Fonap%2Fcps%2Frest%2Fcontroller%2FDataRestControllerSpec.groovy;h=6f415bd45179375a73f448497ab4763f24bd5cde;hb=ebfa4077b2e462237301e93566fed6ef2f56674c;hp=06f2f5795f17b186b0f9767506b8fbe5ddf62e24;hpb=a79c9f1bdf335843c29a425da53c15b5e353e5a3;p=cps.git diff --git a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy index 06f2f5795..6f415bd45 100755 --- a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy +++ b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy @@ -1,8 +1,8 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation + * Copyright (C) 2021-2022 Nordix Foundation * Modifications Copyright (C) 2021 Pantheon.tech - * Modifications Copyright (C) 2021 Bell Canada. + * Modifications Copyright (C) 2021-2022 Bell Canada. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,10 +22,12 @@ package org.onap.cps.rest.controller +import com.fasterxml.jackson.databind.ObjectMapper import org.onap.cps.api.CpsDataService import org.onap.cps.spi.model.DataNode import org.onap.cps.spi.model.DataNodeBuilder import org.onap.cps.utils.DateTimeUtility +import org.onap.cps.utils.JsonObjectMapper import org.spockframework.spring.SpringBean import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Value @@ -50,6 +52,9 @@ class DataRestControllerSpec extends Specification { @SpringBean CpsDataService mockCpsDataService = Mock() + @SpringBean + JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper()) + @Autowired MockMvc mvc @@ -60,6 +65,8 @@ class DataRestControllerSpec extends Specification { def dataspaceName = 'my_dataspace' def anchorName = 'my_anchor' def noTimestamp = null + def requestBody = '{"some-key" : "some-value","categories":[{"books":[{"authors":["Iain M. Banks"]}]}]}' + def expectedJsonData = '{"some-key":"some-value","categories":[{"books":[{"authors":["Iain M. Banks"]}]}]}' @Shared static DataNode dataNodeWithLeavesNoChildren = new DataNodeBuilder().withXpath('/xpath') @@ -74,21 +81,20 @@ class DataRestControllerSpec extends Specification { } def 'Create a node: #scenario.'() { - given: 'some json to create a data node' + given: 'endpoint to create a node' def endpoint = "$dataNodeBaseEndpoint/anchors/$anchorName/nodes" - def json = 'some json (this is not validated)' when: 'post is invoked with datanode endpoint and json' def response = mvc.perform( post(endpoint) .contentType(MediaType.APPLICATION_JSON) .param('xpath', parentNodeXpath) - .content(json) + .content(requestBody) ).andReturn().response then: 'a created response is returned' response.status == HttpStatus.CREATED.value() then: 'the java API was called with the correct parameters' - 1 * mockCpsDataService.saveData(dataspaceName, anchorName, json, noTimestamp) + 1 * mockCpsDataService.saveData(dataspaceName, anchorName, expectedJsonData, noTimestamp) where: 'following xpath parameters are are used' scenario | parentNodeXpath 'no xpath parameter' | '' @@ -96,9 +102,8 @@ class DataRestControllerSpec extends Specification { } def 'Create a node with observed-timestamp'() { - given: 'some json to create a data node' + given: 'endpoint to create a node' def endpoint = "$dataNodeBaseEndpoint/anchors/$anchorName/nodes" - def json = 'some json (this is not validated)' when: 'post is invoked with datanode endpoint and json' def response = mvc.perform( @@ -106,12 +111,12 @@ class DataRestControllerSpec extends Specification { .contentType(MediaType.APPLICATION_JSON) .param('xpath', '') .param('observed-timestamp', observedTimestamp) - .content(json) + .content(requestBody) ).andReturn().response then: 'a created response is returned' response.status == expectedHttpStatus.value() then: 'the java API was called with the correct parameters' - expectedApiCount * mockCpsDataService.saveData(dataspaceName, anchorName, json, + expectedApiCount * mockCpsDataService.saveData(dataspaceName, anchorName, expectedJsonData, { it == DateTimeUtility.toOffsetDateTime(observedTimestamp) }) where: scenario | observedTimestamp || expectedApiCount | expectedHttpStatus @@ -120,16 +125,15 @@ class DataRestControllerSpec extends Specification { } def 'Create a child node'() { - given: 'some json to create a data node' + given: 'endpoint to create a node' def endpoint = "$dataNodeBaseEndpoint/anchors/$anchorName/nodes" - def json = 'some json (this is not validated)' and: 'parent node xpath' def parentNodeXpath = 'some xpath' when: 'post is invoked with datanode endpoint and json' def postRequestBuilder = post(endpoint) .contentType(MediaType.APPLICATION_JSON) .param('xpath', parentNodeXpath) - .content(json) + .content(requestBody) if (observedTimestamp != null) postRequestBuilder.param('observed-timestamp', observedTimestamp) def response = @@ -137,7 +141,7 @@ class DataRestControllerSpec extends Specification { then: 'a created response is returned' response.status == HttpStatus.CREATED.value() then: 'the java API was called with the correct parameters' - 1 * mockCpsDataService.saveData(dataspaceName, anchorName, parentNodeXpath, json, + 1 * mockCpsDataService.saveData(dataspaceName, anchorName, parentNodeXpath, expectedJsonData, DateTimeUtility.toOffsetDateTime(observedTimestamp)) where: scenario | observedTimestamp @@ -146,21 +150,20 @@ class DataRestControllerSpec extends Specification { } def 'Save list elements #scenario.'() { - given: 'parent node xpath and json data inputs' + given: 'parent node xpath ' def parentNodeXpath = 'parent node xpath' - def jsonData = 'json data' when: 'list-node endpoint is invoked with post (create) operation' def postRequestBuilder = post("$dataNodeBaseEndpoint/anchors/$anchorName/list-nodes") .contentType(MediaType.APPLICATION_JSON) .param('xpath', parentNodeXpath) - .content(jsonData) + .content(requestBody) if (observedTimestamp != null) postRequestBuilder.param('observed-timestamp', observedTimestamp) def response = mvc.perform(postRequestBuilder).andReturn().response then: 'a created response is returned' response.status == expectedHttpStatus.value() then: 'the java API was called with the correct parameters' - expectedApiCount * mockCpsDataService.saveListElements(dataspaceName, anchorName, parentNodeXpath, jsonData, + expectedApiCount * mockCpsDataService.saveListElements(dataspaceName, anchorName, parentNodeXpath, expectedJsonData, { it == DateTimeUtility.toOffsetDateTime(observedTimestamp) }) where: scenario | observedTimestamp || expectedApiCount | expectedHttpStatus @@ -171,7 +174,7 @@ class DataRestControllerSpec extends Specification { def 'Get data node with leaves'() { given: 'the service returns data node leaves' - def xpath = 'some xPath' + def xpath = 'xpath' def endpoint = "$dataNodeBaseEndpoint/anchors/$anchorName/node" mockCpsDataService.getDataNode(dataspaceName, anchorName, xpath, OMIT_DESCENDANTS) >> dataNodeWithLeavesNoChildren when: 'get request is performed through REST API' @@ -180,6 +183,8 @@ class DataRestControllerSpec extends Specification { .andReturn().response then: 'a success response is returned' response.status == HttpStatus.OK.value() + then: 'the response contains the the datanode in json format' + response.getContentAsString() == '{"xpath":{"leaf":"value","leafList":["leaveListElement1","leaveListElement2"]}}' and: 'response contains expected leaf and value' response.contentAsString.contains('"leaf":"value"') and: 'response contains expected leaf-list and values' @@ -200,29 +205,30 @@ class DataRestControllerSpec extends Specification { .andReturn().response then: 'a success response is returned' response.status == HttpStatus.OK.value() + and: 'the response contains the root node identifier: #expectedRootidentifier' + response.contentAsString.contains(expectedRootidentifier) and: 'the response contains child is #expectChildInResponse' response.contentAsString.contains('"child"') == expectChildInResponse where: - scenario | dataNode | includeDescendantsOption || expectedCpsDataServiceOption | expectChildInResponse - 'no descendants by default' | dataNodeWithLeavesNoChildren | '' || OMIT_DESCENDANTS | false - 'no descendant explicitly' | dataNodeWithLeavesNoChildren | 'false' || OMIT_DESCENDANTS | false - 'with descendants' | dataNodeWithChild | 'true' || INCLUDE_ALL_DESCENDANTS | true + scenario | dataNode | includeDescendantsOption || expectedCpsDataServiceOption | expectChildInResponse | expectedRootidentifier + 'no descendants by default' | dataNodeWithLeavesNoChildren | '' || OMIT_DESCENDANTS | false | 'xpath' + 'no descendant explicitly' | dataNodeWithLeavesNoChildren | 'false' || OMIT_DESCENDANTS | false | 'xpath' + 'with descendants' | dataNodeWithChild | 'true' || INCLUDE_ALL_DESCENDANTS | true | 'parent' } def 'Update data node leaves: #scenario.'() { - given: 'json data' - def jsonData = 'json data' + given: 'endpoint to update a node ' def endpoint = "$dataNodeBaseEndpoint/anchors/$anchorName/nodes" when: 'patch request is performed' def response = mvc.perform( patch(endpoint) .contentType(MediaType.APPLICATION_JSON) - .content(jsonData) + .content(requestBody) .param('xpath', inputXpath) ).andReturn().response then: 'the service method is invoked with expected parameters' - 1 * mockCpsDataService.updateNodeLeaves(dataspaceName, anchorName, xpathServiceParameter, jsonData, null) + 1 * mockCpsDataService.updateNodeLeaves(dataspaceName, anchorName, xpathServiceParameter, expectedJsonData, null) and: 'response status indicates success' response.status == HttpStatus.OK.value() where: @@ -233,20 +239,19 @@ class DataRestControllerSpec extends Specification { } def 'Update data node leaves with observedTimestamp'() { - given: 'json data' - def jsonData = 'json data' + given: 'endpoint to update a node leaves ' def endpoint = "$dataNodeBaseEndpoint/anchors/$anchorName/nodes" when: 'patch request is performed' def response = mvc.perform( patch(endpoint) .contentType(MediaType.APPLICATION_JSON) - .content(jsonData) + .content(requestBody) .param('xpath', '/') .param('observed-timestamp', observedTimestamp) ).andReturn().response then: 'the service method is invoked with expected parameters' - expectedApiCount * mockCpsDataService.updateNodeLeaves(dataspaceName, anchorName, '/', jsonData, + expectedApiCount * mockCpsDataService.updateNodeLeaves(dataspaceName, anchorName, '/', expectedJsonData, { it == DateTimeUtility.toOffsetDateTime(observedTimestamp) }) and: 'response status indicates success' response.status == expectedHttpStatus.value() @@ -257,19 +262,18 @@ class DataRestControllerSpec extends Specification { } def 'Replace data node tree: #scenario.'() { - given: 'json data' - def jsonData = 'json data' + given: 'endpoint to replace node' def endpoint = "$dataNodeBaseEndpoint/anchors/$anchorName/nodes" when: 'put request is performed' def response = mvc.perform( put(endpoint) .contentType(MediaType.APPLICATION_JSON) - .content(jsonData) + .content(requestBody) .param('xpath', inputXpath)) .andReturn().response then: 'the service method is invoked with expected parameters' - 1 * mockCpsDataService.replaceNodeTree(dataspaceName, anchorName, xpathServiceParameter, jsonData, noTimestamp) + 1 * mockCpsDataService.replaceNodeTree(dataspaceName, anchorName, xpathServiceParameter, expectedJsonData, noTimestamp) and: 'response status indicates success' response.status == HttpStatus.OK.value() where: @@ -280,20 +284,19 @@ class DataRestControllerSpec extends Specification { } def 'Replace data node tree with observedTimestamp.'() { - given: 'json data' - def jsonData = 'json data' + given: 'endpoint to replace node' def endpoint = "$dataNodeBaseEndpoint/anchors/$anchorName/nodes" when: 'put request is performed' def response = mvc.perform( put(endpoint) .contentType(MediaType.APPLICATION_JSON) - .content(jsonData) + .content(requestBody) .param('xpath', '') .param('observed-timestamp', observedTimestamp)) .andReturn().response then: 'the service method is invoked with expected parameters' - expectedApiCount * mockCpsDataService.replaceNodeTree(dataspaceName, anchorName, '/', jsonData, + expectedApiCount * mockCpsDataService.replaceNodeTree(dataspaceName, anchorName, '/', expectedJsonData, { it == DateTimeUtility.toOffsetDateTime(observedTimestamp) }) and: 'response status indicates success' response.status == expectedHttpStatus.value() @@ -308,14 +311,14 @@ class DataRestControllerSpec extends Specification { def putRequestBuilder = put("$dataNodeBaseEndpoint/anchors/$anchorName/list-nodes") .contentType(MediaType.APPLICATION_JSON) .param('xpath', 'parent xpath') - .content('json data') + .content(requestBody) if (observedTimestamp != null) putRequestBuilder.param('observed-timestamp', observedTimestamp) def response = mvc.perform(putRequestBuilder).andReturn().response then: 'a success response is returned' response.status == expectedHttpStatus.value() and: 'the java API was called with the correct parameters' - expectedApiCount * mockCpsDataService.replaceListContent(dataspaceName, anchorName, 'parent xpath', 'json data', + expectedApiCount * mockCpsDataService.replaceListContent(dataspaceName, anchorName, 'parent xpath', expectedJsonData, { it == DateTimeUtility.toOffsetDateTime(observedTimestamp) }) where: scenario | observedTimestamp || expectedApiCount | expectedHttpStatus @@ -342,4 +345,26 @@ class DataRestControllerSpec extends Specification { 'without observed-timestamp' | null || 1 | HttpStatus.NO_CONTENT 'with invalid observed-timestamp' | 'invalid' || 0 | HttpStatus.BAD_REQUEST } + + def 'Delete data node #scenario.'() { + given: 'data node xpath' + def dataNodeXpath = '/dataNodeXpath' + when: 'delete data node endpoint is invoked' + def deleteDataNodeRequest = delete( "$dataNodeBaseEndpoint/anchors/$anchorName/nodes") + .param('xpath', dataNodeXpath) + and: 'observed timestamp is added to the parameters' + if (observedTimestamp != null) + deleteDataNodeRequest.param('observed-timestamp', observedTimestamp) + def response = mvc.perform(deleteDataNodeRequest).andReturn().response + then: 'a successful response is returned' + response.status == expectedHttpStatus.value() + and: 'the api is called with the correct parameters' + expectedApiCount * mockCpsDataService.deleteDataNode(dataspaceName, anchorName, dataNodeXpath, + { it == DateTimeUtility.toOffsetDateTime(observedTimestamp) }) + where: + scenario | observedTimestamp || expectedApiCount | expectedHttpStatus + 'with observed timestamp' | '2021-03-03T23:59:59.999-0400' || 1 | HttpStatus.NO_CONTENT + 'without observed timestamp' | null || 1 | HttpStatus.NO_CONTENT + 'with invalid observed timestamp' | 'invalid' || 0 | HttpStatus.BAD_REQUEST + } }