055147fb8c4388d15fe1dbdac76379bd193b9167
[cps/cps-temporal.git] /
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     public static final String EXPECTED_SCHEMA_EXCEPTION_MESSAGE = 'urn:cps:org.onap.cps:data-updated-event-schema:v99'
37
38     // Define event data
39     def anEventType = 'my-event-type'
40     def anEventSchema = new URI('my-event-schema')
41     def anEventSource = new URI('my-event-source')
42     def aTimestamp = EventFixtures.currentIsoTimestamp()
43     def aDataspace = 'my-dataspace'
44     def aSchemaSet = 'my-schema-set'
45     def anAnchor = 'my-anchor'
46     def aDataName = 'my-data-name'
47     def aDataValue = 'my-data-value'
48
49     // Define service mock
50     def mockService = Mock(NetworkDataService)
51
52     // Define mapper
53     def mapper = Mappers.getMapper(CpsDataUpdatedEventMapper.class)
54
55     // Define listener under test
56     def objectUnderTest = new DataUpdatedEventListener(mockService, mapper)
57
58     def 'Event message consumption'() {
59         when: 'an event is received'
60             def event =
61                     EventFixtures.buildEvent(
62                             timestamp: aTimestamp, dataspace: aDataspace, schemaSet: aSchemaSet, anchor: anAnchor,
63                             dataName: aDataName, dataValue: aDataValue)
64             objectUnderTest.consume(event)
65         then: 'network data service is requested to persisted the data change'
66             1 * mockService.addNetworkData(
67                     {
68                         it.getObservedTimestamp() == EventFixtures.toOffsetDateTime(aTimestamp)
69                         && it.getDataspace() == aDataspace
70                         && it.getSchemaSet() == aSchemaSet
71                         && it.getAnchor() == anAnchor
72                         && it.getPayload() == String.format('{"%s":"%s"}', aDataName, aDataValue)
73                         && it.getCreatedTimestamp() == null
74                     }
75             )
76     }
77
78     def 'Event message consumption fails because of missing envelop'() {
79         when: 'an event without envelop information is received'
80             def invalidEvent = new CpsDataUpdatedEvent().withSchema(null)
81             objectUnderTest.consume(invalidEvent)
82         then: 'an exception is thrown with 4 invalid fields'
83             def e = thrown(InvalidEventEnvelopException)
84             e.getCpsDataUpdatedEvent() == invalidEvent
85             e.getInvalidFields().size() == 4
86             e.getInvalidFields().contains(
87                     new InvalidEventEnvelopException.InvalidField(
88                             UNEXPECTED,"schema", null, EXPECTED_SCHEMA_EXCEPTION_MESSAGE))
89             e.getInvalidFields().contains(
90                     new InvalidEventEnvelopException.InvalidField(
91                             MISSING, "id", null, null))
92             e.getInvalidFields().contains(
93                     new InvalidEventEnvelopException.InvalidField(
94                             UNEXPECTED, "source", null, EventFixtures.defaultEventSource.toString()))
95             e.getInvalidFields().contains(
96                     new InvalidEventEnvelopException.InvalidField(
97                             UNEXPECTED, "type", null, EventFixtures.defaultEventType))
98             e.getMessage().contains(e.getInvalidFields().toString())
99     }
100
101     def 'Event message consumption fails because of invalid envelop'() {
102         when: 'an event with an invalid envelop is received'
103             def invalidEvent =
104                     new CpsDataUpdatedEvent()
105                             .withId('my-id')
106                             .withSchema(anEventSchema)
107                             .withSource(anEventSource)
108                             .withType(anEventType)
109             objectUnderTest.consume(invalidEvent)
110         then: 'an exception is thrown with 2 invalid fields'
111             def e = thrown(InvalidEventEnvelopException)
112             e.getCpsDataUpdatedEvent() == invalidEvent
113             e.getInvalidFields().size() == 3
114             e.getInvalidFields().contains(
115                     new InvalidEventEnvelopException.InvalidField(
116                             UNEXPECTED, "schema", anEventSchema.toString(),
117                             EXPECTED_SCHEMA_EXCEPTION_MESSAGE))
118             e.getInvalidFields().contains(
119                     new InvalidEventEnvelopException.InvalidField(
120                             UNEXPECTED, "type", anEventType, EventFixtures.defaultEventType))
121             e.getInvalidFields().contains(
122                     new InvalidEventEnvelopException.InvalidField(
123                             UNEXPECTED, "source", anEventSource.toString(),
124                             EventFixtures.defaultEventSource.toString()))
125     }
126
127 }