Persisting a list element to a parent list (ep2)
Post List Element does not allow for create List Element, only appends onto existing node as children
-Add a check in saveListElements to see if the parent xpath is a root path ("/").If root node store list element as top node. Else add passed list element to parent xpath node.
-Add test for scenario for above
-Add test scenario Saving list element data fragment under Root node
-Add Integration Tests Add and Delete top-level list (element) data nodes with root node
-Update bookstore model with TopLevelList datanode
Issue-ID: CPS-1586
Change-Id: Iaa7f59fbeebb03703626132c6d5c2afde0e7ab4b
Signed-off-by: Rudrangi Anupriya <ra00745022@techmahindra.com>
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
index db86640..ba43849 100644
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
@@ -110,6 +110,28 @@
noExceptionThrown()
}
+ def 'Saving list element data fragment under Root node.'() {
+ given: 'schema set for given anchor and dataspace references bookstore model'
+ setupSchemaSetMocks('bookstore.yang')
+ when: 'save data method is invoked with list element json data'
+ def jsonData = '{"multiple-data-tree:invoice": [{"ProductID": "2","ProductName": "Banana","price": "100","stock": True}]}'
+ objectUnderTest.saveListElements(dataspaceName, anchorName, '/', jsonData, observedTimestamp)
+ then: 'the persistence service method is invoked with correct parameters'
+ 1 * mockCpsDataPersistenceService.storeDataNodes(dataspaceName, anchorName,
+ { dataNodeCollection ->
+ {
+ assert dataNodeCollection.size() == 1
+ assert dataNodeCollection.collect { it.getXpath() }
+ .containsAll(['/invoice[@ProductID=\'2\']'])
+ }
+ }
+ )
+ and: 'the CpsValidator is called on the dataspaceName and AnchorName'
+ 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName)
+ and: 'data updated event is sent to notification service'
+ 1 * mockNotificationService.processDataUpdatedEvent(anchor, '/', Operation.UPDATE, observedTimestamp)
+ }
+
def 'Saving child data fragment under existing node.'() {
given: 'schema set for given anchor and dataspace references test-tree model'
setupSchemaSetMocks('test-tree.yang')
diff --git a/cps-service/src/test/resources/bookstore.json b/cps-service/src/test/resources/bookstore.json
index 459908b..4b8ed3d 100644
--- a/cps-service/src/test/resources/bookstore.json
+++ b/cps-service/src/test/resources/bookstore.json
@@ -1,4 +1,12 @@
{
+ "multiple-data-tree:invoice": [
+ {
+ "ProductID": "1",
+ "ProductName": "Apple",
+ "price": "100",
+ "stock": false
+ }
+ ],
"test:bookstore":{
"bookstore-name": "Chapters/Easons",
"categories": [
diff --git a/cps-service/src/test/resources/bookstore.yang b/cps-service/src/test/resources/bookstore.yang
index 2179fb9..b7a52e2 100644
--- a/cps-service/src/test/resources/bookstore.yang
+++ b/cps-service/src/test/resources/bookstore.yang
@@ -15,6 +15,34 @@
}
}
+ list invoice {
+ key "ProductID";
+ leaf ProductID {
+ type uint64;
+ mandatory "true";
+ description
+ "Unique product ID. Example: 001";
+ }
+ leaf ProductName {
+ type string;
+ mandatory "true";
+ description
+ "Name of the Product";
+ }
+ leaf price {
+ type uint64;
+ mandatory "true";
+ description
+ "Price of book";
+ }
+ leaf stock {
+ type boolean;
+ default "false";
+ description
+ "Book in stock or not. Example value: true";
+ }
+ }
+
container bookstore {
leaf bookstore-name {