dev.azure.com/aidainnovazione0090/DeviceManager/_git/go-mod-core-contracts@v1.0.2/dtos/requests/deviceservice_test.go (about)

     1  //
     2  // Copyright (C) 2020-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  	"dev.azure.com/aidainnovazione0090/DeviceManager/_git/go-mod-core-contracts/common"
    14  	"dev.azure.com/aidainnovazione0090/DeviceManager/_git/go-mod-core-contracts/dtos"
    15  	dtoCommon "dev.azure.com/aidainnovazione0090/DeviceManager/_git/go-mod-core-contracts/dtos/common"
    16  	"dev.azure.com/aidainnovazione0090/DeviceManager/_git/go-mod-core-contracts/models"
    17  
    18  	"github.com/stretchr/testify/assert"
    19  	"github.com/stretchr/testify/require"
    20  )
    21  
    22  var testAddDeviceService = AddDeviceServiceRequest{
    23  	BaseRequest: dtoCommon.BaseRequest{
    24  		RequestId:   ExampleUUID,
    25  		Versionable: dtoCommon.NewVersionable(),
    26  	},
    27  	Service: dtos.DeviceService{
    28  		Name:        TestDeviceServiceName,
    29  		BaseAddress: TestBaseAddress,
    30  		Labels:      []string{"MODBUS", "TEMP"},
    31  		AdminState:  models.Locked,
    32  	},
    33  }
    34  
    35  var testUpdateDeviceService = UpdateDeviceServiceRequest{
    36  	BaseRequest: dtoCommon.BaseRequest{
    37  		RequestId:   ExampleUUID,
    38  		Versionable: dtoCommon.NewVersionable(),
    39  	},
    40  	Service: mockDeviceServiceDTO(),
    41  }
    42  
    43  func mockDeviceServiceDTO() dtos.UpdateDeviceService {
    44  	testUUID := ExampleUUID
    45  	testName := TestDeviceServiceName
    46  	testBaseAddress := TestBaseAddress
    47  	testAdminState := models.Locked
    48  	ds := dtos.UpdateDeviceService{}
    49  	ds.Id = &testUUID
    50  	ds.Name = &testName
    51  	ds.BaseAddress = &testBaseAddress
    52  	ds.AdminState = &testAdminState
    53  	ds.Labels = testLabels
    54  	return ds
    55  }
    56  
    57  func TestAddDeviceServiceRequest_Validate(t *testing.T) {
    58  	emptyString := " "
    59  	valid := testAddDeviceService
    60  	noReqId := testAddDeviceService
    61  	noReqId.RequestId = ""
    62  	invalidReqId := testAddDeviceService
    63  	invalidReqId.RequestId = "jfdw324"
    64  	noName := testAddDeviceService
    65  	noName.Service.Name = emptyString
    66  	noAdminState := testAddDeviceService
    67  	noAdminState.Service.AdminState = emptyString
    68  	invalidAdminState := testAddDeviceService
    69  	invalidAdminState.Service.AdminState = "invalid"
    70  	noBaseAddress := testAddDeviceService
    71  	noBaseAddress.Service.BaseAddress = emptyString
    72  	invalidBaseAddress := testAddDeviceService
    73  	invalidBaseAddress.Service.BaseAddress = "invalid"
    74  	tests := []struct {
    75  		name          string
    76  		DeviceService AddDeviceServiceRequest
    77  		expectError   bool
    78  	}{
    79  		{"valid AddDeviceServiceRequest", valid, false},
    80  		{"valid AddDeviceServiceRequest, no Request Id", noReqId, false},
    81  		{"invalid AddDeviceServiceRequest, Request Id is not an uuid", invalidReqId, true},
    82  		{"invalid AddDeviceServiceRequest, no Name", noName, true},
    83  		{"invalid AddDeviceServiceRequest, no AdminState", noAdminState, true},
    84  		{"invalid AddDeviceServiceRequest, invalid AdminState", invalidAdminState, true},
    85  		{"invalid AddDeviceServiceRequest, no BaseAddress", noBaseAddress, true},
    86  		{"invalid AddDeviceServiceRequest, no BaseAddress", invalidBaseAddress, true},
    87  	}
    88  	for _, tt := range tests {
    89  		t.Run(tt.name, func(t *testing.T) {
    90  			err := tt.DeviceService.Validate()
    91  			assert.Equal(t, tt.expectError, err != nil, "Unexpected addDeviceServiceRequest validation result.", err)
    92  		})
    93  	}
    94  
    95  	serviceNameWithUnreservedChars := testAddDeviceService
    96  	serviceNameWithUnreservedChars.Service.Name = nameWithUnreservedChars
    97  
    98  	err := serviceNameWithUnreservedChars.Validate()
    99  	assert.NoError(t, err, fmt.Sprintf("AddDeviceServiceRequest with service name containing unreserved chars %s should pass validation", nameWithUnreservedChars))
   100  
   101  	// Following tests verify if service name containing reserved characters should be detected without an error
   102  	for _, n := range namesWithReservedChar {
   103  		serviceNameWithReservedChar := testAddDeviceService
   104  		serviceNameWithReservedChar.Service.Name = n
   105  
   106  		err := serviceNameWithReservedChar.Validate()
   107  		assert.NoError(t, err, fmt.Sprintf("AddDeviceServiceRequest with service name containing reserved char %s should nout return error during validation", n))
   108  	}
   109  }
   110  
   111  func TestAddDeviceService_UnmarshalJSON(t *testing.T) {
   112  	valid := testAddDeviceService
   113  	resultTestBytes, _ := json.Marshal(testAddDeviceService)
   114  	type args struct {
   115  		data []byte
   116  	}
   117  	tests := []struct {
   118  		name             string
   119  		addDeviceService AddDeviceServiceRequest
   120  		args             args
   121  		wantErr          bool
   122  	}{
   123  		{"unmarshal AddDeviceServiceRequest with success", valid, args{resultTestBytes}, false},
   124  		{"unmarshal invalid AddDeviceServiceRequest, empty data", AddDeviceServiceRequest{}, args{[]byte{}}, true},
   125  		{"unmarshal invalid AddDeviceServiceRequest, string data", AddDeviceServiceRequest{}, args{[]byte("Invalid AddDeviceServiceRequest")}, true},
   126  	}
   127  	fmt.Println(string(resultTestBytes))
   128  	for _, tt := range tests {
   129  		t.Run(tt.name, func(t *testing.T) {
   130  			var expected = tt.addDeviceService
   131  			err := tt.addDeviceService.UnmarshalJSON(tt.args.data)
   132  			if tt.wantErr {
   133  				require.Error(t, err)
   134  			} else {
   135  				require.NoError(t, err)
   136  				assert.Equal(t, expected, tt.addDeviceService, "Unmarshal did not result in expected AddDeviceServiceRequest.")
   137  			}
   138  		})
   139  	}
   140  }
   141  
   142  func TestAddDeviceServiceReqToDeviceServiceModels(t *testing.T) {
   143  	requests := []AddDeviceServiceRequest{testAddDeviceService}
   144  	expectedDeviceServiceModel := []models.DeviceService{{
   145  		Name:        TestDeviceServiceName,
   146  		BaseAddress: TestBaseAddress,
   147  		Labels:      []string{"MODBUS", "TEMP"},
   148  		AdminState:  models.Locked,
   149  	}}
   150  	resultModels := AddDeviceServiceReqToDeviceServiceModels(requests)
   151  	assert.Equal(t, expectedDeviceServiceModel, resultModels, "AddDeviceServiceReqToDeviceServiceModels did not result in expected DeviceService model.")
   152  }
   153  
   154  func TestUpdateDeviceService_UnmarshalJSON(t *testing.T) {
   155  	valid := testUpdateDeviceService
   156  	resultTestBytes, _ := json.Marshal(testUpdateDeviceService)
   157  	type args struct {
   158  		data []byte
   159  	}
   160  	tests := []struct {
   161  		name    string
   162  		req     UpdateDeviceServiceRequest
   163  		args    args
   164  		wantErr bool
   165  	}{
   166  		{"unmarshal UpdateDeviceServiceRequest with success", valid, args{resultTestBytes}, false},
   167  		{"unmarshal invalid UpdateDeviceServiceRequest, empty data", UpdateDeviceServiceRequest{}, args{[]byte{}}, true},
   168  		{"unmarshal invalid UpdateDeviceServiceRequest, string data", UpdateDeviceServiceRequest{}, args{[]byte("Invalid UpdateDeviceServiceRequest")}, true},
   169  	}
   170  	fmt.Println(string(resultTestBytes))
   171  	for _, tt := range tests {
   172  		t.Run(tt.name, func(t *testing.T) {
   173  			var expected = tt.req
   174  			err := tt.req.UnmarshalJSON(tt.args.data)
   175  			if tt.wantErr {
   176  				require.Error(t, err)
   177  			} else {
   178  				require.NoError(t, err)
   179  				assert.Equal(t, expected, tt.req, "Unmarshal did not result in expected UpdateDeviceServiceRequest.", err)
   180  			}
   181  		})
   182  	}
   183  }
   184  
   185  func TestUpdateDeviceServiceRequest_Validate(t *testing.T) {
   186  	emptyString := " "
   187  	invalidUUID := "invalidUUID"
   188  	invalidUrl := "http127.0.0.1"
   189  
   190  	valid := testUpdateDeviceService
   191  	noReqId := valid
   192  	noReqId.RequestId = ""
   193  	invalidReqId := valid
   194  	invalidReqId.RequestId = invalidUUID
   195  
   196  	// id
   197  	validOnlyId := valid
   198  	validOnlyId.Service.Name = nil
   199  	invalidId := valid
   200  	invalidId.Service.Id = &invalidUUID
   201  	// name
   202  	validOnlyName := valid
   203  	validOnlyName.Service.Id = nil
   204  	invalidEmptyName := valid
   205  	invalidEmptyName.Service.Name = &emptyString
   206  	nameAndEmptyId := valid
   207  	nameAndEmptyId.Service.Id = &emptyString
   208  	// no id and name
   209  	noIdAndName := valid
   210  	noIdAndName.Service.Id = nil
   211  	noIdAndName.Service.Name = nil
   212  	// baseAddress
   213  	validNilBaseAddress := valid
   214  	validNilBaseAddress.Service.BaseAddress = nil
   215  	invalidBaseAddress := valid
   216  	invalidBaseAddress.Service.BaseAddress = &invalidUrl
   217  
   218  	invalid := "invalid"
   219  	invalidAdminState := valid
   220  	invalidAdminState.Service.AdminState = &invalid
   221  	tests := []struct {
   222  		name        string
   223  		req         UpdateDeviceServiceRequest
   224  		expectError bool
   225  	}{
   226  		{"valid", valid, false},
   227  		{"valid, no Request Id", noReqId, false},
   228  		{"invalid, Request Id is not an uuid", invalidReqId, true},
   229  
   230  		{"valid, only id", validOnlyId, false},
   231  		{"invalid, invalid Id", invalidId, true},
   232  		{"valid, only name", validOnlyName, false},
   233  		{"valid, name and empty Id", nameAndEmptyId, false},
   234  		{"invalid, empty name", invalidEmptyName, true},
   235  
   236  		{"invalid, no Id and name", noIdAndName, true},
   237  
   238  		{"valid, nil baseAddress", validNilBaseAddress, false},
   239  		{"invalid, invalid baseAddress", invalidBaseAddress, true},
   240  
   241  		{"invalid, invalid AdminState", invalidAdminState, true},
   242  	}
   243  	for _, tt := range tests {
   244  		t.Run(tt.name, func(t *testing.T) {
   245  			err := tt.req.Validate()
   246  			assert.Equal(t, tt.expectError, err != nil, "Unexpected updateDeviceServiceRequest validation result.", err)
   247  		})
   248  	}
   249  
   250  	serviceNameWithUnreservedChars := testUpdateDeviceService
   251  	serviceNameWithUnreservedChars.Service.Name = &nameWithUnreservedChars
   252  
   253  	err := serviceNameWithUnreservedChars.Validate()
   254  	assert.NoError(t, err, fmt.Sprintf("UpdateDeviceServiceRequest with service name containing unreserved chars %s should pass validation", nameWithUnreservedChars))
   255  
   256  	// Following tests verify if service name containing reserved characters should not be detected with an error
   257  	for i, n := range namesWithReservedChar {
   258  		serviceNameWithReservedChar := testUpdateDeviceService
   259  		serviceNameWithReservedChar.Service.Name = &namesWithReservedChar[i]
   260  
   261  		err := serviceNameWithReservedChar.Validate()
   262  		assert.NoError(t, err, fmt.Sprintf("UpdateDeviceServiceRequest with service name containing reserved char %s should not return error during validation", n))
   263  	}
   264  }
   265  
   266  func TestUpdateDeviceServiceRequest_UnmarshalJSON_NilField(t *testing.T) {
   267  	reqJson := `{
   268          "requestId":"7a1707f0-166f-4c4b-bc9d-1d54c74e0137",
   269  		"service":{
   270  			"name":"test device service"
   271  		}
   272  	}`
   273  	var req UpdateDeviceServiceRequest
   274  
   275  	err := req.UnmarshalJSON([]byte(reqJson))
   276  
   277  	require.NoError(t, nil, err)
   278  	// Nil field checking is used to update with patch
   279  	assert.Nil(t, req.Service.BaseAddress)
   280  	assert.Nil(t, req.Service.AdminState)
   281  	assert.Nil(t, req.Service.Labels)
   282  }
   283  
   284  func TestUpdateDeviceServiceRequest_UnmarshalJSON_EmptySlice(t *testing.T) {
   285  	reqJson := `{
   286  		"apiVersion" : "v3",
   287          "requestId":"7a1707f0-166f-4c4b-bc9d-1d54c74e0137",
   288  		"service":{
   289  			"apiVersion":"v3",
   290  			"name":"TestDevice",
   291  			"labels":[]
   292  		}
   293  	}`
   294  	var req UpdateDeviceServiceRequest
   295  
   296  	err := req.UnmarshalJSON([]byte(reqJson))
   297  
   298  	require.NoError(t, err)
   299  	// Empty slice is used to remove the data
   300  	assert.NotNil(t, req.Service.Labels)
   301  }
   302  
   303  func TestReplaceDeviceServiceModelFieldsWithDTO(t *testing.T) {
   304  	ds := models.DeviceService{
   305  		Id:   "7a1707f0-166f-4c4b-bc9d-1d54c74e0137",
   306  		Name: "test device service",
   307  	}
   308  	patch := mockDeviceServiceDTO()
   309  
   310  	ReplaceDeviceServiceModelFieldsWithDTO(&ds, patch)
   311  
   312  	assert.Equal(t, TestBaseAddress, ds.BaseAddress)
   313  	assert.Equal(t, models.Locked, string(ds.AdminState))
   314  	assert.Equal(t, testLabels, ds.Labels)
   315  }
   316  
   317  func TestNewAddDeviceServiceRequest(t *testing.T) {
   318  	expectedApiVersion := common.ApiVersion
   319  
   320  	actual := NewAddDeviceServiceRequest(dtos.DeviceService{})
   321  
   322  	assert.Equal(t, expectedApiVersion, actual.ApiVersion)
   323  }
   324  
   325  func TestNewUpdateDeviceServiceRequest(t *testing.T) {
   326  	expectedApiVersion := common.ApiVersion
   327  
   328  	actual := NewUpdateDeviceServiceRequest(dtos.UpdateDeviceService{})
   329  
   330  	assert.Equal(t, expectedApiVersion, actual.ApiVersion)
   331  }