From 6ce84d98f68b45f02f16dc99423670f4a53fd946 Mon Sep 17 00:00:00 2001 From: Michal Jagiello Date: Tue, 13 Dec 2022 07:40:19 +0000 Subject: XML content on create anchors node support Add XML content type support on anchor node creation. Issue-ID: CPS-1257 Change-Id: I7e7a9a1961b6e81de93a4e32e842b47f8a163a09 Signed-off-by: Michal Jagiello Signed-off-by: Lee Anjella Macabuhay --- .../rest/controller/DataRestControllerSpec.groovy | 69 ++++++++++++++-------- .../exceptions/CpsRestExceptionHandlerSpec.groovy | 17 +----- 2 files changed, 46 insertions(+), 40 deletions(-) (limited to 'cps-rest/src/test/groovy') 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 53da3e659..94f62f8c2 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 @@ -3,6 +3,7 @@ * Copyright (C) 2021-2022 Nordix Foundation * Modifications Copyright (C) 2021 Pantheon.tech * Modifications Copyright (C) 2021-2022 Bell Canada. + * Modifications Copyright (C) 2022 Deutsche Telekom AG * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +27,7 @@ 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.ContentType import org.onap.cps.utils.DateTimeUtility import org.onap.cps.utils.JsonObjectMapper import org.onap.cps.utils.PrefixResolver @@ -69,9 +71,19 @@ 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"]}]}]}' + + @Shared + def requestBodyJson = '{"some-key":"some-value","categories":[{"books":[{"authors":["Iain M. Banks"]}]}]}' + + @Shared def expectedJsonData = '{"some-key":"some-value","categories":[{"books":[{"authors":["Iain M. Banks"]}]}]}' + @Shared + def requestBodyXml = '\n\n' + + @Shared + def expectedXmlData = '\n\n' + @Shared static DataNode dataNodeWithLeavesNoChildren = new DataNodeBuilder().withXpath('/xpath') .withLeaves([leaf: 'value', leafList: ['leaveListElement1', 'leaveListElement2']]).build() @@ -91,18 +103,20 @@ class DataRestControllerSpec extends Specification { def response = mvc.perform( post(endpoint) - .contentType(MediaType.APPLICATION_JSON) + .contentType(contentType) .param('xpath', parentNodeXpath) .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, expectedJsonData, noTimestamp) + 1 * mockCpsDataService.saveData(dataspaceName, anchorName, expectedData, noTimestamp, expectedContentType) where: 'following xpath parameters are are used' - scenario | parentNodeXpath - 'no xpath parameter' | '' - 'xpath parameter point root' | '/' + scenario | parentNodeXpath | contentType | expectedContentType | requestBody | expectedData + 'JSON content: no xpath parameter' | '' | MediaType.APPLICATION_JSON | ContentType.JSON | requestBodyJson | expectedJsonData + 'JSON content: xpath parameter point root' | '/' | MediaType.APPLICATION_JSON | ContentType.JSON | requestBodyJson | expectedJsonData + 'XML content: no xpath parameter' | '' | MediaType.APPLICATION_XML | ContentType.XML | requestBodyXml | expectedXmlData + 'XML content: xpath parameter point root' | '/' | MediaType.APPLICATION_XML | ContentType.XML | requestBodyXml | expectedXmlData } def 'Create a node with observed-timestamp'() { @@ -112,30 +126,31 @@ class DataRestControllerSpec extends Specification { def response = mvc.perform( post(endpoint) - .contentType(MediaType.APPLICATION_JSON) + .contentType(contentType) .param('xpath', '') .param('observed-timestamp', observedTimestamp) - .content(requestBody) + .content(content) ).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, expectedJsonData, - { it == DateTimeUtility.toOffsetDateTime(observedTimestamp) }) + expectedApiCount * mockCpsDataService.saveData(dataspaceName, anchorName, expectedData, + { it == DateTimeUtility.toOffsetDateTime(observedTimestamp) }, expectedContentType) where: - scenario | observedTimestamp || expectedApiCount | expectedHttpStatus - 'with observed-timestamp' | '2021-03-03T23:59:59.999-0400' || 1 | HttpStatus.CREATED - 'with invalid observed-timestamp' | 'invalid' || 0 | HttpStatus.BAD_REQUEST + scenario | observedTimestamp | contentType | content || expectedApiCount | expectedHttpStatus | expectedData | expectedContentType + 'with observed-timestamp JSON' | '2021-03-03T23:59:59.999-0400' | MediaType.APPLICATION_JSON | requestBodyJson || 1 | HttpStatus.CREATED | expectedJsonData | ContentType.JSON + 'with observed-timestamp XML' | '2021-03-03T23:59:59.999-0400' | MediaType.APPLICATION_XML | requestBodyXml || 1 | HttpStatus.CREATED | expectedXmlData | ContentType.XML + 'with invalid observed-timestamp' | 'invalid' | MediaType.APPLICATION_JSON | requestBodyJson || 0 | HttpStatus.BAD_REQUEST | expectedJsonData | ContentType.JSON } - def 'Create a child node'() { + def 'Create a child node #scenario'() { given: 'endpoint to create a node' def endpoint = "$dataNodeBaseEndpoint/anchors/$anchorName/nodes" 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) + .contentType(contentType) .param('xpath', parentNodeXpath) .content(requestBody) if (observedTimestamp != null) @@ -145,12 +160,14 @@ 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, expectedJsonData, - DateTimeUtility.toOffsetDateTime(observedTimestamp)) + 1 * mockCpsDataService.saveData(dataspaceName, anchorName, parentNodeXpath, expectedData, + DateTimeUtility.toOffsetDateTime(observedTimestamp), expectedContentType) where: - scenario | observedTimestamp - 'with observed-timestamp' | '2021-03-03T23:59:59.999-0400' - 'without observed-timestamp' | null + scenario | observedTimestamp | contentType | requestBody | expectedData | expectedContentType + 'with observed-timestamp JSON' | '2021-03-03T23:59:59.999-0400' | MediaType.APPLICATION_JSON | requestBodyJson | expectedJsonData | ContentType.JSON + 'with observed-timestamp XML' | '2021-03-03T23:59:59.999-0400' | MediaType.APPLICATION_XML | requestBodyXml | expectedXmlData | ContentType.XML + 'without observed-timestamp JSON' | null | MediaType.APPLICATION_JSON | requestBodyJson | expectedJsonData | ContentType.JSON + 'without observed-timestamp XML' | null | MediaType.APPLICATION_XML | requestBodyXml | expectedXmlData | ContentType.XML } def 'Save list elements #scenario.'() { @@ -160,7 +177,7 @@ class DataRestControllerSpec extends Specification { def postRequestBuilder = post("$dataNodeBaseEndpoint/anchors/$anchorName/list-nodes") .contentType(MediaType.APPLICATION_JSON) .param('xpath', parentNodeXpath) - .content(requestBody) + .content(requestBodyJson) if (observedTimestamp != null) postRequestBuilder.param('observed-timestamp', observedTimestamp) def response = mvc.perform(postRequestBuilder).andReturn().response @@ -228,7 +245,7 @@ class DataRestControllerSpec extends Specification { mvc.perform( patch(endpoint) .contentType(MediaType.APPLICATION_JSON) - .content(requestBody) + .content(requestBodyJson) .param('xpath', inputXpath) ).andReturn().response then: 'the service method is invoked with expected parameters' @@ -250,7 +267,7 @@ class DataRestControllerSpec extends Specification { mvc.perform( patch(endpoint) .contentType(MediaType.APPLICATION_JSON) - .content(requestBody) + .content(requestBodyJson) .param('xpath', '/') .param('observed-timestamp', observedTimestamp) ).andReturn().response @@ -273,7 +290,7 @@ class DataRestControllerSpec extends Specification { mvc.perform( put(endpoint) .contentType(MediaType.APPLICATION_JSON) - .content(requestBody) + .content(requestBodyJson) .param('xpath', inputXpath)) .andReturn().response then: 'the service method is invoked with expected parameters' @@ -295,7 +312,7 @@ class DataRestControllerSpec extends Specification { mvc.perform( put(endpoint) .contentType(MediaType.APPLICATION_JSON) - .content(requestBody) + .content(requestBodyJson) .param('xpath', '') .param('observed-timestamp', observedTimestamp)) .andReturn().response @@ -315,7 +332,7 @@ class DataRestControllerSpec extends Specification { def putRequestBuilder = put("$dataNodeBaseEndpoint/anchors/$anchorName/list-nodes") .contentType(MediaType.APPLICATION_JSON) .param('xpath', 'parent xpath') - .content(requestBody) + .content(requestBodyJson) if (observedTimestamp != null) putRequestBuilder.param('observed-timestamp', observedTimestamp) def response = mvc.perform(putRequestBuilder).andReturn().response diff --git a/cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy b/cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy index ece3507f2..0821b6beb 100644 --- a/cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy +++ b/cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy @@ -4,6 +4,7 @@ * Modifications Copyright (C) 2021-2022 Nordix Foundation * Modifications Copyright (C) 2021 Bell Canada. * Modifications Copyright (C) 2022 TechMahindra Ltd. + * Modifications Copyright (C) 2022 Deutsche Telekom AG * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -167,13 +168,13 @@ class CpsRestExceptionHandlerSpec extends Specification { def 'Post request with #exceptionThrown.class.simpleName returns HTTP Status Bad Request.'() { given: '#exception is thrown the service indicating data is not found' - mockCpsDataService.saveData(_, _, _, _, _) >> { throw exceptionThrown } + mockCpsDataService.saveData(*_) >> { throw exceptionThrown } when: 'data update request is performed' def response = mvc.perform( post("$basePath/v1/dataspaces/dataspace-name/anchors/anchor-name/nodes") .contentType(MediaType.APPLICATION_JSON) .param('xpath', 'parent node xpath') - .content(groovy.json.JsonOutput.toJson('{"some-key" : "some-value"}')) + .content('{"some-key" : "some-value"}') ).andReturn().response then: 'response code indicates bad input parameters' response.status == BAD_REQUEST.value() @@ -181,18 +182,6 @@ class CpsRestExceptionHandlerSpec extends Specification { exceptionThrown << [new DataNodeNotFoundException('', ''), new NotFoundInDataspaceException('', '')] } - def 'Post request with invalid JSON payload returns HTTP Status Bad Request.'() { - when: 'data post request is performed' - def response = mvc.perform( - post("$basePath/v1/dataspaces/dataspace-name/anchors/anchor-name/nodes") - .contentType(MediaType.APPLICATION_JSON) - .param('xpath', 'parent node xpath') - .content('{') - ).andReturn().response - then: 'response code indicates bad input parameters' - response.status == BAD_REQUEST.value() - } - /* * NB. The test uses 'get anchors' endpoint and associated service method invocation * to test the exception handling. The endpoint chosen is not a subject of test. -- cgit 1.2.3-korg