dev.azure.com/aidainnovazione0090/DeviceManager/_git/go-mod-core-contracts@v1.0.2/dtos/requests/provisionwatcher_test.go (about) 1 // 2 // Copyright (C) 2021-2023 IOTech Ltd 3 // 4 // SPDX-License-Identifier: Apache-2.0 5 6 package requests 7 8 import ( 9 "encoding/json" 10 "fmt" 11 "testing" 12 13 "github.com/stretchr/testify/assert" 14 "github.com/stretchr/testify/require" 15 16 "dev.azure.com/aidainnovazione0090/DeviceManager/_git/go-mod-core-contracts/dtos" 17 "dev.azure.com/aidainnovazione0090/DeviceManager/_git/go-mod-core-contracts/dtos/common" 18 "dev.azure.com/aidainnovazione0090/DeviceManager/_git/go-mod-core-contracts/models" 19 ) 20 21 var testProvisionWatcherName = "TestWatcher" 22 var testProvisionWatcherLabels = []string{"TEST", "TEMP"} 23 var testIdentifiers = map[string]string{ 24 "address": "localhost", 25 "port": "3[0-9]{2}", 26 } 27 var testBlockingIdentifiers = map[string][]string{ 28 "port": {"397", "398", "399"}, 29 } 30 var testAddProvisionWatcher = AddProvisionWatcherRequest{ 31 BaseRequest: common.BaseRequest{ 32 RequestId: ExampleUUID, 33 Versionable: common.NewVersionable(), 34 }, 35 ProvisionWatcher: dtos.ProvisionWatcher{ 36 Name: testProvisionWatcherName, 37 ServiceName: TestDeviceServiceName, 38 Labels: testProvisionWatcherLabels, 39 Identifiers: testIdentifiers, 40 BlockingIdentifiers: testBlockingIdentifiers, 41 AdminState: models.Locked, 42 DiscoveredDevice: dtos.DiscoveredDevice{ 43 ProfileName: TestDeviceProfileName, 44 AdminState: models.Locked, 45 AutoEvents: testAutoEvents, 46 }, 47 }, 48 } 49 50 var testUpdateProvisionWatcher = UpdateProvisionWatcherRequest{ 51 BaseRequest: common.BaseRequest{ 52 RequestId: ExampleUUID, 53 Versionable: common.NewVersionable(), 54 }, 55 ProvisionWatcher: mockUpdateProvisionWatcher(), 56 } 57 58 func mockUpdateProvisionWatcher() dtos.UpdateProvisionWatcher { 59 testId := ExampleUUID 60 testName := testProvisionWatcherName 61 testAdminState := models.Locked 62 testDeviceServiceName := TestDeviceServiceName 63 testProfileName := TestDeviceProfileName 64 d := dtos.UpdateProvisionWatcher{} 65 d.Id = &testId 66 d.Name = &testName 67 d.ServiceName = &testDeviceServiceName 68 d.Labels = testProvisionWatcherLabels 69 d.Identifiers = testIdentifiers 70 d.BlockingIdentifiers = testBlockingIdentifiers 71 d.AdminState = &testAdminState 72 d.DiscoveredDevice.ProfileName = &testProfileName 73 d.DiscoveredDevice.AdminState = &testAdminState 74 d.DiscoveredDevice.AutoEvents = testAutoEvents 75 return d 76 } 77 78 func TestAddProvisionWatcherRequest_Validate(t *testing.T) { 79 whiteSpace := " " 80 emptyMap := make(map[string]string) 81 valid := testAddProvisionWatcher 82 noReqId := testAddProvisionWatcher 83 noReqId.RequestId = "" 84 invalidReqId := testAddProvisionWatcher 85 invalidReqId.RequestId = "abc" 86 noProvisionWatcherName := testAddProvisionWatcher 87 noProvisionWatcherName.ProvisionWatcher.Name = whiteSpace 88 provisionWatcherNameWithReservedChar := testAddProvisionWatcher 89 provisionWatcherNameWithReservedChar.ProvisionWatcher.Name = namesWithReservedChar[0] 90 noIdentifiers := testAddProvisionWatcher 91 noIdentifiers.ProvisionWatcher.Identifiers = emptyMap 92 missingIdentifiersKey := testAddProvisionWatcher 93 missingIdentifiersKey.ProvisionWatcher.Identifiers = map[string]string{ 94 "": "value", 95 } 96 missingIdentifiersValue := testAddProvisionWatcher 97 missingIdentifiersValue.ProvisionWatcher.Identifiers = map[string]string{ 98 "key": "", 99 } 100 noServiceName := testAddProvisionWatcher 101 noServiceName.ProvisionWatcher.ServiceName = whiteSpace 102 noProfileName := testAddProvisionWatcher 103 noProfileName.ProvisionWatcher.DiscoveredDevice.ProfileName = whiteSpace 104 emptyStringProfileName := testAddProvisionWatcher 105 emptyStringProfileName.ProvisionWatcher.DiscoveredDevice.ProfileName = "" 106 invalidFrequency := testAddProvisionWatcher 107 invalidFrequency.ProvisionWatcher.DiscoveredDevice.AutoEvents = []dtos.AutoEvent{ 108 {SourceName: "TestDevice", Interval: "-1", OnChange: true}, 109 } 110 noAutoEventFrequency := testAddProvisionWatcher 111 noAutoEventFrequency.ProvisionWatcher.DiscoveredDevice.AutoEvents = []dtos.AutoEvent{ 112 {SourceName: "TestDevice", OnChange: true}, 113 } 114 noAutoEventResource := testAddProvisionWatcher 115 noAutoEventResource.ProvisionWatcher.DiscoveredDevice.AutoEvents = []dtos.AutoEvent{ 116 {Interval: "300ms", OnChange: true}, 117 } 118 119 tests := []struct { 120 name string 121 ProvisionWatcher AddProvisionWatcherRequest 122 expectError bool 123 }{ 124 {"valid AddProvisionWatcherRequest", valid, false}, 125 {"valid AddProvisionWatcherRequest, no Request Id", noReqId, false}, 126 {"invalid AddProvisionWatcherRequest, Request Id is not an uuid", invalidReqId, true}, 127 {"invalid AddProvisionWatcherRequest, no ProvisionWatcherName", noProvisionWatcherName, true}, 128 {"valid AddProvisionWatcherRequest, ProvisionWatcherName with reserved chars", provisionWatcherNameWithReservedChar, false}, 129 {"invalid AddProvisionWatcherRequest, no Identifiers", noIdentifiers, true}, 130 {"invalid AddProvisionWatcherRequest, missing Identifiers key", missingIdentifiersKey, true}, 131 {"invalid AddProvisionWatcherRequest, missing Identifiers value", missingIdentifiersValue, true}, 132 {"invalid AddProvisionWatcherRequest, no ServiceName", noServiceName, true}, 133 {"invalid AddProvisionWatcherRequest, no ProfileName", noProfileName, true}, 134 {"invalid AddProvisionWatcherRequest, empty string ProfileName", emptyStringProfileName, false}, 135 {"invalid AddProvisionWatcherRequest, invalid autoEvent frequency", invalidFrequency, true}, 136 {"invalid AddProvisionWatcherRequest, no AutoEvent frequency", noAutoEventFrequency, true}, 137 {"invalid AddProvisionWatcherRequest, no AutoEvent resource", noAutoEventResource, true}, 138 } 139 for _, tt := range tests { 140 t.Run(tt.name, func(t *testing.T) { 141 err := tt.ProvisionWatcher.Validate() 142 assert.Equal(t, tt.expectError, err != nil, "Unexpected addDeviceRequest validation result.", err) 143 }) 144 } 145 } 146 147 func TestAddProvisionWatcherRequest_UnmarshalJSON(t *testing.T) { 148 valid := testAddProvisionWatcher 149 resultTestBytes, _ := json.Marshal(testAddProvisionWatcher) 150 type args struct { 151 data []byte 152 } 153 tests := []struct { 154 name string 155 addProvisionWatcher AddProvisionWatcherRequest 156 args args 157 wantErr bool 158 }{ 159 {"unmarshal AddProvisionWatcherRequest with success", valid, args{resultTestBytes}, false}, 160 {"unmarshal invalid AddProvisionWatcherRequest, empty data", AddProvisionWatcherRequest{}, args{[]byte{}}, true}, 161 {"unmarshal invalid AddProvisionWatcherRequest, string data", AddProvisionWatcherRequest{}, args{[]byte("Invalid AddDeviceRequest")}, true}, 162 } 163 fmt.Println(string(resultTestBytes)) 164 for _, tt := range tests { 165 t.Run(tt.name, func(t *testing.T) { 166 var expected = tt.addProvisionWatcher 167 err := tt.addProvisionWatcher.UnmarshalJSON(tt.args.data) 168 if tt.wantErr { 169 require.Error(t, err) 170 } else { 171 require.NoError(t, err) 172 assert.Equal(t, expected, tt.addProvisionWatcher, "Unmarshal did not result in expected AddProvisionWatcherRequest.") 173 } 174 }) 175 } 176 } 177 178 func TestAddProvisionWatcherReqToProvisionWatcherModels(t *testing.T) { 179 requests := []AddProvisionWatcherRequest{testAddProvisionWatcher} 180 expectedProvisionWatcherModel := []models.ProvisionWatcher{ 181 { 182 Name: testProvisionWatcherName, 183 ServiceName: TestDeviceServiceName, 184 Labels: testProvisionWatcherLabels, 185 Identifiers: map[string]string{ 186 "address": "localhost", 187 "port": "3[0-9]{2}", 188 }, 189 BlockingIdentifiers: map[string][]string{ 190 "port": {"397", "398", "399"}, 191 }, 192 AdminState: models.Locked, 193 DiscoveredDevice: models.DiscoveredDevice{ 194 ProfileName: TestDeviceProfileName, 195 AdminState: models.Locked, 196 AutoEvents: []models.AutoEvent{ 197 {SourceName: "TestDevice", Interval: "300ms", OnChange: true}, 198 }, 199 }, 200 }, 201 } 202 resultModels := AddProvisionWatcherReqToProvisionWatcherModels(requests) 203 assert.Equal(t, expectedProvisionWatcherModel, resultModels, "AddProvisionWatcherReqToProvisionWatcherModels did not result in expected ProvisionWatcher model.") 204 } 205 206 func TestUpdateProvisionWatcherRequest_Validate(t *testing.T) { 207 whiteSpace := " " 208 emptyMap := make(map[string]string) 209 invalidUUID := "invalidUUID" 210 211 valid := testUpdateProvisionWatcher 212 noReqId := valid 213 noReqId.RequestId = "" 214 invalidReqId := valid 215 invalidReqId.RequestId = invalidUUID 216 217 // id 218 validOnlyId := valid 219 validOnlyId.ProvisionWatcher.Name = nil 220 invalidId := valid 221 invalidId.ProvisionWatcher.Id = &invalidUUID 222 // name 223 validOnlyName := valid 224 validOnlyName.ProvisionWatcher.Id = nil 225 nameAndEmptyId := valid 226 nameAndEmptyId.ProvisionWatcher.Id = &whiteSpace 227 invalidEmptyName := valid 228 invalidEmptyName.ProvisionWatcher.Name = &whiteSpace 229 reservedName := valid 230 reservedName.ProvisionWatcher.Name = &namesWithReservedChar[0] 231 // no id and name 232 noIdAndName := valid 233 noIdAndName.ProvisionWatcher.Id = nil 234 noIdAndName.ProvisionWatcher.Name = nil 235 236 validNilIdentifiers := valid 237 validNilIdentifiers.ProvisionWatcher.Identifiers = nil 238 invalidEmptyIdentifiers := valid 239 invalidEmptyIdentifiers.ProvisionWatcher.Identifiers = emptyMap 240 // ServiceName 241 validNilServiceName := valid 242 validNilServiceName.ProvisionWatcher.ServiceName = nil 243 invalidEmptyServiceName := valid 244 invalidEmptyServiceName.ProvisionWatcher.ServiceName = &whiteSpace 245 // ProfileName 246 validNilProfileName := valid 247 validNilProfileName.ProvisionWatcher.DiscoveredDevice.ProfileName = nil 248 invalidEmptyProfileName := valid 249 invalidEmptyProfileName.ProvisionWatcher.DiscoveredDevice.ProfileName = &whiteSpace 250 emptyStringProfileName := valid 251 emptyString := "" 252 emptyStringProfileName.ProvisionWatcher.DiscoveredDevice.ProfileName = &emptyString 253 254 invalidState := "invalid state" 255 invalidAdminState := valid 256 invalidAdminState.ProvisionWatcher.AdminState = &invalidState 257 invalidFrequency := valid 258 invalidFrequency.ProvisionWatcher.DiscoveredDevice.AutoEvents = testAutoEventsWithInvalidFrequency 259 260 tests := []struct { 261 name string 262 req UpdateProvisionWatcherRequest 263 expectError bool 264 }{ 265 {"valid", valid, false}, 266 {"valid, no Request Id", noReqId, false}, 267 {"invalid, Request Id is not an uuid", invalidReqId, true}, 268 269 {"valid, only id", validOnlyId, false}, 270 {"invalid, invalid Id", invalidId, true}, 271 {"valid, only name", validOnlyName, false}, 272 {"valid, name and empty Id", nameAndEmptyId, false}, 273 {"invalid, empty name", invalidEmptyName, true}, 274 {"valid, name with reserved chars", reservedName, false}, 275 276 {"invalid, no Id and name", noIdAndName, true}, 277 278 {"valid, nil identifiers", validNilIdentifiers, false}, 279 {"invalid, empty identifiers", invalidEmptyIdentifiers, true}, 280 281 {"valid, nil service name", validNilServiceName, false}, 282 {"invalid, empty service name", invalidEmptyServiceName, true}, 283 284 {"valid, nil profile name", validNilProfileName, false}, 285 {"invalid, empty profile name", invalidEmptyProfileName, true}, 286 {"valid, empty string profile name", emptyStringProfileName, false}, 287 288 {"invalid, invalid admin state", invalidAdminState, true}, 289 {"invalid, invalid autoEvent frequency", invalidFrequency, true}, 290 } 291 for _, tt := range tests { 292 t.Run(tt.name, func(t *testing.T) { 293 err := tt.req.Validate() 294 assert.Equal(t, tt.expectError, err != nil, "Unexpected updateProvisionWatcherRequest validation result.", err) 295 }) 296 } 297 } 298 299 func TestUpdateProvisionWatcherRequest_UnmarshalJSON_NilField(t *testing.T) { 300 reqJson := `{ 301 "apiVersion" : "v3", 302 "requestId":"7a1707f0-166f-4c4b-bc9d-1d54c74e0137", 303 "provisionWatcher":{"apiVersion" : "v3","name":"test-watcher"} 304 }` 305 var req UpdateProvisionWatcherRequest 306 307 err := req.UnmarshalJSON([]byte(reqJson)) 308 309 require.NoError(t, err) 310 // Nil field checking is used to update with patch 311 assert.Nil(t, req.ProvisionWatcher.ServiceName) 312 assert.Nil(t, req.ProvisionWatcher.Labels) 313 assert.Nil(t, req.ProvisionWatcher.Identifiers) 314 assert.Nil(t, req.ProvisionWatcher.BlockingIdentifiers) 315 assert.Nil(t, req.ProvisionWatcher.DiscoveredDevice.ProfileName) 316 assert.Nil(t, req.ProvisionWatcher.AdminState) 317 assert.Nil(t, req.ProvisionWatcher.DiscoveredDevice.AutoEvents) 318 assert.Nil(t, req.ProvisionWatcher.DiscoveredDevice.Properties) 319 } 320 321 func TestUpdateProvisionWatcherRequest_UnmarshalJSON_EmptySlice(t *testing.T) { 322 reqJson := `{ 323 "apiVersion" : "v3", 324 "requestId":"7a1707f0-166f-4c4b-bc9d-1d54c74e0137", 325 "provisionWatcher":{ 326 "apiVersion" : "v3", 327 "name":"test-watcher", 328 "labels":[], 329 "discoveredDevice":{ 330 "autoEvents":[] 331 } 332 } 333 }` 334 var req UpdateProvisionWatcherRequest 335 336 err := req.UnmarshalJSON([]byte(reqJson)) 337 338 require.NoError(t, err) 339 // Empty slice is used to remove the data 340 assert.NotNil(t, req.ProvisionWatcher.Labels) 341 assert.NotNil(t, req.ProvisionWatcher.DiscoveredDevice.AutoEvents) 342 } 343 344 func TestReplaceProvisionWatcherModelFieldsWithDTO(t *testing.T) { 345 provisionWatcher := models.ProvisionWatcher{ 346 Id: "7a1707f0-166f-4c4b-bc9d-1d54c74e0137", 347 Name: "test watcher", 348 } 349 patch := mockUpdateProvisionWatcher() 350 351 ReplaceProvisionWatcherModelFieldsWithDTO(&provisionWatcher, patch) 352 353 assert.Equal(t, TestDeviceServiceName, provisionWatcher.ServiceName) 354 assert.Equal(t, testProvisionWatcherLabels, provisionWatcher.Labels) 355 assert.Equal(t, testIdentifiers, provisionWatcher.Identifiers) 356 assert.Equal(t, testBlockingIdentifiers, provisionWatcher.BlockingIdentifiers) 357 assert.Equal(t, TestDeviceProfileName, provisionWatcher.DiscoveredDevice.ProfileName) 358 assert.Equal(t, models.AdminState(models.Locked), provisionWatcher.AdminState) 359 assert.Equal(t, dtos.ToAutoEventModels(testAutoEvents), provisionWatcher.DiscoveredDevice.AutoEvents) 360 }