Add support for delete data-node event
[cps.git] / cps-service / src / test / groovy / org / onap / cps / notification / CpsDataUpdateEventFactorySpec.groovy
1 /*
2  * ============LICENSE_START=======================================================
3  * Copyright (c) 2021-2022 Bell Canada.
4  *  ================================================================================
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *  SPDX-License-Identifier: Apache-2.0
18  *  ============LICENSE_END=========================================================
19  */
20
21 package org.onap.cps.notification
22
23 import java.time.OffsetDateTime
24 import java.time.format.DateTimeFormatter
25 import org.onap.cps.utils.DateTimeUtility
26 import org.onap.cps.api.CpsAdminService
27 import org.onap.cps.api.CpsDataService
28 import org.onap.cps.event.model.Content
29 import org.onap.cps.event.model.Data
30 import org.onap.cps.spi.FetchDescendantsOption
31 import org.onap.cps.spi.model.Anchor
32 import org.onap.cps.spi.model.DataNodeBuilder
33 import org.springframework.util.StringUtils
34 import spock.lang.Specification
35
36 class CpsDataUpdateEventFactorySpec extends Specification {
37
38     def mockCpsDataService = Mock(CpsDataService)
39
40     def objectUnderTest = new CpsDataUpdatedEventFactory(mockCpsDataService)
41
42     def dateTimeFormat = 'yyyy-MM-dd\'T\'HH:mm:ss.SSSZ'
43
44     def 'Create a CPS data updated event successfully: #scenario'() {
45         given: 'an anchor which has been updated'
46             def anchor = new Anchor('my-anchorname', 'my-dataspace', 'my-schemaset-name')
47         and: 'cps data service returns the data node details'
48             def xpath = '/'
49             def dataNode = new DataNodeBuilder().withXpath(xpath).withLeaves(['leafName': 'leafValue']).build()
50             mockCpsDataService.getDataNode(
51                 'my-dataspace', 'my-anchorname', xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
52         when: 'CPS data updated event is created'
53             def cpsDataUpdatedEvent = objectUnderTest.createCpsDataUpdatedEvent(anchor,
54                     DateTimeUtility.toOffsetDateTime(inputObservedTimestamp), Operation.CREATE)
55         then: 'CPS data updated event is created with correct envelope'
56             with(cpsDataUpdatedEvent) {
57                 type == 'org.onap.cps.data-updated-event'
58                 source == new URI('urn:cps:org.onap.cps')
59                 schema == new URI('urn:cps:org.onap.cps:data-updated-event-schema:v1')
60                 StringUtils.hasText(id)
61                 content != null
62             }
63         and: 'correct content'
64             with(cpsDataUpdatedEvent.content) {
65                 assert isExpectedDateTimeFormat(observedTimestamp): "$observedTimestamp is not in $dateTimeFormat format"
66                 if (inputObservedTimestamp != null)
67                     assert observedTimestamp == inputObservedTimestamp
68                 else
69                     assert OffsetDateTime.now().minusSeconds(20).isBefore(
70                             DateTimeUtility.toOffsetDateTime(observedTimestamp))
71                 assert anchorName == 'my-anchorname'
72                 assert dataspaceName == 'my-dataspace'
73                 assert schemaSetName == 'my-schemaset-name'
74                 assert operation == Content.Operation.CREATE
75                 assert data == new Data().withAdditionalProperty('leafName', 'leafValue')
76             }
77         where:
78             scenario                        | inputObservedTimestamp
79             'with observed timestamp -0400' | '2021-01-01T23:00:00.345-0400'
80             'with observed timestamp +0400' | '2021-01-01T23:00:00.345+0400'
81             'missing observed timestamp'    | null
82     }
83
84     def 'Create a delete CPS data updated event successfully'() {
85         given: 'an anchor which has been deleted'
86             def anchor = new Anchor('my-anchorname', 'my-dataspace', 'my-schemaset-name')
87             def deletionTimestamp = '2021-01-01T23:00:00.345-0400'
88         when: 'a delete root data node event is created'
89             def cpsDataUpdatedEvent = objectUnderTest.createCpsDataUpdatedEvent(anchor,
90                     DateTimeUtility.toOffsetDateTime(deletionTimestamp), Operation.DELETE)
91         then: 'CPS data updated event is created with correct envelope'
92             with(cpsDataUpdatedEvent) {
93                 type == 'org.onap.cps.data-updated-event'
94                 source == new URI('urn:cps:org.onap.cps')
95                 schema == new URI('urn:cps:org.onap.cps:data-updated-event-schema:v1')
96                 StringUtils.hasText(id)
97                 content != null
98             }
99         and: 'correct content'
100             with(cpsDataUpdatedEvent.content) {
101                 assert isExpectedDateTimeFormat(observedTimestamp): "$observedTimestamp is not in $dateTimeFormat format"
102                 assert observedTimestamp == deletionTimestamp
103                 assert anchorName == 'my-anchorname'
104                 assert dataspaceName == 'my-dataspace'
105                 assert schemaSetName == 'my-schemaset-name'
106                 assert operation == Content.Operation.DELETE
107                 assert data == null
108             }
109     }
110
111     def isExpectedDateTimeFormat(String observedTimestamp) {
112         try {
113             DateTimeFormatter.ofPattern(dateTimeFormat).parse(observedTimestamp)
114         } catch (DateTimeParseException) {
115             return false
116         }
117         return true
118     }
119
120 }