dev.azure.com/aidainnovazione0090/DeviceManager/_git/go-mod-core-contracts@v1.0.2/dtos/requests/event_test.go (about) 1 // 2 // Copyright (C) 2020-2021 IOTech Ltd 3 // 4 // SPDX-License-Identifier: Apache-2.0 5 6 package requests 7 8 import ( 9 "encoding/json" 10 "fmt" 11 "strconv" 12 "testing" 13 14 "dev.azure.com/aidainnovazione0090/DeviceManager/_git/go-mod-core-contracts/common" 15 "dev.azure.com/aidainnovazione0090/DeviceManager/_git/go-mod-core-contracts/dtos" 16 "dev.azure.com/aidainnovazione0090/DeviceManager/_git/go-mod-core-contracts/models" 17 "github.com/fxamacker/cbor/v2" 18 19 "github.com/stretchr/testify/assert" 20 "github.com/stretchr/testify/require" 21 ) 22 23 func eventData() dtos.Event { 24 event := dtos.NewEvent(TestDeviceProfileName, TestDeviceName, TestSourceName) 25 event.Id = ExampleUUID 26 event.Origin = TestOriginTime 27 event.Tags = map[string]interface{}{ 28 "GatewayId": "Houston-0001", 29 } 30 value, _ := strconv.ParseUint(TestReadingValue, 10, 8) 31 _ = event.AddSimpleReading(TestDeviceResourceName, common.ValueTypeUint8, uint8(value)) 32 event.Readings[0].Id = ExampleUUID 33 event.Readings[0].Origin = TestOriginTime 34 35 return event 36 } 37 38 func eventRequestData() AddEventRequest { 39 request := NewAddEventRequest(eventData()) 40 return request 41 } 42 43 func TestAddEventRequest_Validate(t *testing.T) { 44 valid := eventRequestData() 45 noReqId := eventRequestData() 46 noReqId.RequestId = "" 47 invalidReqId := eventRequestData() 48 invalidReqId.RequestId = "xxy" 49 noEventId := eventRequestData() 50 noEventId.Event.Id = "" 51 invalidEventId := eventRequestData() 52 invalidEventId.Event.Id = "gj93j2-v92hvi3h" 53 noDeviceName := eventRequestData() 54 noDeviceName.Event.DeviceName = "" 55 noProfileName := eventRequestData() 56 noProfileName.Event.ProfileName = "" 57 noSourceName := eventRequestData() 58 noSourceName.Event.SourceName = "" 59 noOrigin := eventRequestData() 60 noOrigin.Event.Origin = 0 61 62 noReading := eventRequestData() 63 noReading.Event.Readings = nil 64 65 invalidReadingNoDevice := eventRequestData() 66 invalidReadingNoDevice.Event.Readings[0].DeviceName = "" 67 invalidReadingNoResourceName := eventRequestData() 68 invalidReadingNoResourceName.Event.Readings[0].ResourceName = "" 69 invalidReadingNoProfileName := eventRequestData() 70 invalidReadingNoProfileName.Event.Readings[0].ProfileName = "" 71 invalidReadingNoOrigin := eventRequestData() 72 invalidReadingNoOrigin.Event.Readings[0].Origin = 0 73 74 invalidReadingNoValueType := eventRequestData() 75 invalidReadingNoValueType.Event.Readings[0].ValueType = "" 76 invalidReadingInvalidValueType := eventRequestData() 77 invalidReadingInvalidValueType.Event.Readings[0].ValueType = "BadType" 78 79 invalidSimpleReadingNoValue := eventRequestData() 80 invalidSimpleReadingNoValue.Event.Readings[0].SimpleReading.Value = "" 81 82 invalidBinaryReadingNoValue := eventRequestData() 83 invalidBinaryReadingNoValue.Event.Readings[0].ValueType = common.ValueTypeBinary 84 invalidBinaryReadingNoValue.Event.Readings[0].BinaryReading.MediaType = TestBinaryReadingMediaType 85 invalidBinaryReadingNoValue.Event.Readings[0].BinaryReading.BinaryValue = []byte{} 86 87 invalidBinaryReadingNoMedia := eventRequestData() 88 invalidBinaryReadingNoMedia.Event.Readings[0].ValueType = common.ValueTypeBinary 89 invalidBinaryReadingNoMedia.Event.Readings[0].BinaryReading.MediaType = "" 90 invalidBinaryReadingNoMedia.Event.Readings[0].BinaryReading.BinaryValue = []byte(TestReadingBinaryValue) 91 92 tests := []struct { 93 name string 94 event AddEventRequest 95 expectError bool 96 }{ 97 {"valid AddEventRequest", valid, false}, 98 {"valid AddEventRequest, no Request Id", noReqId, false}, 99 {"invalid AddEventRequest, Request Id is not an uuid", invalidReqId, true}, 100 {"invalid AddEventRequest, no Event Id", noEventId, true}, 101 {"invalid AddEventRequest, Event Id is not an uuid", invalidEventId, true}, 102 {"invalid AddEventRequest, no DeviceName", noDeviceName, true}, 103 {"invalid AddEventRequest, no ProfileName", noProfileName, true}, 104 {"invalid AddEventRequest, no SourceName", noSourceName, true}, 105 {"invalid AddEventRequest, no Origin", noOrigin, true}, 106 {"invalid AddEventRequest, no Reading", noReading, true}, 107 {"invalid AddEventRequest, no Reading DeviceName", invalidReadingNoDevice, true}, 108 {"invalid AddEventRequest, no Resource Name", invalidReadingNoResourceName, true}, 109 {"invalid AddEventRequest, no Profile Name", invalidReadingNoProfileName, true}, 110 {"invalid AddEventRequest, no Reading Origin", invalidReadingNoOrigin, true}, 111 {"invalid AddEventRequest, no Reading ValueType", invalidReadingNoValueType, true}, 112 {"invalid AddEventRequest, invalid Reading ValueType", invalidReadingInvalidValueType, true}, 113 {"invalid AddEventRequest, no SimpleReading Value", invalidSimpleReadingNoValue, true}, 114 {"invalid AddEventRequest, no BinaryReading BinaryValue", invalidBinaryReadingNoValue, true}, 115 {"invalid AddEventRequest, no BinaryReading MediaType", invalidBinaryReadingNoMedia, true}, 116 } 117 for _, tt := range tests { 118 t.Run(tt.name, func(t *testing.T) { 119 err := tt.event.Validate() 120 if tt.expectError { 121 require.Error(t, err) 122 } else { 123 require.NoError(t, err) 124 } 125 }) 126 } 127 128 type testForNameField struct { 129 name string 130 event AddEventRequest 131 expectError bool 132 } 133 134 deviceNameWithUnreservedChar := eventRequestData() 135 deviceNameWithUnreservedChar.Event.DeviceName = nameWithUnreservedChars 136 profileNameWithUnreservedChar := eventRequestData() 137 profileNameWithUnreservedChar.Event.ProfileName = nameWithUnreservedChars 138 sourceNameWithUnreservedChar := eventRequestData() 139 sourceNameWithUnreservedChar.Event.SourceName = nameWithUnreservedChars 140 readingDeviceNameWithUnreservedChar := eventRequestData() 141 readingDeviceNameWithUnreservedChar.Event.Readings[0].DeviceName = nameWithUnreservedChars 142 readingResourceNameWithUnreservedChar := eventRequestData() 143 readingResourceNameWithUnreservedChar.Event.Readings[0].ResourceName = nameWithUnreservedChars 144 readingProfileNameWithUnreservedChar := eventRequestData() 145 readingProfileNameWithUnreservedChar.Event.Readings[0].ProfileName = nameWithUnreservedChars 146 147 // Following tests verify if name fields containing unreserved characters should pass edgex-dto-rfc3986-unreserved-chars check 148 testsForNameFields := []testForNameField{ 149 {"Valid AddEventRequest with device name containing unreserved chars", deviceNameWithUnreservedChar, false}, 150 {"Valid AddEventRequest with profile name containing unreserved chars", profileNameWithUnreservedChar, false}, 151 {"Valid AddEventRequest with source name containing unreserved chars", sourceNameWithUnreservedChar, false}, 152 {"Valid AddEventRequest with reading device name containing unreserved chars", readingDeviceNameWithUnreservedChar, false}, 153 {"Valid AddEventRequest with reading resource name containing unreserved chars", readingResourceNameWithUnreservedChar, false}, 154 {"Valid AddEventRequest with reading profile name containing unreserved chars", readingProfileNameWithUnreservedChar, false}, 155 } 156 157 // Following tests verify if name fields containing reserved characters should be detected with an error 158 for _, n := range namesWithReservedChar { 159 deviceNameWithReservedChar := eventRequestData() 160 deviceNameWithReservedChar.Event.DeviceName = n 161 profileNameWithReservedChar := eventRequestData() 162 profileNameWithReservedChar.Event.ProfileName = n 163 sourceNameWithReservedChar := eventRequestData() 164 sourceNameWithReservedChar.Event.SourceName = n 165 readingDeviceNameWithReservedChar := eventRequestData() 166 readingDeviceNameWithReservedChar.Event.Readings[0].DeviceName = n 167 readingResourceNameWithReservedChar := eventRequestData() 168 readingResourceNameWithReservedChar.Event.Readings[0].ResourceName = n 169 readingProfileNameWithReservedChar := eventRequestData() 170 readingProfileNameWithReservedChar.Event.Readings[0].ProfileName = n 171 172 testsForNameFields = append(testsForNameFields, 173 testForNameField{"Valid AddEventRequest with device name containing reserved char", deviceNameWithReservedChar, false}, 174 testForNameField{"Valid AddEventRequest with profile name containing reserved char", profileNameWithReservedChar, false}, 175 testForNameField{"Valid AddEventRequest with source name containing reserved char", sourceNameWithReservedChar, false}, 176 testForNameField{"Valid AddEventRequest with reading device name containing reserved char", readingDeviceNameWithReservedChar, false}, 177 testForNameField{"Valid AddEventRequest with reading resource name containing reserved char", readingResourceNameWithReservedChar, false}, 178 testForNameField{"Valid AddEventRequest with reading profile name containing reserved char", readingProfileNameWithReservedChar, false}, 179 ) 180 } 181 182 for _, tt := range testsForNameFields { 183 t.Run(tt.name, func(t *testing.T) { 184 err := tt.event.Validate() 185 if tt.expectError { 186 assert.Error(t, err, fmt.Sprintf("expect error but not : %s", tt.name)) 187 } else { 188 assert.NoError(t, err, fmt.Sprintf("unexpected error occurs : %s", tt.name)) 189 } 190 }) 191 } 192 } 193 194 func TestAddEvent_UnmarshalJSON(t *testing.T) { 195 expected := eventRequestData() 196 expected.RequestId = ExampleUUID 197 validData, err := json.Marshal(expected) 198 require.NoError(t, err) 199 200 validValueTypeLowerCase := eventRequestData() 201 validValueTypeLowerCase.RequestId = ExampleUUID 202 validValueTypeLowerCase.Event.Readings[0].ValueType = "uint8" 203 validValueTypeLowerCaseData, err := json.Marshal(validValueTypeLowerCase) 204 require.NoError(t, err) 205 206 validValueTypeUpperCase := eventRequestData() 207 validValueTypeUpperCase.RequestId = ExampleUUID 208 validValueTypeUpperCase.Event.Readings[0].ValueType = "UINT8" 209 validValueTypeUpperCaseData, err := json.Marshal(validValueTypeUpperCase) 210 require.NoError(t, err) 211 212 tests := []struct { 213 name string 214 data []byte 215 wantErr bool 216 }{ 217 {"unmarshal AddEventRequest with success", validData, false}, 218 {"unmarshal AddEventRequest with success, valid value type uint8", validValueTypeLowerCaseData, false}, 219 {"unmarshal AddEventRequest with success, valid value type UINT8", validValueTypeUpperCaseData, false}, 220 {"unmarshal invalid AddEventRequest, empty data", []byte{}, true}, 221 {"unmarshal invalid AddEventRequest, string data", []byte("Invalid AddEventRequest"), true}, 222 } 223 224 for _, tt := range tests { 225 t.Run(tt.name, func(t *testing.T) { 226 var addEvent AddEventRequest 227 err := addEvent.UnmarshalJSON(tt.data) 228 if tt.wantErr { 229 require.Error(t, err) 230 } else { 231 require.NoError(t, err) 232 assert.Equal(t, expected, addEvent, "Unmarshal did not result in expected AddEventRequest.") 233 } 234 }) 235 } 236 } 237 238 func TestAddEvent_UnmarshalCBOR(t *testing.T) { 239 expected := eventRequestData() 240 expected.RequestId = ExampleUUID 241 validData, err := cbor.Marshal(expected) 242 require.NoError(t, err) 243 244 validValueTypeLowerCase := eventRequestData() 245 validValueTypeLowerCase.RequestId = ExampleUUID 246 validValueTypeLowerCase.Event.Readings[0].ValueType = "uint8" 247 validValueTypeLowerCaseData, err := cbor.Marshal(validValueTypeLowerCase) 248 require.NoError(t, err) 249 250 validValueTypeUpperCase := eventRequestData() 251 validValueTypeUpperCase.RequestId = ExampleUUID 252 validValueTypeUpperCase.Event.Readings[0].ValueType = "UINT8" 253 validValueTypeUpperCaseData, err := cbor.Marshal(validValueTypeUpperCase) 254 require.NoError(t, err) 255 256 tests := []struct { 257 name string 258 data []byte 259 wantErr bool 260 }{ 261 {"unmarshal AddEventRequest with success", validData, false}, 262 {"unmarshal AddEventRequest with success, valid value type uint8", validValueTypeLowerCaseData, false}, 263 {"unmarshal AddEventRequest with success, valid value type UINT8", validValueTypeUpperCaseData, false}, 264 {"unmarshal invalid AddEventRequest, empty data", []byte{}, true}, 265 {"unmarshal invalid AddEventRequest, string data", []byte("Invalid AddEventRequest"), true}, 266 } 267 268 for _, tt := range tests { 269 t.Run(tt.name, func(t *testing.T) { 270 var addEvent AddEventRequest 271 err := addEvent.UnmarshalCBOR(tt.data) 272 if tt.wantErr { 273 require.Error(t, err) 274 } else { 275 require.NoError(t, err) 276 assert.Equal(t, expected, addEvent, "Unmarshal did not result in expected AddEventRequest.") 277 } 278 }) 279 } 280 } 281 282 func Test_AddEventReqToEventModels(t *testing.T) { 283 valid := eventRequestData() 284 s := models.SimpleReading{ 285 BaseReading: models.BaseReading{ 286 Id: ExampleUUID, 287 DeviceName: TestDeviceName, 288 ResourceName: TestDeviceResourceName, 289 ProfileName: TestDeviceProfileName, 290 Origin: TestOriginTime, 291 ValueType: common.ValueTypeUint8, 292 }, 293 Value: TestReadingValue, 294 } 295 expectedEventModel := models.Event{ 296 Id: ExampleUUID, 297 DeviceName: TestDeviceName, 298 ProfileName: TestDeviceProfileName, 299 SourceName: TestSourceName, 300 Origin: TestOriginTime, 301 Readings: []models.Reading{s}, 302 Tags: map[string]interface{}{ 303 "GatewayId": "Houston-0001", 304 }, 305 } 306 307 tests := []struct { 308 name string 309 addEventReq AddEventRequest 310 }{ 311 {"valid AddEventRequest", valid}, 312 } 313 for _, tt := range tests { 314 t.Run(tt.name, func(t *testing.T) { 315 eventModel := AddEventReqToEventModel(tt.addEventReq) 316 assert.Equal(t, expectedEventModel, eventModel, "AddEventReqToEventModel did not result in expected Event model.") 317 }) 318 } 319 } 320 321 func TestNewAddEventRequest(t *testing.T) { 322 expectedProfileName := TestDeviceProfileName 323 expectedDeviceName := TestDeviceName 324 expectedSourceName := TestSourceName 325 expectedApiVersion := common.ApiVersion 326 327 actual := NewAddEventRequest(eventData()) 328 329 assert.Equal(t, expectedApiVersion, actual.ApiVersion) 330 assert.NotEmpty(t, actual.RequestId) 331 assert.Equal(t, expectedApiVersion, actual.Event.ApiVersion) 332 assert.NotEmpty(t, actual.Event.Id) 333 assert.Equal(t, expectedProfileName, actual.Event.ProfileName) 334 assert.Equal(t, expectedDeviceName, actual.Event.DeviceName) 335 assert.Equal(t, expectedSourceName, actual.Event.SourceName) 336 assert.NotZero(t, len(actual.Event.Readings)) 337 assert.NotZero(t, actual.Event.Origin) 338 }