X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=integration-test%2Fsrc%2Ftest%2Fgroovy%2Forg%2Fonap%2Fcps%2Fintegration%2Ffunctional%2FCpsDataServiceIntegrationSpec.groovy;h=bf86e13c874f058cf4d86a0663688be444c2f260;hb=872a5a063378c878ec49e50c23e50df7a370cd1a;hp=f609ba00e0c8ad3d2763c8a733936d28b5d2fb99;hpb=36d6e83473846cd4e0ad5e42ad6a8d0e3e3b3425;p=cps.git diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy index f609ba00e..bf86e13c8 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy @@ -24,12 +24,23 @@ package org.onap.cps.integration.functional import org.onap.cps.api.CpsDataService import org.onap.cps.integration.base.FunctionalSpecBase import org.onap.cps.spi.FetchDescendantsOption +import org.onap.cps.spi.exceptions.AnchorNotFoundException +import org.onap.cps.spi.exceptions.DataValidationException +import org.onap.cps.spi.exceptions.DataspaceNotFoundException + +import java.time.OffsetDateTime + +import java.time.OffsetDateTime class CpsDataServiceIntegrationSpec extends FunctionalSpecBase { CpsDataService objectUnderTest + def originalCountBookstoreChildNodes - def setup() { objectUnderTest = cpsDataService } + def setup() { + objectUnderTest = cpsDataService + originalCountBookstoreChildNodes = countDataNodesInTree(objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore', FetchDescendantsOption.DIRECT_CHILDREN_ONLY)) + } def 'Read bookstore top-level container(s) using #fetchDescendantsOption.'() { when: 'get data nodes for bookstore container' @@ -38,6 +49,10 @@ class CpsDataServiceIntegrationSpec extends FunctionalSpecBase { assert countDataNodesInTree(result) == expectNumberOfDataNodes and: 'the top level data node has the expected attribute and value' assert result.leaves['bookstore-name'] == ['Easons'] + and: 'they are from the correct dataspace' + assert result.dataspace == [FUNCTIONAL_TEST_DATASPACE_1] + and: 'they are from the correct anchor' + assert result.anchorName == [BOOKSTORE_ANCHOR_1] where: 'the following option is used' fetchDescendantsOption || expectNumberOfDataNodes FetchDescendantsOption.OMIT_DESCENDANTS || 1 @@ -46,13 +61,83 @@ class CpsDataServiceIntegrationSpec extends FunctionalSpecBase { new FetchDescendantsOption(2) || 17 } - def 'Read bookstore top-level container(s) has correct dataspace and anchor.'() { - when: 'get data nodes for bookstore container' - def result = objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) - then: 'the correct dataspace was queried' - assert result.dataspace.toSet() == [FUNCTIONAL_TEST_DATASPACE_1].toSet() - and: 'the correct anchor was queried' - assert result.anchorName.toSet() == [BOOKSTORE_ANCHOR_1].toSet() + def 'Add and Delete a (container) datanode.'() { + given: 'new (webinfo) datanode' + def json = '{"webinfo": {"domain-name":"ourbookstore.com" ,"contact-email":"info@ourbookstore.com" }}' + when: 'the new datanode is saved' + objectUnderTest.saveData(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1 , '/bookstore', json, OffsetDateTime.now()) + then: 'it can be retrieved by its xpath' + def result = objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore/webinfo', FetchDescendantsOption.DIRECT_CHILDREN_ONLY) + assert result.size() == 1 + assert result[0].xpath == '/bookstore/webinfo' + and: 'there is now one extra datanode' + assert originalCountBookstoreChildNodes + 1 == countDataNodesInTree(objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore', FetchDescendantsOption.DIRECT_CHILDREN_ONLY)) + when: 'the new datanode is deleted' + objectUnderTest.deleteDataNode(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore/webinfo', OffsetDateTime.now()) + then: 'the original number of datanodes is restored' + assert originalCountBookstoreChildNodes == countDataNodesInTree(objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore', FetchDescendantsOption.DIRECT_CHILDREN_ONLY)) + } + + def 'Add and Delete list (element) datanodes.'() { + given: 'two new (categories) datanodes' + def json = '{"categories": [ {"code":"new1"}, {"code":"new2" } ] }' + when: 'the new list elements are saved' + objectUnderTest.saveListElements(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1 , '/bookstore', json, OffsetDateTime.now()) + then: 'they can be retrieved by their xpaths' + objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore/categories[@code="new1"]', FetchDescendantsOption.DIRECT_CHILDREN_ONLY).size() == 1 + objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore/categories[@code="new2"]', FetchDescendantsOption.DIRECT_CHILDREN_ONLY).size() == 1 + and: 'there are now two extra datanodes' + assert originalCountBookstoreChildNodes + 2 == countDataNodesInTree(objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore', FetchDescendantsOption.DIRECT_CHILDREN_ONLY)) + when: 'the new elements are deleted' + objectUnderTest.deleteDataNode(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore/categories[@code="new1"]', OffsetDateTime.now()) + objectUnderTest.deleteDataNode(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore/categories[@code="new2"]', OffsetDateTime.now()) + then: 'the original number of datanodes is restored' + assert originalCountBookstoreChildNodes == countDataNodesInTree(objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore', FetchDescendantsOption.DIRECT_CHILDREN_ONLY)) } + def 'Add and Delete a batch of lists (element) datanodes.'() { + given: 'two new (categories) datanodes in two separate batches' + def json1 = '{"categories": [ {"code":"new1"} ] }' + def json2 = '{"categories": [ {"code":"new2"} ] }' + when: 'the batches of new list element(s) are saved' + objectUnderTest.saveListElementsBatch(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1 , '/bookstore', [json1, json2], OffsetDateTime.now()) + then: 'they can be retrieved by their xpaths' + objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore/categories[@code="new1"]', FetchDescendantsOption.DIRECT_CHILDREN_ONLY).size() == 1 + objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore/categories[@code="new2"]', FetchDescendantsOption.DIRECT_CHILDREN_ONLY).size() == 1 + and: 'there are now two extra datanodes' + assert originalCountBookstoreChildNodes + 2 == countDataNodesInTree(objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore', FetchDescendantsOption.DIRECT_CHILDREN_ONLY)) + when: 'the new elements are deleted' + objectUnderTest.deleteDataNode(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore/categories[@code="new1"]', OffsetDateTime.now()) + objectUnderTest.deleteDataNode(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore/categories[@code="new2"]', OffsetDateTime.now()) + then: 'the original number of datanodes is restored' + assert originalCountBookstoreChildNodes == countDataNodesInTree(objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore', FetchDescendantsOption.DIRECT_CHILDREN_ONLY)) + } + + def 'Update multiple data node leaves.'() { + given: 'Updated json for bookstore data' + def jsonData = "{'book-store:books':{'lang':'English/French','price':100,'title':'Matilda','authors':['RoaldDahl']}}" + when: 'update is performed for leaves' + objectUnderTest.updateNodeLeaves(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_FOR_PATCH, "/bookstore/categories[@code='1']", jsonData, OffsetDateTime.now()) + then: 'the updated data nodes are retrieved' + def result = cpsDataService.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_FOR_PATCH, "/bookstore/categories[@code=1]/books[@title='Matilda']", FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) + and: 'the leaf values are updated as expected' + assert result.leaves['lang'] == ['English/French'] + assert result.leaves['price'] == [100] + } + + def 'Update multiple data leaves error scenario: #scenario.'() { + given: 'Updated json for bookstore data' + def jsonData = "{'book-store:books':{'lang':'English/French','price':100,'title':'Matilda','authors':['RoaldDahl'],'pub_year':1988}}" + when: 'attempt to update data node for #scenario' + objectUnderTest.updateNodeLeaves(dataspaceName, anchorName, xpath, jsonData, OffsetDateTime.now()) + then: 'a #expectedException is thrown' + thrown(expectedException) + where: 'the following data is used' + scenario | dataspaceName | anchorName | xpath || expectedException + 'invalid dataspace name' | 'INVALID DATAsPACE' | 'not-relevant' | '/not relevant' || DataValidationException + 'invalid anchor name' | FUNCTIONAL_TEST_DATASPACE_1 | 'INVALID ANCHOR' | '/not relevant' || DataValidationException + 'non-existing dataspace' | 'non-existing-dataspace' | 'not-relevant' | '/not relevant' || DataspaceNotFoundException + 'non-existing anchor' | FUNCTIONAL_TEST_DATASPACE_1 | 'non-existing-anchor' | '/not relevant' || AnchorNotFoundException + 'non-existing-xpath' | FUNCTIONAL_TEST_DATASPACE_1 | BOOKSTORE_ANCHOR_FOR_PATCH | '/non-existing' || DataValidationException + } }