d3a407c5702afd3701dfdee1b2dbb83aa8f24c94
[cps/cps-temporal.git] / src / test / groovy / org / onap / cps / temporal / controller / event / listener / kafka / DataUpdatedEventListenerSpec.groovy
1 /*
2  * ============LICENSE_START=======================================================
3  * Copyright (c) 2021 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  * ============LICENSE_END=========================================================
17  */
18
19 package org.onap.cps.temporal.controller.event.listener.kafka
20
21 import org.mapstruct.factory.Mappers
22 import org.onap.cps.event.model.CpsDataUpdatedEvent
23 import org.onap.cps.temporal.controller.event.listener.exception.InvalidEventEnvelopException
24 import org.onap.cps.temporal.controller.event.model.CpsDataUpdatedEventMapper
25 import org.onap.cps.temporal.service.NetworkDataService
26 import spock.lang.Specification
27
28 import static org.onap.cps.temporal.controller.event.listener.exception.InvalidEventEnvelopException.InvalidField.ErrorType.MISSING
29 import static org.onap.cps.temporal.controller.event.listener.exception.InvalidEventEnvelopException.InvalidField.ErrorType.UNEXPECTED
30
31 /**
32  * Test specification for data updated event listener.
33  */
34 class DataUpdatedEventListenerSpec extends Specification {
35
36     // Define event data
37     def anEventType = 'my-event-type'
38     def anEventSource = new URI('my-event-source')
39     def aTimestamp = EventFixtures.currentIsoTimestamp()
40     def aDataspace = 'my-dataspace'
41     def aSchemaSet = 'my-schema-set'
42     def anAnchor = 'my-anchor'
43     def aDataName = 'my-data-name'
44     def aDataValue = 'my-data-value'
45
46     // Define service mock
47     def mockService = Mock(NetworkDataService)
48
49     // Define mapper
50     def mapper = Mappers.getMapper(CpsDataUpdatedEventMapper.class)
51
52     // Define listener under test
53     def objectUnderTest = new DataUpdatedEventListener(mockService, mapper)
54
55     def 'Event message consumption'() {
56         when: 'an event is received'
57             def event =
58                     EventFixtures.buildEvent(
59                             timestamp: aTimestamp, dataspace: aDataspace, schemaSet: aSchemaSet, anchor: anAnchor,
60                             dataName: aDataName, dataValue: aDataValue)
61             objectUnderTest.consume(event)
62         then: 'network data service is requested to persisted the data change'
63             1 * mockService.addNetworkData(
64                     {
65                         it.getObservedTimestamp() == EventFixtures.toOffsetDateTime(aTimestamp)
66                         && it.getDataspace() == aDataspace
67                         && it.getSchemaSet() == aSchemaSet
68                         && it.getAnchor() == anAnchor
69                         && it.getPayload() == String.format('{"%s":"%s"}', aDataName, aDataValue)
70                         && it.getCreatedTimestamp() == null
71                     }
72             )
73     }
74
75     def 'Event message consumption fails because of missing envelop'() {
76         when: 'an event without envelop information is received'
77             def invalidEvent = new CpsDataUpdatedEvent().withSchema(null)
78             objectUnderTest.consume(invalidEvent)
79         then: 'an exception is thrown with 4 invalid fields'
80             def e = thrown(InvalidEventEnvelopException)
81             e.getInvalidFields().size() == 4
82             e.getInvalidFields().contains(
83                     new InvalidEventEnvelopException.InvalidField(
84                             MISSING,"schema", null,
85                             CpsDataUpdatedEvent.Schema.URN_CPS_ORG_ONAP_CPS_DATA_UPDATED_EVENT_SCHEMA_1_1_0_SNAPSHOT
86                                     .value()))
87             e.getInvalidFields().contains(
88                     new InvalidEventEnvelopException.InvalidField(
89                             MISSING, "id", null, null))
90             e.getInvalidFields().contains(
91                     new InvalidEventEnvelopException.InvalidField(
92                             UNEXPECTED, "source", null, EventFixtures.defaultEventSource.toString()))
93             e.getInvalidFields().contains(
94                     new InvalidEventEnvelopException.InvalidField(
95                             UNEXPECTED, "type", null, EventFixtures.defaultEventType))
96             e.getMessage().contains(e.getInvalidFields().toString())
97     }
98
99     def 'Event message consumption fails because of invalid envelop'() {
100         when: 'an event with an invalid envelop is received'
101             def invalidEvent =
102                     new CpsDataUpdatedEvent()
103                             .withId('my-id').withSource(anEventSource).withType(anEventType)
104             objectUnderTest.consume(invalidEvent)
105         then: 'an exception is thrown with 2 invalid fields'
106             def e = thrown(InvalidEventEnvelopException)
107             e.getInvalidFields().size() == 2
108             e.getInvalidFields().contains(
109                     new InvalidEventEnvelopException.InvalidField(
110                             UNEXPECTED, "type", anEventType, EventFixtures.defaultEventType))
111             e.getInvalidFields().contains(
112                     new InvalidEventEnvelopException.InvalidField(
113                             UNEXPECTED, "source", anEventSource.toString(),
114                             EventFixtures.defaultEventSource.toString()))
115     }
116
117 }