Bug fix for delete data node not working for root node
[cps.git] / cps-service / src / test / groovy / org / onap / cps / notification / NotificationServiceSpec.groovy
index ab72767..6ef6874 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * ============LICENSE_START=======================================================
- *  Copyright (c) 2021 Bell Canada.
+ *  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.
 
 package org.onap.cps.notification
 
+import java.time.OffsetDateTime
 import org.onap.cps.config.AsyncConfig
 import org.onap.cps.event.model.CpsDataUpdatedEvent
+import org.onap.cps.spi.model.Anchor
 import org.spockframework.spring.SpringBean
 import org.spockframework.spring.SpringSpy
 import org.springframework.beans.factory.annotation.Autowired
@@ -35,7 +37,6 @@ import spock.lang.Specification
 import java.util.concurrent.TimeUnit
 
 @SpringBootTest
-@EnableAsync
 @EnableConfigurationProperties
 @ContextConfiguration(classes = [NotificationProperties, NotificationService, NotificationErrorHandler, AsyncConfig])
 class NotificationServiceSpec extends Specification {
@@ -53,14 +54,14 @@ class NotificationServiceSpec extends Specification {
     NotificationService objectUnderTest
 
     @Shared
-    def myDataspacePublishedName = 'my-dataspace-published'
-    def myAnchorName = 'my-anchorname'
+    def anchor = new Anchor('my-anchorname', 'my-dataspace-published', 'my-schemaset-name')
+    def myObservedTimestamp = OffsetDateTime.now()
 
     def 'Skip sending notification when disabled.'() {
         given: 'notification is disabled'
             spyNotificationProperties.isEnabled() >> false
         when: 'dataUpdatedEvent is received'
-            objectUnderTest.processDataUpdatedEvent(myDataspacePublishedName, myAnchorName)
+            objectUnderTest.processDataUpdatedEvent(anchor, myObservedTimestamp, '/', Operation.CREATE)
         then: 'the notification is not sent'
             0 * mockNotificationPublisher.sendNotification(_)
     }
@@ -68,12 +69,16 @@ class NotificationServiceSpec extends Specification {
     def 'Send notification when enabled: #scenario.'() {
         given: 'notification is enabled'
             spyNotificationProperties.isEnabled() >> true
+        and: 'an anchor is in dataspace where #scenario'
+            def anchor = new Anchor('my-anchorname', dataspaceName, 'my-schemaset-name')
         and: 'event factory can create event successfully'
             def cpsDataUpdatedEvent = new CpsDataUpdatedEvent()
-            mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(dataspaceName, myAnchorName) >> cpsDataUpdatedEvent
+            mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(anchor, myObservedTimestamp, Operation.CREATE) >>
+                    cpsDataUpdatedEvent
         when: 'dataUpdatedEvent is received'
-            def future = objectUnderTest.processDataUpdatedEvent(dataspaceName, myAnchorName)
-        and: 'wait for async processing is completed'
+            def future = objectUnderTest.processDataUpdatedEvent(anchor, myObservedTimestamp,
+                    '/', Operation.CREATE)
+        and: 'wait for async processing to complete'
             future.get(10, TimeUnit.SECONDS)
         then: 'async process completed successfully'
             future.isDone()
@@ -82,30 +87,54 @@ class NotificationServiceSpec extends Specification {
         where:
             scenario                               | dataspaceName            || expectedSendNotificationCount
             'dataspace name does not match filter' | 'does-not-match-pattern' || 0
-            'dataspace name matches filter'        | myDataspacePublishedName || 1
+            'dataspace name matches filter'        | 'my-dataspace-published' || 1
+    }
+
+    def '#scenario are changed with xpath #xpath and operation #operation'() {
+        given: 'notification is enabled'
+            spyNotificationProperties.isEnabled() >> true
+        and: 'event factory creates event if operation is #operation'
+            def cpsDataUpdatedEvent = new CpsDataUpdatedEvent()
+            mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(anchor, myObservedTimestamp, expectedOperationInEvent) >>
+                    cpsDataUpdatedEvent
+        when: 'dataUpdatedEvent is received for #xpath'
+            def future = objectUnderTest.processDataUpdatedEvent(anchor, myObservedTimestamp, xpath, operation)
+        and: 'wait for async processing to complete'
+            future.get(10, TimeUnit.SECONDS)
+        then: 'async process completed successfully'
+            future.isDone()
+        and: 'notification is sent'
+            1 * mockNotificationPublisher.sendNotification(cpsDataUpdatedEvent)
+        where:
+            scenario                                   | xpath           | operation            || expectedOperationInEvent
+            'Same event is sent when root nodes'       | ''              | Operation.CREATE     || Operation.CREATE
+            'Same event is sent when root nodes'       | ''              | Operation.UPDATE     || Operation.UPDATE
+            'Same event is sent when root nodes'       | ''              | Operation.DELETE     || Operation.DELETE
+            'Same event is sent when root nodes'       | '/'             | Operation.CREATE     || Operation.CREATE
+            'Same event is sent when root nodes'       | '/'             | Operation.UPDATE     || Operation.UPDATE
+            'Same event is sent when root nodes'       | '/'             | Operation.DELETE     || Operation.DELETE
+            'Same event is sent when container nodes'  | '/parent'       | Operation.CREATE     || Operation.CREATE
+            'Same event is sent when container nodes'  | '/parent'       | Operation.UPDATE     || Operation.UPDATE
+            'Same event is sent when container nodes'  | '/parent'       | Operation.DELETE     || Operation.DELETE
+            'UPDATE event is sent when non root nodes' | '/parent/child' | Operation.CREATE     || Operation.UPDATE
+            'UPDATE event is sent when non root nodes' | '/parent/child' | Operation.UPDATE     || Operation.UPDATE
+            'UPDATE event is sent when non root nodes' | '/parent/child' | Operation.DELETE     || Operation.UPDATE
     }
 
     def 'Error handling in notification service.'() {
         given: 'notification is enabled'
             spyNotificationProperties.isEnabled() >> true
         and: 'event factory can not create event successfully'
-            mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(myDataspacePublishedName, myAnchorName) >>
-                { throw new Exception("Could not create event") }
+            mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(anchor, myObservedTimestamp, Operation.CREATE) >>
+                    { throw new Exception("Could not create event") }
         when: 'event is sent for processing'
-            def future = objectUnderTest.processDataUpdatedEvent(myDataspacePublishedName, myAnchorName)
-        and: 'wait for async processing is completed'
+            def future = objectUnderTest.processDataUpdatedEvent(anchor, myObservedTimestamp, '/', Operation.CREATE)
+        and: 'wait for async processing to complete'
             future.get(10, TimeUnit.SECONDS)
         then: 'async process completed successfully'
             future.isDone()
         and: 'error is handled and not thrown to caller'
             notThrown Exception
-            1 * spyNotificationErrorHandler.onException(_, _, _, _)
-    }
-
-    NotificationService createNotificationService(boolean notificationEnabled) {
-        spyNotificationProperties = Spy(notificationProperties)
-        spyNotificationProperties.isEnabled() >> notificationEnabled
-        return new NotificationService(spyNotificationProperties, mockNotificationPublisher,
-            mockCpsDataUpdatedEventFactory, spyNotificationErrorHandler)
+            1 * spyNotificationErrorHandler.onException(_, _, _, '/', Operation.CREATE)
     }
 }