github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/cloudwrapper/configurations_test.go (about)

     1  package cloudwrapper
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"io"
     7  	"net/http"
     8  	"net/http/httptest"
     9  	"testing"
    10  
    11  	"github.com/akamai/AkamaiOPEN-edgegrid-golang/v8/pkg/tools"
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  func TestGetConfiguration(t *testing.T) {
    17  	tests := map[string]struct {
    18  		params           GetConfigurationRequest
    19  		responseStatus   int
    20  		responseBody     string
    21  		expectedPath     string
    22  		expectedResponse *Configuration
    23  		withError        func(*testing.T, error)
    24  	}{
    25  		"200 OK": {
    26  			params: GetConfigurationRequest{
    27  				ConfigID: 1,
    28  			},
    29  			responseStatus: 200,
    30  			responseBody: `
    31  {
    32      "configId": 1,
    33      "configName": "TestConfigName",
    34      "contractId": "TestContractID",
    35      "propertyIds": [
    36          "321",
    37  		"654"
    38      ],
    39      "comments": "TestComments",
    40      "status": "ACTIVE",
    41      "retainIdleObjects": false,
    42      "locations": [
    43          {
    44              "trafficTypeId": 1,
    45              "comments": "TestComments",
    46              "capacity": {
    47                  "value": 1,
    48                  "unit": "GB"
    49              },
    50  			"mapName": "cw-s-use"
    51          },
    52  		{
    53              "trafficTypeId": 2,
    54              "comments": "TestComments",
    55              "capacity": {
    56                  "value": 2,
    57                  "unit": "TB"
    58              },
    59  			"mapName": "cw-s-use"
    60          }
    61      ],
    62      "multiCdnSettings": {
    63          "origins": [
    64              {
    65                  "originId": "TestOriginID",
    66                  "hostname": "TestHostname",
    67  						"propertyId": 321
    68              },
    69  			{
    70                  "originId": "TestOriginID2",
    71                  "hostname": "TestHostname",
    72                  "propertyId": 654
    73              }
    74          ],
    75          "cdns": [
    76              {
    77                  "cdnCode": "TestCDNCode",
    78                  "enabled": true,
    79                  "cdnAuthKeys": [
    80                      {
    81                          "authKeyName": "TestAuthKeyName"
    82                      }
    83                  ],
    84                  "ipAclCidrs": [],
    85                  "httpsOnly": false
    86              },
    87  			{
    88                  "cdnCode": "TestCDNCode",
    89                  "enabled": false,
    90                  "cdnAuthKeys": [
    91                      {
    92                          "authKeyName": "TestAuthKeyName"
    93                      },
    94  					{
    95                          "authKeyName": "TestAuthKeyName2"
    96                      }
    97                  ],
    98                  "ipAclCidrs": [
    99  					"test1",
   100  					"test2"
   101  				],
   102                  "httpsOnly": true
   103              }
   104          ],
   105          "dataStreams": {
   106              "enabled": true,
   107              "dataStreamIds": [
   108  				11,
   109  				22
   110  			],
   111  			"samplingRate": 999
   112          },
   113          "bocc": {
   114              "enabled": false,
   115  			"conditionalSamplingFrequency": "ONE_TENTH",
   116  			"forwardType": "ORIGIN_AND_MIDGRESS",
   117  			"requestType": "EDGE_ONLY",
   118  			"samplingFrequency": "ZERO"
   119          },
   120          "enableSoftAlerts": true
   121      },
   122      "capacityAlertsThreshold": 75,
   123      "notificationEmails": [
   124          "test@akamai.com"
   125      ],
   126      "lastUpdatedDate": "2023-05-10T09:55:37.000Z",
   127      "lastUpdatedBy": "user",
   128      "lastActivatedDate": "2023-05-10T10:14:49.379Z",
   129      "lastActivatedBy": "user"
   130  }`,
   131  			expectedPath: "/cloud-wrapper/v1/configurations/1",
   132  			expectedResponse: &Configuration{
   133  				CapacityAlertsThreshold: tools.IntPtr(75),
   134  				Comments:                "TestComments",
   135  				ContractID:              "TestContractID",
   136  				ConfigID:                1,
   137  				Locations: []ConfigLocationResp{
   138  					{
   139  						Comments:      "TestComments",
   140  						TrafficTypeID: 1,
   141  						Capacity: Capacity{
   142  							Unit:  "GB",
   143  							Value: 1,
   144  						},
   145  						MapName: "cw-s-use",
   146  					},
   147  					{
   148  						Comments:      "TestComments",
   149  						TrafficTypeID: 2,
   150  						Capacity: Capacity{
   151  							Unit:  "TB",
   152  							Value: 2,
   153  						},
   154  						MapName: "cw-s-use",
   155  					},
   156  				},
   157  				MultiCDNSettings: &MultiCDNSettings{
   158  					BOCC: &BOCC{
   159  						ConditionalSamplingFrequency: SamplingFrequencyOneTenth,
   160  						Enabled:                      false,
   161  						ForwardType:                  ForwardTypeOriginAndMidgress,
   162  						RequestType:                  RequestTypeEdgeOnly,
   163  						SamplingFrequency:            SamplingFrequencyZero,
   164  					},
   165  					CDNs: []CDN{
   166  						{
   167  							CDNAuthKeys: []CDNAuthKey{
   168  								{
   169  									AuthKeyName: "TestAuthKeyName",
   170  								},
   171  							},
   172  							CDNCode:    "TestCDNCode",
   173  							Enabled:    true,
   174  							HTTPSOnly:  false,
   175  							IPACLCIDRs: []string{},
   176  						},
   177  						{
   178  							CDNAuthKeys: []CDNAuthKey{
   179  								{
   180  									AuthKeyName: "TestAuthKeyName",
   181  								},
   182  								{
   183  									AuthKeyName: "TestAuthKeyName2",
   184  								},
   185  							},
   186  							CDNCode:   "TestCDNCode",
   187  							Enabled:   false,
   188  							HTTPSOnly: true,
   189  							IPACLCIDRs: []string{
   190  								"test1",
   191  								"test2",
   192  							},
   193  						},
   194  					},
   195  					DataStreams: &DataStreams{
   196  						DataStreamIDs: []int64{11, 22},
   197  						Enabled:       true,
   198  						SamplingRate:  tools.IntPtr(999),
   199  					},
   200  					EnableSoftAlerts: true,
   201  					Origins: []Origin{
   202  						{
   203  							Hostname:   "TestHostname",
   204  							OriginID:   "TestOriginID",
   205  							PropertyID: 321,
   206  						},
   207  						{
   208  							Hostname:   "TestHostname",
   209  							OriginID:   "TestOriginID2",
   210  							PropertyID: 654,
   211  						},
   212  					},
   213  				},
   214  				Status:             "ACTIVE",
   215  				ConfigName:         "TestConfigName",
   216  				LastUpdatedBy:      "user",
   217  				LastUpdatedDate:    "2023-05-10T09:55:37.000Z",
   218  				LastActivatedBy:    tools.StringPtr("user"),
   219  				LastActivatedDate:  tools.StringPtr("2023-05-10T10:14:49.379Z"),
   220  				NotificationEmails: []string{"test@akamai.com"},
   221  				PropertyIDs: []string{
   222  					"321",
   223  					"654",
   224  				},
   225  				RetainIdleObjects: false,
   226  			},
   227  		},
   228  		"200 OK - minimal": {
   229  			params: GetConfigurationRequest{
   230  				ConfigID: 1,
   231  			},
   232  			responseStatus: 200,
   233  			responseBody: `
   234  {
   235     "configId":1,
   236     "configName":"TestConfigName",
   237     "contractId":"TestContractID",
   238     "propertyIds":[
   239        "123"
   240     ],
   241     "comments":"TestComments",
   242     "status":"ACTIVE",
   243     "retainIdleObjects":false,
   244     "locations":[
   245        {
   246           "trafficTypeId":1,
   247           "comments":"TestComments",
   248           "capacity":{
   249              "value":1,
   250              "unit":"GB"
   251           },
   252  		 "mapName": "cw-s-use"
   253        }
   254     ],
   255     "multiCdnSettings":null,
   256     "capacityAlertsThreshold":null,
   257     "notificationEmails":[],
   258     "lastUpdatedDate":"2023-05-10T09:55:37.000Z",
   259     "lastUpdatedBy":"user",
   260     "lastActivatedDate":null,
   261     "lastActivatedBy":null
   262  }`,
   263  			expectedPath: "/cloud-wrapper/v1/configurations/1",
   264  			expectedResponse: &Configuration{
   265  				Comments:   "TestComments",
   266  				ContractID: "TestContractID",
   267  				ConfigID:   1,
   268  				Locations: []ConfigLocationResp{
   269  					{
   270  						Comments:      "TestComments",
   271  						TrafficTypeID: 1,
   272  						Capacity: Capacity{
   273  							Unit:  "GB",
   274  							Value: 1,
   275  						},
   276  						MapName: "cw-s-use",
   277  					},
   278  				},
   279  				Status:             "ACTIVE",
   280  				ConfigName:         "TestConfigName",
   281  				LastUpdatedBy:      "user",
   282  				LastUpdatedDate:    "2023-05-10T09:55:37.000Z",
   283  				NotificationEmails: []string{},
   284  				PropertyIDs: []string{
   285  					"123",
   286  				},
   287  				RetainIdleObjects: false,
   288  			},
   289  		},
   290  		"missing required params - validation error": {
   291  			params: GetConfigurationRequest{},
   292  			withError: func(t *testing.T, err error) {
   293  				assert.Equal(t, "get configuration: struct validation: ConfigID: cannot be blank", err.Error())
   294  			},
   295  		},
   296  		"500 internal server error": {
   297  			params: GetConfigurationRequest{
   298  				ConfigID: 3,
   299  			},
   300  			responseStatus: http.StatusInternalServerError,
   301  			responseBody: `
   302  {
   303      "type": "/cloudwrapper/error-types/cloudwrapper-server-error",
   304      "title": "An unexpected error has occurred.",
   305      "detail": "Error processing request",
   306      "instance": "/cloudwrapper/error-instances/abc",
   307      "status": 500
   308  }`,
   309  			expectedPath: "/cloud-wrapper/v1/configurations/3",
   310  			withError: func(t *testing.T, err error) {
   311  				want := &Error{
   312  					Type:     "/cloudwrapper/error-types/cloudwrapper-server-error",
   313  					Title:    "An unexpected error has occurred.",
   314  					Detail:   "Error processing request",
   315  					Instance: "/cloudwrapper/error-instances/abc",
   316  					Status:   500,
   317  				}
   318  				assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err)
   319  			},
   320  		},
   321  	}
   322  
   323  	for name, test := range tests {
   324  		t.Run(name, func(t *testing.T) {
   325  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   326  				assert.Equal(t, test.expectedPath, r.URL.String())
   327  				assert.Equal(t, http.MethodGet, r.Method)
   328  				w.WriteHeader(test.responseStatus)
   329  				_, err := w.Write([]byte(test.responseBody))
   330  				assert.NoError(t, err)
   331  			}))
   332  			client := mockAPIClient(t, mockServer)
   333  			result, err := client.GetConfiguration(context.Background(), test.params)
   334  			if test.withError != nil {
   335  				test.withError(t, err)
   336  				return
   337  			}
   338  			require.NoError(t, err)
   339  			assert.Equal(t, test.expectedResponse, result)
   340  		})
   341  	}
   342  }
   343  
   344  func TestListConfigurations(t *testing.T) {
   345  	tests := map[string]struct {
   346  		responseStatus   int
   347  		responseBody     string
   348  		expectedPath     string
   349  		expectedResponse *ListConfigurationsResponse
   350  		withError        error
   351  	}{
   352  		"200 OK": {
   353  			responseStatus: 200,
   354  			responseBody: `
   355  {
   356     "configurations":[
   357        {
   358           "configId":1,
   359           "configName":"testcloudwrapper",
   360           "contractId":"testContract",
   361           "propertyIds":[
   362              "11"
   363           ],
   364           "comments":"testComments",
   365           "status":"ACTIVE",
   366           "retainIdleObjects":false,
   367           "locations":[
   368              {
   369                 "trafficTypeId":1,
   370                 "comments":"usageNotes",
   371                 "capacity":{
   372                    "value":1,
   373                    "unit":"GB"
   374                 },
   375  			   "mapName": "cw-s-use"
   376              }
   377           ],
   378           "multiCdnSettings":null,
   379           "capacityAlertsThreshold":75,
   380           "notificationEmails":[
   381              "user@akamai.com"
   382           ],
   383           "lastUpdatedDate":"2023-05-10T09:55:37.000Z",
   384           "lastUpdatedBy":"user",
   385           "lastActivatedDate":"2023-05-10T10:14:49.379Z",
   386           "lastActivatedBy":"user"
   387        },
   388        {
   389           "configId":2,
   390           "configName":"testcloudwrappermcdn",
   391           "contractId":"testContract2",
   392           "propertyIds":[
   393              "22"
   394           ],
   395           "comments":"mcdn",
   396           "status":"ACTIVE",
   397           "retainIdleObjects":false,
   398           "locations":[
   399              {
   400                 "trafficTypeId":2,
   401                 "comments":"mcdn",
   402                 "capacity":{
   403                    "value":2,
   404                    "unit":"TB"
   405                 },
   406  			   "mapName": "cw-s-use"
   407              }
   408           ],
   409           "multiCdnSettings":{
   410              "origins":[
   411                 {
   412                    "originId":"testOrigin",
   413                    "hostname":"hostname.example.com",
   414                    "propertyId":222
   415                 }
   416              ],
   417              "cdns":[
   418                 {
   419                    "cdnCode":"testCode2",
   420                    "enabled":true,
   421                    "cdnAuthKeys":[
   422                       {
   423                          "authKeyName":"authKeyTest2"
   424                       }
   425                    ],
   426                    "ipAclCidrs":[
   427                       "2.2.2.2/22"
   428                    ],
   429                    "httpsOnly":true
   430                 }
   431              ],
   432              "dataStreams":{
   433                 "enabled":false,
   434                 "dataStreamIds":[
   435                    2
   436                 ]
   437              },
   438              "bocc":{
   439                 "enabled":false
   440              },
   441              "enableSoftAlerts":true
   442           },
   443           "capacityAlertsThreshold":75,
   444           "notificationEmails":[
   445              "user@akamai.com"
   446           ],
   447           "lastUpdatedDate":"2023-05-10T09:55:37.000Z",
   448           "lastUpdatedBy":"user",
   449           "lastActivatedDate":"2023-05-10T10:14:49.379Z",
   450           "lastActivatedBy":"user"
   451        }
   452     ]
   453  }`,
   454  			expectedPath: "/cloud-wrapper/v1/configurations",
   455  			expectedResponse: &ListConfigurationsResponse{
   456  				Configurations: []Configuration{
   457  					{
   458  						CapacityAlertsThreshold: tools.IntPtr(75),
   459  						Comments:                "testComments",
   460  						ContractID:              "testContract",
   461  						ConfigID:                1,
   462  						Locations: []ConfigLocationResp{
   463  							{
   464  								Comments:      "usageNotes",
   465  								TrafficTypeID: 1,
   466  								Capacity: Capacity{
   467  									Unit:  "GB",
   468  									Value: 1,
   469  								},
   470  								MapName: "cw-s-use",
   471  							},
   472  						},
   473  						Status:             "ACTIVE",
   474  						ConfigName:         "testcloudwrapper",
   475  						LastUpdatedBy:      "user",
   476  						LastUpdatedDate:    "2023-05-10T09:55:37.000Z",
   477  						LastActivatedBy:    tools.StringPtr("user"),
   478  						LastActivatedDate:  tools.StringPtr("2023-05-10T10:14:49.379Z"),
   479  						NotificationEmails: []string{"user@akamai.com"},
   480  						PropertyIDs: []string{
   481  							"11",
   482  						},
   483  						RetainIdleObjects: false,
   484  					},
   485  					{
   486  						CapacityAlertsThreshold: tools.IntPtr(75),
   487  						Comments:                "mcdn",
   488  						ContractID:              "testContract2",
   489  						ConfigID:                2,
   490  						Locations: []ConfigLocationResp{
   491  							{
   492  								Comments:      "mcdn",
   493  								TrafficTypeID: 2,
   494  								Capacity: Capacity{
   495  									Unit:  "TB",
   496  									Value: 2,
   497  								},
   498  								MapName: "cw-s-use",
   499  							},
   500  						},
   501  						MultiCDNSettings: &MultiCDNSettings{
   502  							BOCC: &BOCC{
   503  								Enabled: false,
   504  							},
   505  							CDNs: []CDN{
   506  								{
   507  									CDNAuthKeys: []CDNAuthKey{
   508  										{
   509  											AuthKeyName: "authKeyTest2",
   510  										},
   511  									},
   512  									CDNCode:   "testCode2",
   513  									Enabled:   true,
   514  									HTTPSOnly: true,
   515  									IPACLCIDRs: []string{
   516  										"2.2.2.2/22",
   517  									},
   518  								},
   519  							},
   520  							DataStreams: &DataStreams{
   521  								DataStreamIDs: []int64{2},
   522  								Enabled:       false,
   523  							},
   524  							EnableSoftAlerts: true,
   525  							Origins: []Origin{
   526  								{
   527  									Hostname:   "hostname.example.com",
   528  									OriginID:   "testOrigin",
   529  									PropertyID: 222,
   530  								},
   531  							},
   532  						},
   533  						Status:             "ACTIVE",
   534  						ConfigName:         "testcloudwrappermcdn",
   535  						LastUpdatedBy:      "user",
   536  						LastUpdatedDate:    "2023-05-10T09:55:37.000Z",
   537  						LastActivatedBy:    tools.StringPtr("user"),
   538  						LastActivatedDate:  tools.StringPtr("2023-05-10T10:14:49.379Z"),
   539  						NotificationEmails: []string{"user@akamai.com"},
   540  						PropertyIDs:        []string{"22"},
   541  						RetainIdleObjects:  false,
   542  					},
   543  				},
   544  			},
   545  		},
   546  		"500 internal server error": {
   547  			responseStatus: http.StatusInternalServerError,
   548  			responseBody: `
   549  {
   550      "type": "/cloudwrapper/error-types/cloudwrapper-server-error",
   551      "title": "An unexpected error has occurred.",
   552      "detail": "Error processing request",
   553      "instance": "/cloudwrapper/error-instances/abc",
   554      "status": 500
   555  }`,
   556  			expectedPath: "/cloud-wrapper/v1/configurations",
   557  			withError: &Error{
   558  				Type:     "/cloudwrapper/error-types/cloudwrapper-server-error",
   559  				Title:    "An unexpected error has occurred.",
   560  				Detail:   "Error processing request",
   561  				Instance: "/cloudwrapper/error-instances/abc",
   562  				Status:   500,
   563  			},
   564  		},
   565  	}
   566  
   567  	for name, test := range tests {
   568  		t.Run(name, func(t *testing.T) {
   569  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   570  				assert.Equal(t, test.expectedPath, r.URL.String())
   571  				assert.Equal(t, http.MethodGet, r.Method)
   572  				w.WriteHeader(test.responseStatus)
   573  				_, err := w.Write([]byte(test.responseBody))
   574  				assert.NoError(t, err)
   575  			}))
   576  			client := mockAPIClient(t, mockServer)
   577  			result, err := client.ListConfigurations(context.Background())
   578  			if test.withError != nil {
   579  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
   580  				return
   581  			}
   582  			require.NoError(t, err)
   583  			assert.Equal(t, test.expectedResponse, result)
   584  		})
   585  	}
   586  }
   587  
   588  func TestCreateConfiguration(t *testing.T) {
   589  	tests := map[string]struct {
   590  		params              CreateConfigurationRequest
   591  		expectedRequestBody string
   592  		expectedPath        string
   593  		responseStatus      int
   594  		responseBody        string
   595  		expectedResponse    *Configuration
   596  		withError           func(*testing.T, error)
   597  	}{
   598  		"200 OK - minimal": {
   599  			params: CreateConfigurationRequest{
   600  				Body: CreateConfigurationBody{
   601  					Comments:   "TestComments",
   602  					ContractID: "TestContractID",
   603  					Locations: []ConfigLocationReq{
   604  						{
   605  							Comments:      "TestComments",
   606  							TrafficTypeID: 1,
   607  							Capacity: Capacity{
   608  								Unit:  UnitGB,
   609  								Value: 1,
   610  							},
   611  						},
   612  					},
   613  					ConfigName:  "TestConfigName",
   614  					PropertyIDs: []string{"123"},
   615  				},
   616  			},
   617  			expectedRequestBody: `
   618  {
   619     "locations":[
   620        {
   621           "capacity":{
   622              "value":1,
   623              "unit":"GB"
   624           },
   625           "comments":"TestComments",
   626           "trafficTypeId":1
   627        }
   628     ],
   629     "propertyIds":[
   630        "123"
   631     ],
   632     "contractId":"TestContractID",
   633     "comments":"TestComments",
   634     "configName":"TestConfigName"
   635  }`,
   636  			expectedPath:   "/cloud-wrapper/v1/configurations?activate=false",
   637  			responseStatus: 201,
   638  			responseBody: `
   639  {
   640     "configId":111,
   641     "configName":"TestConfigName",
   642     "contractId":"TestContractID",
   643     "propertyIds":[
   644        "123"
   645     ],
   646     "comments":"TestComments",
   647     "status":"IN_PROGRESS",
   648     "retainIdleObjects":false,
   649     "locations":[
   650        {
   651           "trafficTypeId":1,
   652           "comments":"TestComments",
   653           "capacity":{
   654              "value":1,
   655              "unit":"GB"
   656           },
   657  		 "mapName": "cw-s-use"
   658        }
   659     ],
   660     "multiCdnSettings":null,
   661     "capacityAlertsThreshold":50,
   662     "notificationEmails":[
   663        
   664     ],
   665     "lastUpdatedDate":"2022-06-10T13:21:14.488Z",
   666     "lastUpdatedBy":"johndoe",
   667     "lastActivatedDate":null,
   668     "lastActivatedBy":null
   669  }`,
   670  			expectedResponse: &Configuration{
   671  				CapacityAlertsThreshold: tools.IntPtr(50),
   672  				Comments:                "TestComments",
   673  				ContractID:              "TestContractID",
   674  				Locations: []ConfigLocationResp{
   675  					{
   676  						Comments:      "TestComments",
   677  						TrafficTypeID: 1,
   678  						Capacity: Capacity{
   679  							Unit:  UnitGB,
   680  							Value: 1,
   681  						},
   682  						MapName: "cw-s-use",
   683  					},
   684  				},
   685  				Status:             StatusInProgress,
   686  				ConfigName:         "TestConfigName",
   687  				LastUpdatedBy:      "johndoe",
   688  				LastUpdatedDate:    "2022-06-10T13:21:14.488Z",
   689  				NotificationEmails: []string{},
   690  				PropertyIDs:        []string{"123"},
   691  				ConfigID:           111,
   692  			},
   693  		},
   694  		"200 OK - minimal with activate query param": {
   695  			params: CreateConfigurationRequest{
   696  				Activate: true,
   697  				Body: CreateConfigurationBody{
   698  					Comments:   "TestComments",
   699  					ContractID: "TestContractID",
   700  					Locations: []ConfigLocationReq{
   701  						{
   702  							Comments:      "TestComments",
   703  							TrafficTypeID: 1,
   704  							Capacity: Capacity{
   705  								Unit:  "GB",
   706  								Value: 1,
   707  							},
   708  						},
   709  					},
   710  					ConfigName:  "TestConfigName",
   711  					PropertyIDs: []string{"123"},
   712  				},
   713  			},
   714  			expectedRequestBody: `
   715  {
   716     "locations":[
   717        {
   718           "capacity":{
   719              "value":1,
   720              "unit":"GB"
   721           },
   722           "comments":"TestComments",
   723           "trafficTypeId":1
   724        }
   725     ],
   726     "propertyIds":[
   727        "123"
   728     ],
   729     "contractId":"TestContractID",
   730     "comments":"TestComments",
   731     "configName":"TestConfigName"
   732  }`,
   733  			expectedPath:   "/cloud-wrapper/v1/configurations?activate=true",
   734  			responseStatus: 201,
   735  			responseBody: `
   736  {
   737     "configId":111,
   738     "configName":"TestConfigName",
   739     "contractId":"TestContractID",
   740     "propertyIds":[
   741        "123"
   742     ],
   743     "comments":"TestComments",
   744     "status":"IN_PROGRESS",
   745     "retainIdleObjects":false,
   746     "locations":[
   747        {
   748           "trafficTypeId":1,
   749           "comments":"TestComments",
   750           "capacity":{
   751              "value":1,
   752              "unit":"GB"
   753           },
   754  		 "mapName": "cw-s-use"
   755        }
   756     ],
   757     "multiCdnSettings":null,
   758     "capacityAlertsThreshold":50,
   759     "notificationEmails":[
   760        
   761     ],
   762     "lastUpdatedDate":"2022-06-10T13:21:14.488Z",
   763     "lastUpdatedBy":"johndoe",
   764     "lastActivatedDate":null,
   765     "lastActivatedBy":null
   766  }`,
   767  			expectedResponse: &Configuration{
   768  				CapacityAlertsThreshold: tools.IntPtr(50),
   769  				Comments:                "TestComments",
   770  				ContractID:              "TestContractID",
   771  				Locations: []ConfigLocationResp{
   772  					{
   773  						Comments:      "TestComments",
   774  						TrafficTypeID: 1,
   775  						Capacity: Capacity{
   776  							Unit:  "GB",
   777  							Value: 1,
   778  						},
   779  						MapName: "cw-s-use",
   780  					},
   781  				},
   782  				Status:             StatusInProgress,
   783  				ConfigName:         "TestConfigName",
   784  				LastUpdatedBy:      "johndoe",
   785  				LastUpdatedDate:    "2022-06-10T13:21:14.488Z",
   786  				NotificationEmails: []string{},
   787  				PropertyIDs:        []string{"123"},
   788  				ConfigID:           111,
   789  			},
   790  		},
   791  		"200 OK - minimal MultiCDNSettings": {
   792  			params: CreateConfigurationRequest{
   793  				Body: CreateConfigurationBody{
   794  					Comments:   "TestComments",
   795  					ContractID: "TestContractID",
   796  					Locations: []ConfigLocationReq{
   797  						{
   798  							Comments:      "TestComments",
   799  							TrafficTypeID: 1,
   800  							Capacity: Capacity{
   801  								Unit:  "GB",
   802  								Value: 1,
   803  							},
   804  						},
   805  					},
   806  					MultiCDNSettings: &MultiCDNSettings{
   807  						BOCC: &BOCC{
   808  							Enabled: false,
   809  						},
   810  						CDNs: []CDN{
   811  							{
   812  								CDNAuthKeys: []CDNAuthKey{
   813  									{
   814  										AuthKeyName: "TestAuthKeyName",
   815  										ExpiryDate:  "TestExpiryDate",
   816  										HeaderName:  "TestHeaderName",
   817  										Secret:      "testtesttesttesttesttest",
   818  									},
   819  								},
   820  								CDNCode: "TestCDNCode",
   821  								Enabled: true,
   822  							},
   823  						},
   824  						DataStreams: &DataStreams{
   825  							Enabled: false,
   826  						},
   827  						Origins: []Origin{
   828  							{
   829  								Hostname:   "TestHostname",
   830  								OriginID:   "TestOriginID",
   831  								PropertyID: 123,
   832  							},
   833  						},
   834  					},
   835  					ConfigName:  "TestConfigName",
   836  					PropertyIDs: []string{"123"},
   837  				},
   838  			},
   839  			expectedRequestBody: `
   840  {
   841     "locations":[
   842        {
   843           "capacity":{
   844              "value":1,
   845              "unit":"GB"
   846           },
   847           "comments":"TestComments",
   848           "trafficTypeId":1
   849        }
   850     ],
   851     "multiCdnSettings":{
   852        "origins":[
   853           {
   854              "originId":"TestOriginID",
   855              "hostname":"TestHostname",
   856              "propertyId":123
   857           }
   858        ],
   859        "cdns":[
   860           {
   861              "cdnCode":"TestCDNCode",
   862              "enabled":true,
   863              "cdnAuthKeys":[
   864                 {
   865                    "authKeyName":"TestAuthKeyName",
   866                    "headerName":"TestHeaderName",
   867                    "secret":"testtesttesttesttesttest",
   868                    "expiryDate":"TestExpiryDate"
   869                 }
   870              ]
   871           }
   872        ],
   873        "dataStreams":{
   874           "enabled":false
   875        },
   876        "bocc":{
   877           "enabled":false
   878        }
   879     },
   880     "propertyIds":[
   881        "123"
   882     ],
   883     "contractId":"TestContractID",
   884     "comments":"TestComments",
   885     "configName":"TestConfigName"
   886  }`,
   887  			expectedPath:   "/cloud-wrapper/v1/configurations?activate=false",
   888  			responseStatus: 201,
   889  			responseBody: `
   890  {
   891     "configId":111,
   892     "configName":"TestConfigName",
   893     "contractId":"TestContractID",
   894     "propertyIds":[
   895        "123"
   896     ],
   897     "comments":"TestComments",
   898     "status":"IN_PROGRESS",
   899     "retainIdleObjects":false,
   900     "locations":[
   901        {
   902           "trafficTypeId":1,
   903           "comments":"TestComments",
   904           "capacity":{
   905              "value":1,
   906              "unit":"GB"
   907           },
   908  		 "mapName": "cw-s-use"
   909        }
   910     ],
   911     "multiCdnSettings":{
   912        "origins":[
   913           {
   914              "originId":"TestOriginID",
   915              "hostname":"TestHostname",
   916              "propertyId":123
   917           }
   918        ],
   919        "cdns":[
   920           {
   921              "cdnCode":"TestCDNCode",
   922              "enabled":true,
   923              "cdnAuthKeys":[
   924                 {
   925                    "authKeyName":"TestAuthKeyName",
   926                    "headerName":"TestHeaderName",
   927                    "secret":"testtesttesttesttesttest",
   928                    "expiryDate":"TestExpiryDate"
   929                 }
   930              ],
   931              "ipAclCidrs":[],
   932              "httpsOnly":false
   933           }
   934        ],
   935        "dataStreams":{
   936           "enabled":false
   937        },
   938        "bocc":{
   939           "enabled":false
   940        },
   941        "enableSoftAlerts":false
   942     },
   943     "capacityAlertsThreshold":null,
   944     "notificationEmails":[],
   945     "lastUpdatedDate":"2022-06-10T13:21:14.488Z",
   946     "lastUpdatedBy":"johndoe",
   947     "lastActivatedDate":null,
   948     "lastActivatedBy":null
   949  }`,
   950  			expectedResponse: &Configuration{
   951  				CapacityAlertsThreshold: nil,
   952  				Comments:                "TestComments",
   953  				ContractID:              "TestContractID",
   954  				Locations: []ConfigLocationResp{
   955  					{
   956  						Comments:      "TestComments",
   957  						TrafficTypeID: 1,
   958  						Capacity: Capacity{
   959  							Unit:  "GB",
   960  							Value: 1,
   961  						},
   962  						MapName: "cw-s-use",
   963  					},
   964  				},
   965  				MultiCDNSettings: &MultiCDNSettings{
   966  					BOCC: &BOCC{
   967  						Enabled: false,
   968  					},
   969  					CDNs: []CDN{
   970  						{
   971  							CDNAuthKeys: []CDNAuthKey{
   972  								{
   973  									AuthKeyName: "TestAuthKeyName",
   974  									ExpiryDate:  "TestExpiryDate",
   975  									HeaderName:  "TestHeaderName",
   976  									Secret:      "testtesttesttesttesttest",
   977  								},
   978  							},
   979  							CDNCode:    "TestCDNCode",
   980  							Enabled:    true,
   981  							IPACLCIDRs: []string{},
   982  						},
   983  					},
   984  					DataStreams: &DataStreams{
   985  						Enabled: false,
   986  					},
   987  					Origins: []Origin{
   988  						{
   989  							Hostname:   "TestHostname",
   990  							OriginID:   "TestOriginID",
   991  							PropertyID: 123,
   992  						},
   993  					},
   994  					EnableSoftAlerts: false,
   995  				},
   996  				RetainIdleObjects:  false,
   997  				Status:             StatusInProgress,
   998  				ConfigName:         "TestConfigName",
   999  				LastUpdatedBy:      "johndoe",
  1000  				LastUpdatedDate:    "2022-06-10T13:21:14.488Z",
  1001  				NotificationEmails: []string{},
  1002  				PropertyIDs:        []string{"123"},
  1003  				ConfigID:           111,
  1004  			},
  1005  		},
  1006  		"200 OK - full MultiCDNSettings": {
  1007  			params: CreateConfigurationRequest{
  1008  				Body: CreateConfigurationBody{
  1009  					CapacityAlertsThreshold: tools.IntPtr(70),
  1010  					Comments:                "TestComments",
  1011  					ContractID:              "TestContractID",
  1012  					Locations: []ConfigLocationReq{
  1013  						{
  1014  							Comments:      "TestComments",
  1015  							TrafficTypeID: 1,
  1016  							Capacity: Capacity{
  1017  								Unit:  "GB",
  1018  								Value: 1,
  1019  							},
  1020  						},
  1021  						{
  1022  							Comments:      "TestComments2",
  1023  							TrafficTypeID: 2,
  1024  							Capacity: Capacity{
  1025  								Unit:  "TB",
  1026  								Value: 2,
  1027  							},
  1028  						},
  1029  					},
  1030  					MultiCDNSettings: &MultiCDNSettings{
  1031  						BOCC: &BOCC{
  1032  							ConditionalSamplingFrequency: SamplingFrequencyZero,
  1033  							Enabled:                      true,
  1034  							ForwardType:                  ForwardTypeOriginAndMidgress,
  1035  							RequestType:                  RequestTypeEdgeAndMidgress,
  1036  							SamplingFrequency:            SamplingFrequencyZero,
  1037  						},
  1038  						CDNs: []CDN{
  1039  							{
  1040  								CDNAuthKeys: []CDNAuthKey{
  1041  									{
  1042  										AuthKeyName: "TestAuthKeyName",
  1043  										ExpiryDate:  "TestExpiryDate",
  1044  										HeaderName:  "TestHeaderName",
  1045  										Secret:      "testtesttesttesttesttest",
  1046  									},
  1047  								},
  1048  								CDNCode:   "TestCDNCode",
  1049  								Enabled:   true,
  1050  								HTTPSOnly: true,
  1051  							},
  1052  							{
  1053  								CDNCode:   "TestCDNCode",
  1054  								Enabled:   true,
  1055  								HTTPSOnly: true,
  1056  								IPACLCIDRs: []string{
  1057  									"1.1.1.1/1",
  1058  								},
  1059  							},
  1060  						},
  1061  						DataStreams: &DataStreams{
  1062  							DataStreamIDs: []int64{1},
  1063  							Enabled:       true,
  1064  							SamplingRate:  tools.IntPtr(10),
  1065  						},
  1066  						Origins: []Origin{
  1067  							{
  1068  								Hostname:   "TestHostname",
  1069  								OriginID:   "TestOriginID",
  1070  								PropertyID: 123,
  1071  							},
  1072  							{
  1073  								Hostname:   "TestHostname2",
  1074  								OriginID:   "TestOriginID2",
  1075  								PropertyID: 1234,
  1076  							},
  1077  						},
  1078  						EnableSoftAlerts: true,
  1079  					},
  1080  					ConfigName: "TestConfigName",
  1081  					NotificationEmails: []string{
  1082  						"test@test.com",
  1083  					},
  1084  					PropertyIDs:       []string{"123"},
  1085  					RetainIdleObjects: true,
  1086  				},
  1087  			},
  1088  			expectedRequestBody: `
  1089  {
  1090     "capacityAlertsThreshold":70,
  1091     "locations":[
  1092        {
  1093           "capacity":{
  1094              "value":1,
  1095              "unit":"GB"
  1096           },
  1097           "comments":"TestComments",
  1098           "trafficTypeId":1
  1099        },
  1100  	  {
  1101           "capacity":{
  1102              "value":2,
  1103              "unit":"TB"
  1104           },
  1105           "comments":"TestComments2",
  1106           "trafficTypeId":2
  1107        }
  1108     ],
  1109     "multiCdnSettings":{
  1110        "origins":[
  1111           {
  1112              "originId":"TestOriginID",
  1113              "hostname":"TestHostname",
  1114              "propertyId":123
  1115           },
  1116  		 {
  1117              "originId":"TestOriginID2",
  1118              "hostname":"TestHostname2",
  1119              "propertyId":1234
  1120           }
  1121        ],
  1122        "cdns":[
  1123           {
  1124              "cdnCode":"TestCDNCode",
  1125              "enabled":true,
  1126              "cdnAuthKeys":[
  1127                 {
  1128                    "authKeyName":"TestAuthKeyName",
  1129                    "headerName":"TestHeaderName",
  1130                    "secret":"testtesttesttesttesttest",
  1131                    "expiryDate":"TestExpiryDate"
  1132                 }
  1133              ],
  1134              "httpsOnly":true
  1135           },
  1136  		 {
  1137              "cdnCode":"TestCDNCode",
  1138              "enabled":true,
  1139              "httpsOnly":true,
  1140  			"ipAclCidrs": [
  1141  				"1.1.1.1/1"
  1142  			]
  1143           }
  1144        ],
  1145        "dataStreams":{
  1146           "enabled":true,
  1147  		 "dataStreamIds": [
  1148  			1
  1149  		 ],
  1150  		 "samplingRate": 10
  1151        },
  1152        "bocc":{
  1153           "enabled":true,
  1154  		 "conditionalSamplingFrequency": "ZERO",
  1155  		 "forwardType": "ORIGIN_AND_MIDGRESS",
  1156  		 "requestType": "EDGE_AND_MIDGRESS",
  1157  		 "samplingFrequency": "ZERO"
  1158        },
  1159  	  "enableSoftAlerts":true
  1160     },
  1161     "propertyIds":[
  1162        "123"
  1163     ],
  1164     "notificationEmails": [
  1165  		"test@test.com"
  1166     ],
  1167     "retainIdleObjects":true,
  1168     "contractId":"TestContractID",
  1169     "comments":"TestComments",
  1170     "configName":"TestConfigName"
  1171  }
  1172  `,
  1173  			expectedPath:   "/cloud-wrapper/v1/configurations?activate=false",
  1174  			responseStatus: 201,
  1175  			responseBody: `
  1176  {
  1177     "configId":111,
  1178     "capacityAlertsThreshold": 70,
  1179     "configName":"TestConfigName",
  1180     "contractId":"TestContractID",
  1181     "propertyIds":[
  1182        "123"
  1183     ],
  1184     "comments":"TestComments",
  1185     "status":"IN_PROGRESS",
  1186     "retainIdleObjects":true,
  1187     "locations":[
  1188        {
  1189           "trafficTypeId":1,
  1190           "comments":"TestComments",
  1191           "capacity":{
  1192              "value":1,
  1193              "unit":"GB"
  1194           },
  1195  		 "mapName": "cw-s-use"
  1196        },
  1197  	  {
  1198           "trafficTypeId":2,
  1199           "comments":"TestComments2",
  1200           "capacity":{
  1201              "value":2,
  1202              "unit":"TB"
  1203           },
  1204  		 "mapName": "cw-s-use"
  1205        }
  1206     ],
  1207     "multiCdnSettings":{
  1208        "origins":[
  1209           {
  1210              "originId":"TestOriginID",
  1211              "hostname":"TestHostname",
  1212              "propertyId":123
  1213           },
  1214  		 {
  1215              "originId":"TestOriginID2",
  1216              "hostname":"TestHostname2",
  1217              "propertyId":1234
  1218           }
  1219        ],
  1220        "cdns":[
  1221           {
  1222              "cdnCode":"TestCDNCode",
  1223              "enabled":true,
  1224              "cdnAuthKeys":[
  1225                 {
  1226                    "authKeyName":"TestAuthKeyName",
  1227                    "headerName":"TestHeaderName",
  1228                    "secret":"testtesttesttesttesttest",
  1229                    "expiryDate":"TestExpiryDate"
  1230                 }
  1231              ],
  1232              "ipAclCidrs":[],
  1233              "httpsOnly":true
  1234           },
  1235  		 {
  1236              "cdnCode":"TestCDNCode",
  1237              "enabled":true,
  1238              "httpsOnly":true,
  1239  			"ipAclCidrs": [
  1240  				"1.1.1.1/1"
  1241  			]
  1242           }
  1243        ],
  1244        "dataStreams":{
  1245           "enabled":true,
  1246  		 "dataStreamIds": [
  1247  			1
  1248  		 ],
  1249  		 "samplingRate": 10
  1250        },
  1251        "bocc":{
  1252           "enabled":true,
  1253  		 "conditionalSamplingFrequency": "ZERO",
  1254  		 "forwardType": "ORIGIN_AND_MIDGRESS",
  1255  		 "requestType": "EDGE_AND_MIDGRESS",
  1256  		 "samplingFrequency": "ZERO"
  1257        },
  1258        "enableSoftAlerts": true
  1259     },
  1260     "notificationEmails":[
  1261        "test@test.com"
  1262     ],
  1263     "lastUpdatedDate":"2022-06-10T13:21:14.488Z",
  1264     "lastUpdatedBy":"johndoe",
  1265     "lastActivatedDate":null,
  1266     "lastActivatedBy":null
  1267  }`,
  1268  			expectedResponse: &Configuration{
  1269  				CapacityAlertsThreshold: tools.IntPtr(70),
  1270  				Comments:                "TestComments",
  1271  				ContractID:              "TestContractID",
  1272  				Locations: []ConfigLocationResp{
  1273  					{
  1274  						Comments:      "TestComments",
  1275  						TrafficTypeID: 1,
  1276  						Capacity: Capacity{
  1277  							Unit:  "GB",
  1278  							Value: 1,
  1279  						},
  1280  						MapName: "cw-s-use",
  1281  					},
  1282  					{
  1283  						Comments:      "TestComments2",
  1284  						TrafficTypeID: 2,
  1285  						Capacity: Capacity{
  1286  							Unit:  "TB",
  1287  							Value: 2,
  1288  						},
  1289  						MapName: "cw-s-use",
  1290  					},
  1291  				},
  1292  				MultiCDNSettings: &MultiCDNSettings{
  1293  					BOCC: &BOCC{
  1294  						ConditionalSamplingFrequency: SamplingFrequencyZero,
  1295  						Enabled:                      true,
  1296  						ForwardType:                  ForwardTypeOriginAndMidgress,
  1297  						RequestType:                  RequestTypeEdgeAndMidgress,
  1298  						SamplingFrequency:            SamplingFrequencyZero,
  1299  					},
  1300  					CDNs: []CDN{
  1301  						{
  1302  							CDNAuthKeys: []CDNAuthKey{
  1303  								{
  1304  									AuthKeyName: "TestAuthKeyName",
  1305  									ExpiryDate:  "TestExpiryDate",
  1306  									HeaderName:  "TestHeaderName",
  1307  									Secret:      "testtesttesttesttesttest",
  1308  								},
  1309  							},
  1310  							CDNCode:    "TestCDNCode",
  1311  							Enabled:    true,
  1312  							IPACLCIDRs: []string{},
  1313  							HTTPSOnly:  true,
  1314  						},
  1315  						{
  1316  							CDNCode:    "TestCDNCode",
  1317  							Enabled:    true,
  1318  							IPACLCIDRs: []string{"1.1.1.1/1"},
  1319  							HTTPSOnly:  true,
  1320  						},
  1321  					},
  1322  					DataStreams: &DataStreams{
  1323  						DataStreamIDs: []int64{1},
  1324  						Enabled:       true,
  1325  						SamplingRate:  tools.IntPtr(10),
  1326  					},
  1327  					Origins: []Origin{
  1328  						{
  1329  							Hostname:   "TestHostname",
  1330  							OriginID:   "TestOriginID",
  1331  							PropertyID: 123,
  1332  						},
  1333  						{
  1334  							Hostname:   "TestHostname2",
  1335  							OriginID:   "TestOriginID2",
  1336  							PropertyID: 1234,
  1337  						},
  1338  					},
  1339  					EnableSoftAlerts: true,
  1340  				},
  1341  				RetainIdleObjects:  true,
  1342  				Status:             StatusInProgress,
  1343  				ConfigName:         "TestConfigName",
  1344  				LastUpdatedBy:      "johndoe",
  1345  				LastUpdatedDate:    "2022-06-10T13:21:14.488Z",
  1346  				NotificationEmails: []string{"test@test.com"},
  1347  				PropertyIDs:        []string{"123"},
  1348  				ConfigID:           111,
  1349  			},
  1350  		},
  1351  		"200 OK - BOCC struct fields default values": {
  1352  			params: CreateConfigurationRequest{
  1353  				Body: CreateConfigurationBody{
  1354  					Comments:   "TestComments",
  1355  					ContractID: "TestContractID",
  1356  					Locations: []ConfigLocationReq{
  1357  						{
  1358  							Comments:      "TestComments",
  1359  							TrafficTypeID: 1,
  1360  							Capacity: Capacity{
  1361  								Unit:  "GB",
  1362  								Value: 10,
  1363  							},
  1364  						},
  1365  					},
  1366  					MultiCDNSettings: &MultiCDNSettings{
  1367  						BOCC: &BOCC{},
  1368  						CDNs: []CDN{
  1369  							{
  1370  								CDNAuthKeys: []CDNAuthKey{
  1371  									{
  1372  										AuthKeyName: "TestAuthKeyName",
  1373  									},
  1374  								},
  1375  								CDNCode: "TestCDNCode",
  1376  								Enabled: true,
  1377  							},
  1378  						},
  1379  						DataStreams: &DataStreams{
  1380  							Enabled: true,
  1381  						},
  1382  						Origins: []Origin{
  1383  							{
  1384  								Hostname:   "TestHostname",
  1385  								OriginID:   "TestOriginID",
  1386  								PropertyID: 123,
  1387  							},
  1388  						},
  1389  					},
  1390  					ConfigName:  "TestConfigName",
  1391  					PropertyIDs: []string{"123"},
  1392  				},
  1393  			},
  1394  			expectedRequestBody: `
  1395  {
  1396     "locations":[
  1397        {
  1398           "capacity":{
  1399              "value":10,
  1400              "unit":"GB"
  1401           },
  1402           "comments":"TestComments",
  1403           "trafficTypeId":1
  1404        }
  1405     ],
  1406     "multiCdnSettings":{
  1407        "origins":[
  1408           {
  1409              "originId":"TestOriginID",
  1410              "hostname":"TestHostname",
  1411              "propertyId":123
  1412           }
  1413        ],
  1414        "cdns":[
  1415           {
  1416              "cdnCode":"TestCDNCode",
  1417              "enabled":true,
  1418              "cdnAuthKeys":[
  1419                 {
  1420                    "authKeyName":"TestAuthKeyName"
  1421                 }
  1422              ]
  1423           }
  1424        ],
  1425        "dataStreams":{
  1426           "enabled":true
  1427        },
  1428        "bocc":{
  1429           "enabled":false
  1430        }
  1431     },
  1432     "propertyIds":[
  1433        "123"
  1434     ],
  1435     "contractId":"TestContractID",
  1436     "comments":"TestComments",
  1437     "configName":"TestConfigName"
  1438  }`,
  1439  			expectedPath: "/cloud-wrapper/v1/configurations?activate=false",
  1440  			responseBody: `
  1441  {
  1442     "configId":111,
  1443     "capacityAlertsThreshold":null,
  1444     "configName":"TestConfigName",
  1445     "contractId":"TestContractID",
  1446     "propertyIds":[
  1447        "123"
  1448     ],
  1449     "comments":"TestComments",
  1450     "status":"IN_PROGRESS",
  1451     "retainIdleObjects":false,
  1452     "locations":[
  1453        {
  1454           "trafficTypeId":1,
  1455           "comments":"TestComments",
  1456           "capacity":{
  1457              "value":10,
  1458              "unit":"GB"
  1459           }
  1460        }
  1461     ],
  1462     "multiCdnSettings":{
  1463        "origins":[
  1464           {
  1465              "originId":"TestOriginID",
  1466              "hostname":"TestHostname",
  1467              "propertyId":123
  1468           }
  1469        ],
  1470        "cdns":[
  1471           {
  1472              "cdnCode":"TestCDNCode",
  1473              "enabled":true,
  1474              "cdnAuthKeys":[
  1475                 {
  1476                    "authKeyName":"TestAuthKeyName"
  1477                 }
  1478              ],
  1479              "ipAclCidrs":[]
  1480           }
  1481        ],
  1482        "dataStreams":{
  1483           "enabled":true
  1484        },
  1485        "bocc":{
  1486           "enabled":false
  1487        },
  1488        "enableSoftAlerts":false
  1489     },
  1490     "notificationEmails":[
  1491        
  1492     ],
  1493     "lastUpdatedDate":"2022-06-10T13:21:14.488Z",
  1494     "lastUpdatedBy":"johndoe",
  1495     "lastActivatedDate":null,
  1496     "lastActivatedBy":null
  1497  }`,
  1498  			responseStatus: 201,
  1499  			expectedResponse: &Configuration{
  1500  				Comments:   "TestComments",
  1501  				ContractID: "TestContractID",
  1502  				Status:     StatusInProgress,
  1503  				ConfigID:   111,
  1504  				Locations: []ConfigLocationResp{
  1505  					{
  1506  						Comments:      "TestComments",
  1507  						TrafficTypeID: 1,
  1508  						Capacity: Capacity{
  1509  							Unit:  "GB",
  1510  							Value: 10,
  1511  						},
  1512  					},
  1513  				},
  1514  				MultiCDNSettings: &MultiCDNSettings{
  1515  					BOCC: &BOCC{
  1516  						Enabled: false,
  1517  					},
  1518  					CDNs: []CDN{
  1519  						{
  1520  							CDNAuthKeys: []CDNAuthKey{
  1521  								{
  1522  									AuthKeyName: "TestAuthKeyName",
  1523  								},
  1524  							},
  1525  							CDNCode:    "TestCDNCode",
  1526  							Enabled:    true,
  1527  							IPACLCIDRs: []string{},
  1528  						},
  1529  					},
  1530  					DataStreams: &DataStreams{
  1531  						Enabled: true,
  1532  					},
  1533  					Origins: []Origin{
  1534  						{
  1535  							Hostname:   "TestHostname",
  1536  							OriginID:   "TestOriginID",
  1537  							PropertyID: 123,
  1538  						},
  1539  					},
  1540  				},
  1541  				ConfigName:         "TestConfigName",
  1542  				PropertyIDs:        []string{"123"},
  1543  				NotificationEmails: []string{},
  1544  				LastUpdatedBy:      "johndoe",
  1545  				LastUpdatedDate:    "2022-06-10T13:21:14.488Z",
  1546  			},
  1547  		},
  1548  		"200 OK - DataStreams struct fields default values": {
  1549  			params: CreateConfigurationRequest{
  1550  				Body: CreateConfigurationBody{
  1551  					Comments:   "TestComments",
  1552  					ContractID: "TestContractID",
  1553  					Locations: []ConfigLocationReq{
  1554  						{
  1555  							Comments:      "TestComments",
  1556  							TrafficTypeID: 1,
  1557  							Capacity: Capacity{
  1558  								Unit:  "GB",
  1559  								Value: 10,
  1560  							},
  1561  						},
  1562  					},
  1563  					MultiCDNSettings: &MultiCDNSettings{
  1564  						BOCC: &BOCC{},
  1565  						CDNs: []CDN{
  1566  							{
  1567  								CDNAuthKeys: []CDNAuthKey{
  1568  									{
  1569  										AuthKeyName: "TestAuthKeyName",
  1570  									},
  1571  								},
  1572  								CDNCode: "TestCDNCode",
  1573  								Enabled: true,
  1574  							},
  1575  						},
  1576  						DataStreams: &DataStreams{},
  1577  						Origins: []Origin{
  1578  							{
  1579  								Hostname:   "TestHostname",
  1580  								OriginID:   "TestOriginID",
  1581  								PropertyID: 123,
  1582  							},
  1583  						},
  1584  					},
  1585  					ConfigName:  "TestConfigName",
  1586  					PropertyIDs: []string{"123"},
  1587  				},
  1588  			},
  1589  			expectedRequestBody: `
  1590  {
  1591     "locations":[
  1592        {
  1593           "capacity":{
  1594              "value":10,
  1595              "unit":"GB"
  1596           },
  1597           "comments":"TestComments",
  1598           "trafficTypeId":1
  1599        }
  1600     ],
  1601     "multiCdnSettings":{
  1602        "origins":[
  1603           {
  1604              "originId":"TestOriginID",
  1605              "hostname":"TestHostname",
  1606              "propertyId":123
  1607           }
  1608        ],
  1609        "cdns":[
  1610           {
  1611              "cdnCode":"TestCDNCode",
  1612              "enabled":true,
  1613              "cdnAuthKeys":[
  1614                 {
  1615                    "authKeyName":"TestAuthKeyName"
  1616                 }
  1617              ]
  1618           }
  1619        ],
  1620        "dataStreams":{
  1621           "enabled":false
  1622        },
  1623        "bocc":{
  1624           "enabled":false
  1625        }
  1626     },
  1627     "propertyIds":[
  1628        "123"
  1629     ],
  1630     "contractId":"TestContractID",
  1631     "comments":"TestComments",
  1632     "configName":"TestConfigName"
  1633  }`,
  1634  			expectedPath: "/cloud-wrapper/v1/configurations?activate=false",
  1635  			responseBody: `
  1636  {
  1637     "configId":111,
  1638     "capacityAlertsThreshold":null,
  1639     "configName":"TestConfigName",
  1640     "contractId":"TestContractID",
  1641     "propertyIds":[
  1642        "123"
  1643     ],
  1644     "comments":"TestComments",
  1645     "status":"IN_PROGRESS",
  1646     "retainIdleObjects":false,
  1647     "locations":[
  1648        {
  1649           "trafficTypeId":1,
  1650           "comments":"TestComments",
  1651           "capacity":{
  1652              "value":10,
  1653              "unit":"GB"
  1654           },
  1655  		 "mapName": "cw-s-use"
  1656        }
  1657     ],
  1658     "multiCdnSettings":{
  1659        "origins":[
  1660           {
  1661              "originId":"TestOriginID",
  1662              "hostname":"TestHostname",
  1663              "propertyId":123
  1664           }
  1665        ],
  1666        "cdns":[
  1667           {
  1668              "cdnCode":"TestCDNCode",
  1669              "enabled":true,
  1670              "cdnAuthKeys":[
  1671                 {
  1672                    "authKeyName":"TestAuthKeyName"
  1673                 }
  1674              ],
  1675              "ipAclCidrs":[]
  1676           }
  1677        ],
  1678        "dataStreams":{
  1679           "enabled":false,
  1680  		 "dataStreamsIds": []
  1681        },
  1682        "bocc":{
  1683           "enabled":false
  1684        },
  1685        "enableSoftAlerts":false
  1686     },
  1687     "notificationEmails":[],
  1688     "lastUpdatedDate":"2022-06-10T13:21:14.488Z",
  1689     "lastUpdatedBy":"johndoe",
  1690     "lastActivatedDate":null,
  1691     "lastActivatedBy":null
  1692  }`,
  1693  			responseStatus: 201,
  1694  			expectedResponse: &Configuration{
  1695  				Comments:   "TestComments",
  1696  				ContractID: "TestContractID",
  1697  				Status:     StatusInProgress,
  1698  				ConfigID:   111,
  1699  				Locations: []ConfigLocationResp{
  1700  					{
  1701  						Comments:      "TestComments",
  1702  						TrafficTypeID: 1,
  1703  						Capacity: Capacity{
  1704  							Unit:  "GB",
  1705  							Value: 10,
  1706  						},
  1707  						MapName: "cw-s-use",
  1708  					},
  1709  				},
  1710  				MultiCDNSettings: &MultiCDNSettings{
  1711  					BOCC: &BOCC{
  1712  						Enabled: false,
  1713  					},
  1714  					CDNs: []CDN{
  1715  						{
  1716  							CDNAuthKeys: []CDNAuthKey{
  1717  								{
  1718  									AuthKeyName: "TestAuthKeyName",
  1719  								},
  1720  							},
  1721  							CDNCode:    "TestCDNCode",
  1722  							Enabled:    true,
  1723  							IPACLCIDRs: []string{},
  1724  						},
  1725  					},
  1726  					DataStreams: &DataStreams{
  1727  						Enabled: false,
  1728  					},
  1729  					Origins: []Origin{
  1730  						{
  1731  							Hostname:   "TestHostname",
  1732  							OriginID:   "TestOriginID",
  1733  							PropertyID: 123,
  1734  						},
  1735  					},
  1736  				},
  1737  				ConfigName:         "TestConfigName",
  1738  				PropertyIDs:        []string{"123"},
  1739  				NotificationEmails: []string{},
  1740  				LastUpdatedBy:      "johndoe",
  1741  				LastUpdatedDate:    "2022-06-10T13:21:14.488Z",
  1742  			},
  1743  		},
  1744  		"missing required params: comments, configName, contractID, locations and propertyIDs - validation error": {
  1745  			params: CreateConfigurationRequest{},
  1746  			withError: func(t *testing.T, err error) {
  1747  				assert.Equal(t, "create configuration: struct validation: Comments: cannot be blank\nConfigName: cannot be blank\nContractID: cannot be blank\nLocations: cannot be blank\nPropertyIDs: cannot be blank", err.Error())
  1748  			},
  1749  		},
  1750  		"missing required params - location fields": {
  1751  			params: CreateConfigurationRequest{
  1752  				Body: CreateConfigurationBody{
  1753  					Comments:   "TestComments",
  1754  					ContractID: "TestContractID",
  1755  					Locations: []ConfigLocationReq{
  1756  						{
  1757  							Comments:      "",
  1758  							TrafficTypeID: 0,
  1759  							Capacity:      Capacity{},
  1760  						},
  1761  					},
  1762  					ConfigName:  "TestConfigName",
  1763  					PropertyIDs: []string{"1"},
  1764  				},
  1765  			},
  1766  			withError: func(t *testing.T, err error) {
  1767  				assert.Equal(t, "create configuration: struct validation: Locations[0]: {\n\tUnit: cannot be blank\n\tValue: cannot be blank\n\tComments: cannot be blank\n\tTrafficTypeID: cannot be blank\n}", err.Error())
  1768  			},
  1769  		},
  1770  		"missing required params - multiCDN fields": {
  1771  			params: CreateConfigurationRequest{
  1772  				Body: CreateConfigurationBody{
  1773  					Comments:   "TestComments",
  1774  					ContractID: "TestContractID",
  1775  					Locations: []ConfigLocationReq{
  1776  						{
  1777  							Comments:      "TestComments",
  1778  							TrafficTypeID: 5,
  1779  							Capacity: Capacity{
  1780  								Unit:  "GB",
  1781  								Value: 10,
  1782  							},
  1783  						},
  1784  					},
  1785  					MultiCDNSettings: &MultiCDNSettings{},
  1786  					ConfigName:       "TestConfigName",
  1787  					PropertyIDs:      []string{"1"},
  1788  				},
  1789  			},
  1790  			withError: func(t *testing.T, err error) {
  1791  				assert.Equal(t, "create configuration: struct validation: BOCC: cannot be blank\nCDNs: cannot be blank\nDataStreams: cannot be blank\nOrigins: cannot be blank", err.Error())
  1792  			},
  1793  		},
  1794  		"missing required params - BOCC struct fields when enabled": {
  1795  			params: CreateConfigurationRequest{
  1796  				Body: CreateConfigurationBody{
  1797  					Comments:   "TestComments",
  1798  					ContractID: "TestContractID",
  1799  					Locations: []ConfigLocationReq{
  1800  						{
  1801  							Comments:      "TestComments",
  1802  							TrafficTypeID: 5,
  1803  							Capacity: Capacity{
  1804  								Unit:  "GB",
  1805  								Value: 10,
  1806  							},
  1807  						},
  1808  					},
  1809  					MultiCDNSettings: &MultiCDNSettings{
  1810  						BOCC: &BOCC{
  1811  							Enabled: true,
  1812  						},
  1813  						CDNs: []CDN{
  1814  							{
  1815  								CDNAuthKeys: []CDNAuthKey{
  1816  									{AuthKeyName: "TestAuthKeyName"},
  1817  								},
  1818  								CDNCode: "TestCDNCode",
  1819  								Enabled: true,
  1820  							},
  1821  						},
  1822  						DataStreams: &DataStreams{
  1823  							Enabled: true,
  1824  						},
  1825  						Origins: []Origin{
  1826  							{
  1827  								Hostname:   "TestHostname",
  1828  								OriginID:   "TestOriginID",
  1829  								PropertyID: 1,
  1830  							},
  1831  						},
  1832  					},
  1833  					ConfigName:  "TestConfigName",
  1834  					PropertyIDs: []string{"1"},
  1835  				},
  1836  			},
  1837  			withError: func(t *testing.T, err error) {
  1838  				assert.Equal(t, "create configuration: struct validation: ConditionalSamplingFrequency: cannot be blank\nForwardType: cannot be blank\nRequestType: cannot be blank\nSamplingFrequency: cannot be blank", err.Error())
  1839  			},
  1840  		},
  1841  		"missing required params - Origin struct fields": {
  1842  			params: CreateConfigurationRequest{
  1843  				Body: CreateConfigurationBody{Comments: "TestComments",
  1844  					ContractID: "TestContractID",
  1845  					Locations: []ConfigLocationReq{
  1846  						{
  1847  							Comments:      "TestComments",
  1848  							TrafficTypeID: 5,
  1849  							Capacity: Capacity{
  1850  								Unit:  "GB",
  1851  								Value: 10,
  1852  							},
  1853  						},
  1854  					},
  1855  					MultiCDNSettings: &MultiCDNSettings{
  1856  						BOCC: &BOCC{
  1857  							Enabled: false,
  1858  						},
  1859  						CDNs: []CDN{
  1860  							{
  1861  								CDNCode:    "TestCDNCode",
  1862  								Enabled:    true,
  1863  								IPACLCIDRs: []string{"1.1.1.1/1"},
  1864  							},
  1865  						},
  1866  						DataStreams: &DataStreams{
  1867  							Enabled: true,
  1868  						},
  1869  						Origins: []Origin{
  1870  							{},
  1871  						},
  1872  					},
  1873  					ConfigName:  "TestConfigName",
  1874  					PropertyIDs: []string{"1"},
  1875  				},
  1876  			},
  1877  			withError: func(t *testing.T, err error) {
  1878  				assert.Equal(t, "create configuration: struct validation: Origins[0]: {\n\tHostname: cannot be blank\n\tOriginID: cannot be blank\n\tPropertyID: cannot be blank\n}", err.Error())
  1879  			},
  1880  		},
  1881  		"validation error - at least one CDN must be enabled": {
  1882  			params: CreateConfigurationRequest{
  1883  				Body: CreateConfigurationBody{
  1884  					Comments:   "TestComments",
  1885  					ContractID: "TestContractID",
  1886  					Locations: []ConfigLocationReq{
  1887  						{
  1888  							Comments:      "TestComments",
  1889  							TrafficTypeID: 5,
  1890  							Capacity: Capacity{
  1891  								Unit:  "GB",
  1892  								Value: 10,
  1893  							},
  1894  						},
  1895  					},
  1896  					MultiCDNSettings: &MultiCDNSettings{
  1897  						BOCC: &BOCC{
  1898  							Enabled: false,
  1899  						},
  1900  						CDNs: []CDN{
  1901  							{
  1902  								CDNCode:    "TestCDNCode",
  1903  								Enabled:    false,
  1904  								IPACLCIDRs: []string{"1.1.1.1/1"},
  1905  							},
  1906  							{
  1907  								CDNCode:    "TestCDNCode",
  1908  								Enabled:    false,
  1909  								IPACLCIDRs: []string{"1.1.1.1/1"},
  1910  							},
  1911  						},
  1912  						DataStreams: &DataStreams{
  1913  							Enabled: false,
  1914  						},
  1915  						Origins: []Origin{
  1916  							{
  1917  								Hostname:   "TestHostname",
  1918  								OriginID:   "TestOriginID",
  1919  								PropertyID: 1,
  1920  							},
  1921  						},
  1922  					},
  1923  					ConfigName:  "TestConfigName",
  1924  					PropertyIDs: []string{"1"},
  1925  				},
  1926  			},
  1927  			withError: func(t *testing.T, err error) {
  1928  				assert.Equal(t, "create configuration: struct validation: CDNs: at least one of CDNs must be enabled", err.Error())
  1929  			},
  1930  		},
  1931  		"validation error - authKeys nor IPACLCIDRs specified": {
  1932  			params: CreateConfigurationRequest{
  1933  				Body: CreateConfigurationBody{
  1934  					Comments:   "TestComments",
  1935  					ContractID: "TestContractID",
  1936  					Locations: []ConfigLocationReq{
  1937  						{
  1938  							Comments:      "TestComments",
  1939  							TrafficTypeID: 5,
  1940  							Capacity: Capacity{
  1941  								Unit:  "GB",
  1942  								Value: 10,
  1943  							},
  1944  						},
  1945  					},
  1946  					MultiCDNSettings: &MultiCDNSettings{
  1947  						BOCC: &BOCC{
  1948  							Enabled: false,
  1949  						},
  1950  						CDNs: []CDN{
  1951  							{
  1952  								CDNCode: "TestCDNCode",
  1953  								Enabled: false,
  1954  							},
  1955  						},
  1956  						DataStreams: &DataStreams{
  1957  							Enabled: false,
  1958  						},
  1959  						Origins: []Origin{
  1960  							{
  1961  								Hostname:   "TestHostname",
  1962  								OriginID:   "TestOriginID",
  1963  								PropertyID: 1,
  1964  							},
  1965  						},
  1966  					},
  1967  					ConfigName:  "TestConfigName",
  1968  					PropertyIDs: []string{"1"},
  1969  				},
  1970  			},
  1971  			withError: func(t *testing.T, err error) {
  1972  				assert.Equal(t, "create configuration: struct validation: CDNs: at least one authentication method is required for CDN. Either IP ACL or header authentication must be enabled", err.Error())
  1973  			},
  1974  		},
  1975  		"struct fields validations": {
  1976  			params: CreateConfigurationRequest{
  1977  				Body: CreateConfigurationBody{
  1978  					CapacityAlertsThreshold: tools.IntPtr(20),
  1979  					Comments:                "TestComments",
  1980  					ContractID:              "TestContractID",
  1981  					Locations: []ConfigLocationReq{
  1982  						{
  1983  							Comments:      "TestComments",
  1984  							TrafficTypeID: 5,
  1985  							Capacity: Capacity{
  1986  								Unit:  "MB",
  1987  								Value: 10,
  1988  							},
  1989  						},
  1990  					},
  1991  					MultiCDNSettings: &MultiCDNSettings{
  1992  						BOCC: &BOCC{
  1993  							ConditionalSamplingFrequency: "a",
  1994  							Enabled:                      false,
  1995  							ForwardType:                  "a",
  1996  							RequestType:                  "a",
  1997  							SamplingFrequency:            "a",
  1998  						},
  1999  						CDNs: []CDN{
  2000  							{
  2001  								CDNCode:    "TestCDNCode",
  2002  								Enabled:    true,
  2003  								IPACLCIDRs: []string{"1.1.1.1/1"},
  2004  							},
  2005  							{
  2006  								CDNAuthKeys: []CDNAuthKey{
  2007  									{},
  2008  								},
  2009  								CDNCode: "TestCDNCode",
  2010  								Enabled: true,
  2011  							},
  2012  						},
  2013  						DataStreams: &DataStreams{
  2014  							DataStreamIDs: []int64{1},
  2015  							Enabled:       true,
  2016  							SamplingRate:  tools.IntPtr(-10),
  2017  						},
  2018  						Origins: []Origin{
  2019  							{
  2020  								Hostname:   "TestHostname",
  2021  								OriginID:   "TestOriginID",
  2022  								PropertyID: 1,
  2023  							},
  2024  						},
  2025  					},
  2026  					ConfigName:  "TestConfigName",
  2027  					PropertyIDs: []string{"1"},
  2028  				},
  2029  			},
  2030  			withError: func(t *testing.T, err error) {
  2031  				assert.Equal(t, "create configuration: struct validation: CapacityAlertsThreshold: must be no less than 50\nLocations[0]: {\n\tUnit: value 'MB' is invalid. Must be one of: 'GB', 'TB'\n}\nConditionalSamplingFrequency: value 'a' is invalid. Must be one of: 'ZERO', 'ONE_TENTH'\nForwardType: value 'a' is invalid. Must be one of: 'ORIGIN_ONLY', 'MIDGRESS_ONLY', 'ORIGIN_AND_MIDGRESS'\nRequestType: value 'a' is invalid. Must be one of: 'EDGE_ONLY', 'EDGE_AND_MIDGRESS'\nSamplingFrequency: value 'a' is invalid. Must be one of: 'ZERO', 'ONE_TENTH'\nCDNs[1]: {\n\tCDNAuthKeys[0]: {\n\t\tAuthKeyName: cannot be blank\n\t}\n}\nSamplingRate: must be no less than 1", err.Error())
  2032  			},
  2033  		},
  2034  		"500 internal server error": {
  2035  			params: CreateConfigurationRequest{
  2036  				Body: CreateConfigurationBody{
  2037  					Comments:   "TestComments",
  2038  					ContractID: "TestContractID",
  2039  					Locations: []ConfigLocationReq{
  2040  						{
  2041  							Comments:      "TestComments",
  2042  							TrafficTypeID: 1,
  2043  							Capacity: Capacity{
  2044  								Unit:  "GB",
  2045  								Value: 1,
  2046  							},
  2047  						},
  2048  					},
  2049  					ConfigName:  "TestConfigName",
  2050  					PropertyIDs: []string{"123"},
  2051  				},
  2052  			},
  2053  			responseStatus: http.StatusInternalServerError,
  2054  			responseBody: `
  2055  {
  2056      "type": "/cloudwrapper/error-types/cloudwrapper-server-error",
  2057      "title": "An unexpected error has occurred.",
  2058      "detail": "Error processing request",
  2059      "instance": "/cloudwrapper/error-instances/abc",
  2060      "status": 500
  2061  }`,
  2062  			expectedPath: "/cloud-wrapper/v1/configurations?activate=false",
  2063  			withError: func(t *testing.T, err error) {
  2064  				want := &Error{
  2065  					Type:     "/cloudwrapper/error-types/cloudwrapper-server-error",
  2066  					Title:    "An unexpected error has occurred.",
  2067  					Detail:   "Error processing request",
  2068  					Instance: "/cloudwrapper/error-instances/abc",
  2069  					Status:   500,
  2070  				}
  2071  				assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err)
  2072  			},
  2073  		},
  2074  	}
  2075  
  2076  	for name, test := range tests {
  2077  		if name != "200 OK - full MultiCDNSettings" {
  2078  			continue
  2079  		}
  2080  		t.Run(name, func(t *testing.T) {
  2081  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  2082  				assert.Equal(t, test.expectedPath, r.URL.String())
  2083  				assert.Equal(t, http.MethodPost, r.Method)
  2084  				if test.expectedRequestBody != "" {
  2085  					body, err := io.ReadAll(r.Body)
  2086  					require.NoError(t, err)
  2087  					assert.JSONEq(t, test.expectedRequestBody, string(body))
  2088  				}
  2089  				w.WriteHeader(test.responseStatus)
  2090  				_, err := w.Write([]byte(test.responseBody))
  2091  				assert.NoError(t, err)
  2092  			}))
  2093  			client := mockAPIClient(t, mockServer)
  2094  			result, err := client.CreateConfiguration(context.Background(), test.params)
  2095  			if test.withError != nil {
  2096  				test.withError(t, err)
  2097  				return
  2098  			}
  2099  			require.NoError(t, err)
  2100  			assert.Equal(t, test.expectedResponse, result)
  2101  		})
  2102  	}
  2103  }
  2104  
  2105  func TestUpdateConfiguration(t *testing.T) {
  2106  	tests := map[string]struct {
  2107  		params              UpdateConfigurationRequest
  2108  		expectedRequestBody string
  2109  		expectedPath        string
  2110  		responseStatus      int
  2111  		responseBody        string
  2112  		expectedResponse    *Configuration
  2113  		withError           func(*testing.T, error)
  2114  	}{
  2115  		"200 OK - minimal": {
  2116  			params: UpdateConfigurationRequest{
  2117  				ConfigID: 111,
  2118  				Body: UpdateConfigurationBody{
  2119  					Comments: "TestCommentsUpdated",
  2120  					Locations: []ConfigLocationReq{
  2121  						{
  2122  							Comments:      "TestCommentsUpdated",
  2123  							TrafficTypeID: 1,
  2124  							Capacity: Capacity{
  2125  								Unit:  "GB",
  2126  								Value: 1,
  2127  							},
  2128  						},
  2129  					},
  2130  					PropertyIDs: []string{
  2131  						"123",
  2132  					},
  2133  				},
  2134  			},
  2135  			expectedRequestBody: `
  2136  {
  2137     "locations":[
  2138        {
  2139           "capacity":{
  2140              "value":1,
  2141              "unit":"GB"
  2142           },
  2143           "comments":"TestCommentsUpdated",
  2144           "trafficTypeId":1
  2145        }
  2146     ],
  2147     "propertyIds":[
  2148        "123"
  2149     ],
  2150     "comments":"TestCommentsUpdated"
  2151  }`,
  2152  			expectedPath:   "/cloud-wrapper/v1/configurations/111?activate=false",
  2153  			responseStatus: 200,
  2154  			responseBody: `
  2155  {
  2156     "configId":111,
  2157     "configName":"TestConfigName",
  2158     "contractId":"TestContractID",
  2159     "propertyIds":[
  2160        "123"
  2161     ],
  2162     "comments":"TestCommentsUpdated",
  2163     "status":"IN_PROGRESS",
  2164     "retainIdleObjects":false,
  2165     "locations":[
  2166        {
  2167           "trafficTypeId":1,
  2168           "comments":"TestCommentsUpdated",
  2169           "capacity":{
  2170              "value":1,
  2171              "unit":"GB"
  2172           },
  2173  		 "mapName": "cw-s-use"
  2174        }
  2175     ],
  2176     "multiCdnSettings":null,
  2177     "capacityAlertsThreshold":50,
  2178     "notificationEmails":[
  2179        
  2180     ],
  2181     "lastUpdatedDate":"2022-06-10T13:21:14.488Z",
  2182     "lastUpdatedBy":"johndoe",
  2183     "lastActivatedDate":null,
  2184     "lastActivatedBy":null
  2185  }`,
  2186  			expectedResponse: &Configuration{
  2187  				ConfigID:                111,
  2188  				CapacityAlertsThreshold: tools.IntPtr(50),
  2189  				Comments:                "TestCommentsUpdated",
  2190  				ContractID:              "TestContractID",
  2191  				Locations: []ConfigLocationResp{
  2192  					{
  2193  						Comments:      "TestCommentsUpdated",
  2194  						TrafficTypeID: 1,
  2195  						Capacity: Capacity{
  2196  							Unit:  "GB",
  2197  							Value: 1,
  2198  						},
  2199  						MapName: "cw-s-use",
  2200  					},
  2201  				},
  2202  				Status:             StatusInProgress,
  2203  				ConfigName:         "TestConfigName",
  2204  				LastUpdatedBy:      "johndoe",
  2205  				LastUpdatedDate:    "2022-06-10T13:21:14.488Z",
  2206  				NotificationEmails: []string{},
  2207  				PropertyIDs:        []string{"123"},
  2208  				RetainIdleObjects:  false,
  2209  			},
  2210  		},
  2211  		"200 OK - minimal MultiCDNSettings": {
  2212  			params: UpdateConfigurationRequest{
  2213  				ConfigID: 111,
  2214  				Body: UpdateConfigurationBody{
  2215  					Comments: "TestCommentsUpdated",
  2216  					Locations: []ConfigLocationReq{
  2217  						{
  2218  							Comments:      "TestCommentsUpdated",
  2219  							TrafficTypeID: 1,
  2220  							Capacity: Capacity{
  2221  								Unit:  "GB",
  2222  								Value: 1,
  2223  							},
  2224  						},
  2225  					},
  2226  					PropertyIDs: []string{
  2227  						"123",
  2228  					},
  2229  					MultiCDNSettings: &MultiCDNSettings{
  2230  						BOCC: &BOCC{
  2231  							Enabled: false,
  2232  						},
  2233  						CDNs: []CDN{
  2234  							{
  2235  								CDNCode: "TestCDNCode",
  2236  								Enabled: true,
  2237  								IPACLCIDRs: []string{
  2238  									"1.1.1.1/1",
  2239  								},
  2240  							},
  2241  						},
  2242  						DataStreams: &DataStreams{
  2243  							Enabled: false,
  2244  						},
  2245  						Origins: []Origin{
  2246  							{
  2247  								Hostname:   "TestHostname",
  2248  								OriginID:   "TestOriginID",
  2249  								PropertyID: 123,
  2250  							},
  2251  						},
  2252  					},
  2253  				},
  2254  			},
  2255  			expectedRequestBody: `
  2256  {
  2257     "locations":[
  2258        {
  2259           "capacity":{
  2260              "value":1,
  2261              "unit":"GB"
  2262           },
  2263           "comments":"TestCommentsUpdated",
  2264           "trafficTypeId":1
  2265        }
  2266     ],
  2267     "multiCdnSettings":{
  2268        "origins":[
  2269           {
  2270              "originId":"TestOriginID",
  2271              "hostname":"TestHostname",
  2272              "propertyId":123
  2273           }
  2274        ],
  2275        "cdns":[
  2276           {
  2277              "cdnCode":"TestCDNCode",
  2278              "enabled":true,
  2279              "ipAclCidrs":[
  2280                 "1.1.1.1/1"
  2281              ]
  2282           }
  2283        ],
  2284        "dataStreams":{
  2285           "enabled":false
  2286        },
  2287        "bocc":{
  2288           "enabled":false
  2289        }
  2290     },
  2291     "propertyIds":[
  2292        "123"
  2293     ],
  2294     "comments":"TestCommentsUpdated"
  2295  }`,
  2296  			expectedPath:   "/cloud-wrapper/v1/configurations/111?activate=false",
  2297  			responseStatus: 200,
  2298  			responseBody: `
  2299  {
  2300     "configId":111,
  2301     "configName":"TestConfigName",
  2302     "contractId":"TestContractID",
  2303     "propertyIds":[
  2304        "123"
  2305     ],
  2306     "comments":"TestCommentsUpdated",
  2307     "status":"IN_PROGRESS",
  2308     "retainIdleObjects":false,
  2309     "locations":[
  2310        {
  2311           "trafficTypeId":1,
  2312           "comments":"TestCommentsUpdated",
  2313           "capacity":{
  2314              "value":1,
  2315              "unit":"GB"
  2316           },
  2317  		 "mapName": "cw-s-use"
  2318        }
  2319     ],
  2320     "multiCdnSettings":{
  2321        "origins":[
  2322           {
  2323              "originId":"TestOriginID",
  2324              "hostname":"TestHostname",
  2325              "propertyId":123
  2326           }
  2327        ],
  2328        "cdns":[
  2329           {
  2330              "cdnCode":"TestCDNCode",
  2331              "enabled":true,
  2332              "cdnAuthKeys":[],
  2333              "ipAclCidrs":[
  2334                 "1.1.1.1/1"
  2335              ],
  2336              "httpsOnly":false
  2337           }
  2338        ],
  2339        "dataStreams":{
  2340           "enabled":false
  2341        },
  2342        "bocc":{
  2343           "enabled":false
  2344        },
  2345        "enableSoftAlerts":false
  2346     },
  2347     "capacityAlertsThreshold":null,
  2348     "notificationEmails":[],
  2349     "lastUpdatedDate":"2022-06-10T13:21:14.488Z",
  2350     "lastUpdatedBy":"johndoe",
  2351     "lastActivatedDate":null,
  2352     "lastActivatedBy":null
  2353  }`,
  2354  			expectedResponse: &Configuration{
  2355  				ConfigID:   111,
  2356  				Comments:   "TestCommentsUpdated",
  2357  				ContractID: "TestContractID",
  2358  				Locations: []ConfigLocationResp{
  2359  					{
  2360  						Comments:      "TestCommentsUpdated",
  2361  						TrafficTypeID: 1,
  2362  						Capacity: Capacity{
  2363  							Unit:  "GB",
  2364  							Value: 1,
  2365  						},
  2366  						MapName: "cw-s-use",
  2367  					},
  2368  				},
  2369  				MultiCDNSettings: &MultiCDNSettings{
  2370  					BOCC: &BOCC{
  2371  						Enabled: false,
  2372  					},
  2373  					CDNs: []CDN{
  2374  						{
  2375  							CDNAuthKeys: []CDNAuthKey{},
  2376  							CDNCode:     "TestCDNCode",
  2377  							Enabled:     true,
  2378  							HTTPSOnly:   false,
  2379  							IPACLCIDRs: []string{
  2380  								"1.1.1.1/1",
  2381  							},
  2382  						},
  2383  					},
  2384  					DataStreams: &DataStreams{
  2385  						Enabled: false,
  2386  					},
  2387  					EnableSoftAlerts: false,
  2388  					Origins: []Origin{
  2389  						{
  2390  							Hostname:   "TestHostname",
  2391  							OriginID:   "TestOriginID",
  2392  							PropertyID: 123,
  2393  						},
  2394  					},
  2395  				},
  2396  				Status:             StatusInProgress,
  2397  				ConfigName:         "TestConfigName",
  2398  				LastUpdatedBy:      "johndoe",
  2399  				LastUpdatedDate:    "2022-06-10T13:21:14.488Z",
  2400  				NotificationEmails: []string{},
  2401  				PropertyIDs:        []string{"123"},
  2402  				RetainIdleObjects:  false,
  2403  			},
  2404  		},
  2405  		"200 OK - all fields": {
  2406  			params: UpdateConfigurationRequest{
  2407  				ConfigID: 111,
  2408  				Body: UpdateConfigurationBody{
  2409  					CapacityAlertsThreshold: tools.IntPtr(80),
  2410  					Comments:                "TestCommentsUpdated",
  2411  					Locations: []ConfigLocationReq{
  2412  						{
  2413  							Comments:      "TestCommentsUpdated",
  2414  							TrafficTypeID: 1,
  2415  							Capacity: Capacity{
  2416  								Unit:  "GB",
  2417  								Value: 1,
  2418  							},
  2419  						},
  2420  					},
  2421  					MultiCDNSettings: &MultiCDNSettings{
  2422  						BOCC: &BOCC{
  2423  							ConditionalSamplingFrequency: SamplingFrequencyZero,
  2424  							Enabled:                      true,
  2425  							ForwardType:                  ForwardTypeOriginAndMidgress,
  2426  							RequestType:                  RequestTypeEdgeAndMidgress,
  2427  							SamplingFrequency:            SamplingFrequencyZero,
  2428  						},
  2429  						CDNs: []CDN{
  2430  							{
  2431  								CDNAuthKeys: []CDNAuthKey{
  2432  									{
  2433  										AuthKeyName: "TestAuthKeyName",
  2434  										ExpiryDate:  "TestExpiryDate",
  2435  										HeaderName:  "TestHeaderName",
  2436  										Secret:      "TestSecretTestSecret1234",
  2437  									},
  2438  								},
  2439  								CDNCode: "TestCDNCode",
  2440  								Enabled: true,
  2441  								IPACLCIDRs: []string{
  2442  									"1.1.1.1/1",
  2443  								},
  2444  								HTTPSOnly: true,
  2445  							},
  2446  						},
  2447  						DataStreams: &DataStreams{
  2448  							DataStreamIDs: []int64{1},
  2449  							Enabled:       true,
  2450  							SamplingRate:  tools.IntPtr(10),
  2451  						},
  2452  						Origins: []Origin{
  2453  							{
  2454  								Hostname:   "TestHostname",
  2455  								OriginID:   "TestOriginID",
  2456  								PropertyID: 123,
  2457  							},
  2458  						},
  2459  					},
  2460  					NotificationEmails: []string{
  2461  						"test@test.com",
  2462  					},
  2463  					PropertyIDs: []string{
  2464  						"123",
  2465  					},
  2466  					RetainIdleObjects: true,
  2467  				},
  2468  			},
  2469  			expectedRequestBody: `
  2470  {
  2471     "capacityAlertsThreshold":80,
  2472     "locations":[
  2473        {
  2474           "capacity":{
  2475              "value":1,
  2476              "unit":"GB"
  2477           },
  2478           "comments":"TestCommentsUpdated",
  2479           "trafficTypeId":1
  2480        }
  2481     ],
  2482     "multiCdnSettings":{
  2483        "origins":[
  2484           {
  2485              "originId":"TestOriginID",
  2486              "hostname":"TestHostname",
  2487              "propertyId":123
  2488           }
  2489        ],
  2490        "cdns":[
  2491           {
  2492              "cdnAuthKeys":[
  2493                 {
  2494                    "authKeyName":"TestAuthKeyName",
  2495                    "expiryDate":"TestExpiryDate",
  2496                    "headerName":"TestHeaderName",
  2497                    "secret":"TestSecretTestSecret1234"
  2498                 }
  2499              ],
  2500              "cdnCode":"TestCDNCode",
  2501              "enabled":true,
  2502              "ipAclCidrs":[
  2503                 "1.1.1.1/1"
  2504              ],
  2505              "httpsOnly":true
  2506           }
  2507        ],
  2508        "dataStreams":{
  2509           "enabled":true,
  2510           "dataStreamIds":[
  2511              1
  2512           ],
  2513           "samplingRate":10
  2514        },
  2515        "bocc":{
  2516           "enabled":true,
  2517           "conditionalSamplingFrequency":"ZERO",
  2518           "forwardType":"ORIGIN_AND_MIDGRESS",
  2519           "requestType":"EDGE_AND_MIDGRESS",
  2520           "samplingFrequency":"ZERO"
  2521        }
  2522     },
  2523     "propertyIds":[
  2524        "123"
  2525     ],
  2526     "notificationEmails":[
  2527        "test@test.com"
  2528     ],
  2529     "retainIdleObjects":true,
  2530     "comments":"TestCommentsUpdated"
  2531  }
  2532  `,
  2533  			expectedPath:   "/cloud-wrapper/v1/configurations/111?activate=false",
  2534  			responseStatus: 200,
  2535  			responseBody: `
  2536  {
  2537     "configId":111,
  2538     "configName":"TestConfigName",
  2539     "contractId":"TestContractID",
  2540     "propertyIds":[
  2541        "123"
  2542     ],
  2543     "comments":"TestCommentsUpdated",
  2544     "status":"IN_PROGRESS",
  2545     "retainIdleObjects":true,
  2546     "locations":[
  2547        {
  2548           "trafficTypeId":1,
  2549           "comments":"TestCommentsUpdated",
  2550           "capacity":{
  2551              "value":1,
  2552              "unit":"GB"
  2553           },
  2554  		 "mapName": "cw-s-use"
  2555        }
  2556     ],
  2557     "multiCdnSettings":{
  2558        "origins":[
  2559           {
  2560              "originId":"TestOriginID",
  2561              "hostname":"TestHostname",
  2562              "propertyId":123
  2563           }
  2564        ],
  2565        "cdns":[
  2566           {
  2567              "cdnCode":"TestCDNCode",
  2568              "enabled":true,
  2569              "cdnAuthKeys":[
  2570                 {
  2571                    "authKeyName":"TestAuthKeyName",
  2572                    "expiryDate":"TestExpiryDate",
  2573                    "headerName":"TestHeaderName",
  2574                    "secret":"TestSecretTestSecret1234"
  2575                 }
  2576              ],
  2577              "ipAclCidrs":[
  2578                 "1.1.1.1/1"
  2579              ],
  2580              "httpsOnly":true
  2581           }
  2582        ],
  2583        "dataStreams":{
  2584           "enabled":true,
  2585           "dataStreamIds":[
  2586              1
  2587           ],
  2588           "samplingRate":10
  2589        },
  2590        "bocc":{
  2591           "enabled":true,
  2592           "conditionalSamplingFrequency":"ZERO",
  2593           "forwardType":"ORIGIN_AND_MIDGRESS",
  2594           "requestType":"EDGE_AND_MIDGRESS",
  2595           "samplingFrequency":"ZERO"
  2596        },
  2597        "enableSoftAlerts":true
  2598     },
  2599     "capacityAlertsThreshold":80,
  2600     "notificationEmails":[
  2601        "test@test.com"
  2602     ],
  2603     "lastUpdatedDate":"2022-06-10T13:21:14.488Z",
  2604     "lastUpdatedBy":"johndoe",
  2605     "lastActivatedDate":null,
  2606     "lastActivatedBy":null
  2607  }`,
  2608  			expectedResponse: &Configuration{
  2609  				CapacityAlertsThreshold: tools.IntPtr(80),
  2610  				Comments:                "TestCommentsUpdated",
  2611  				ContractID:              "TestContractID",
  2612  				ConfigID:                111,
  2613  				Locations: []ConfigLocationResp{
  2614  					{
  2615  						Comments:      "TestCommentsUpdated",
  2616  						TrafficTypeID: 1,
  2617  						Capacity: Capacity{
  2618  							Unit:  "GB",
  2619  							Value: 1,
  2620  						},
  2621  						MapName: "cw-s-use",
  2622  					},
  2623  				},
  2624  				MultiCDNSettings: &MultiCDNSettings{
  2625  					BOCC: &BOCC{
  2626  						ConditionalSamplingFrequency: SamplingFrequencyZero,
  2627  						Enabled:                      true,
  2628  						ForwardType:                  ForwardTypeOriginAndMidgress,
  2629  						RequestType:                  RequestTypeEdgeAndMidgress,
  2630  						SamplingFrequency:            SamplingFrequencyZero,
  2631  					},
  2632  					CDNs: []CDN{
  2633  						{
  2634  							CDNAuthKeys: []CDNAuthKey{
  2635  								{
  2636  									AuthKeyName: "TestAuthKeyName",
  2637  									ExpiryDate:  "TestExpiryDate",
  2638  									HeaderName:  "TestHeaderName",
  2639  									Secret:      "TestSecretTestSecret1234",
  2640  								},
  2641  							},
  2642  							CDNCode: "TestCDNCode",
  2643  							Enabled: true,
  2644  							IPACLCIDRs: []string{
  2645  								"1.1.1.1/1",
  2646  							},
  2647  							HTTPSOnly: true,
  2648  						},
  2649  					},
  2650  					DataStreams: &DataStreams{
  2651  						DataStreamIDs: []int64{1},
  2652  						Enabled:       true,
  2653  						SamplingRate:  tools.IntPtr(10),
  2654  					},
  2655  					EnableSoftAlerts: true,
  2656  					Origins: []Origin{
  2657  						{
  2658  							Hostname:   "TestHostname",
  2659  							OriginID:   "TestOriginID",
  2660  							PropertyID: 123,
  2661  						},
  2662  					},
  2663  				},
  2664  				Status:          StatusInProgress,
  2665  				ConfigName:      "TestConfigName",
  2666  				LastUpdatedBy:   "johndoe",
  2667  				LastUpdatedDate: "2022-06-10T13:21:14.488Z",
  2668  				NotificationEmails: []string{
  2669  					"test@test.com",
  2670  				},
  2671  				PropertyIDs:       []string{"123"},
  2672  				RetainIdleObjects: true,
  2673  			},
  2674  		},
  2675  		"missing required params - validation error": {
  2676  			params: UpdateConfigurationRequest{},
  2677  			withError: func(t *testing.T, err error) {
  2678  				assert.Equal(t, "update configuration: struct validation: Comments: cannot be blank\nLocations: cannot be blank\nPropertyIDs: cannot be blank\nConfigID: cannot be blank", err.Error())
  2679  			},
  2680  		},
  2681  		"500 internal server error": {
  2682  			params: UpdateConfigurationRequest{
  2683  				ConfigID: 1,
  2684  				Body: UpdateConfigurationBody{
  2685  					Comments: "TestCommentsUpdated",
  2686  					Locations: []ConfigLocationReq{
  2687  						{
  2688  							Comments:      "TestCommentsUpdated",
  2689  							TrafficTypeID: 1,
  2690  							Capacity: Capacity{
  2691  								Unit:  "GB",
  2692  								Value: 1,
  2693  							},
  2694  						},
  2695  					},
  2696  					PropertyIDs: []string{"1"},
  2697  				},
  2698  			},
  2699  			responseStatus: http.StatusInternalServerError,
  2700  			responseBody: `
  2701  {
  2702      "type": "/cloudwrapper/error-types/cloudwrapper-server-error",
  2703      "title": "An unexpected error has occurred.",
  2704      "detail": "Error processing request",
  2705      "instance": "/cloudwrapper/error-instances/abc",
  2706      "status": 500
  2707  }`,
  2708  			expectedPath: "/cloud-wrapper/v1/configurations/1?activate=false",
  2709  			withError: func(t *testing.T, err error) {
  2710  				want := &Error{
  2711  					Type:     "/cloudwrapper/error-types/cloudwrapper-server-error",
  2712  					Title:    "An unexpected error has occurred.",
  2713  					Detail:   "Error processing request",
  2714  					Instance: "/cloudwrapper/error-instances/abc",
  2715  					Status:   500,
  2716  				}
  2717  				assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err)
  2718  			},
  2719  		},
  2720  	}
  2721  
  2722  	for name, test := range tests {
  2723  		t.Run(name, func(t *testing.T) {
  2724  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  2725  				assert.Equal(t, test.expectedPath, r.URL.String())
  2726  				assert.Equal(t, http.MethodPut, r.Method)
  2727  				w.WriteHeader(test.responseStatus)
  2728  				_, err := w.Write([]byte(test.responseBody))
  2729  				assert.NoError(t, err)
  2730  				if test.expectedRequestBody != "" {
  2731  					body, err := io.ReadAll(r.Body)
  2732  					assert.NoError(t, err)
  2733  					assert.JSONEq(t, test.expectedRequestBody, string(body))
  2734  				}
  2735  			}))
  2736  			client := mockAPIClient(t, mockServer)
  2737  			result, err := client.UpdateConfiguration(context.Background(), test.params)
  2738  			if test.withError != nil {
  2739  				test.withError(t, err)
  2740  				return
  2741  			}
  2742  			require.NoError(t, err)
  2743  			assert.Equal(t, test.expectedResponse, result)
  2744  		})
  2745  	}
  2746  }
  2747  
  2748  func TestDeleteConfiguration(t *testing.T) {
  2749  	tests := map[string]struct {
  2750  		params         DeleteConfigurationRequest
  2751  		responseStatus int
  2752  		responseBody   string
  2753  		expectedPath   string
  2754  		withError      func(*testing.T, error)
  2755  	}{
  2756  		"202 - Accepted": {
  2757  			params: DeleteConfigurationRequest{
  2758  				ConfigID: 1,
  2759  			},
  2760  			responseStatus: 202,
  2761  			expectedPath:   "/cloud-wrapper/v1/configurations/1",
  2762  		},
  2763  		"missing required params - validation error": {
  2764  			params: DeleteConfigurationRequest{},
  2765  			withError: func(t *testing.T, err error) {
  2766  				assert.Equal(t, "delete configuration: struct validation: ConfigID: cannot be blank", err.Error())
  2767  			},
  2768  		},
  2769  		"500 internal server error": {
  2770  			params: DeleteConfigurationRequest{
  2771  				ConfigID: 1,
  2772  			},
  2773  			responseStatus: http.StatusInternalServerError,
  2774  			responseBody: `
  2775  {
  2776      "type": "/cloudwrapper/error-types/cloudwrapper-server-error",
  2777      "title": "An unexpected error has occurred.",
  2778      "detail": "Error processing request",
  2779      "instance": "/cloudwrapper/error-instances/abc",
  2780      "status": 500
  2781  }`,
  2782  			expectedPath: "/cloud-wrapper/v1/configurations/1",
  2783  			withError: func(t *testing.T, err error) {
  2784  				want := &Error{
  2785  					Type:     "/cloudwrapper/error-types/cloudwrapper-server-error",
  2786  					Title:    "An unexpected error has occurred.",
  2787  					Detail:   "Error processing request",
  2788  					Instance: "/cloudwrapper/error-instances/abc",
  2789  					Status:   500,
  2790  				}
  2791  				assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err)
  2792  			},
  2793  		},
  2794  	}
  2795  
  2796  	for name, test := range tests {
  2797  		t.Run(name, func(t *testing.T) {
  2798  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  2799  				assert.Equal(t, test.expectedPath, r.URL.String())
  2800  				assert.Equal(t, http.MethodDelete, r.Method)
  2801  				w.WriteHeader(test.responseStatus)
  2802  				_, err := w.Write([]byte(test.responseBody))
  2803  				assert.NoError(t, err)
  2804  			}))
  2805  			client := mockAPIClient(t, mockServer)
  2806  			err := client.DeleteConfiguration(context.Background(), test.params)
  2807  			if test.withError != nil {
  2808  				test.withError(t, err)
  2809  				return
  2810  			}
  2811  			require.NoError(t, err)
  2812  		})
  2813  	}
  2814  }
  2815  
  2816  func TestActivateConfiguration(t *testing.T) {
  2817  	tests := map[string]struct {
  2818  		params              ActivateConfigurationRequest
  2819  		expectedRequestBody string
  2820  		responseStatus      int
  2821  		responseBody        string
  2822  		expectedPath        string
  2823  		withError           func(*testing.T, error)
  2824  	}{
  2825  		"204 - single configID": {
  2826  			params: ActivateConfigurationRequest{
  2827  				ConfigurationIDs: []int{1},
  2828  			},
  2829  			expectedRequestBody: `
  2830  {
  2831     "configurationIds":[
  2832        1
  2833     ]
  2834  }`,
  2835  			responseStatus: 204,
  2836  			expectedPath:   "/cloud-wrapper/v1/configurations/activate",
  2837  		},
  2838  		"204 - multiple configIDs": {
  2839  			params: ActivateConfigurationRequest{
  2840  				ConfigurationIDs: []int{1, 2, 3},
  2841  			},
  2842  			expectedRequestBody: `
  2843  {
  2844  	"configurationIds": [
  2845  		1,
  2846  		2,
  2847  		3
  2848  	]
  2849  }`,
  2850  			responseStatus: 204,
  2851  			expectedPath:   "/cloud-wrapper/v1/configurations/activate",
  2852  		},
  2853  		"missing required params - validation error": {
  2854  			params: ActivateConfigurationRequest{},
  2855  			withError: func(t *testing.T, err error) {
  2856  				assert.Equal(t, "activate configuration: struct validation: ConfigurationIDs: cannot be blank", err.Error())
  2857  			},
  2858  		},
  2859  		"500 internal server error": {
  2860  			params: ActivateConfigurationRequest{
  2861  				ConfigurationIDs: []int{1},
  2862  			},
  2863  			responseStatus: http.StatusInternalServerError,
  2864  			responseBody: `
  2865  {
  2866      "type": "/cloudwrapper/error-types/cloudwrapper-server-error",
  2867      "title": "An unexpected error has occurred.",
  2868      "detail": "Error processing request",
  2869      "instance": "/cloudwrapper/error-instances/abc",
  2870      "status": 500
  2871  }`,
  2872  			expectedPath: "/cloud-wrapper/v1/configurations/activate",
  2873  			withError: func(t *testing.T, err error) {
  2874  				want := &Error{
  2875  					Type:     "/cloudwrapper/error-types/cloudwrapper-server-error",
  2876  					Title:    "An unexpected error has occurred.",
  2877  					Detail:   "Error processing request",
  2878  					Instance: "/cloudwrapper/error-instances/abc",
  2879  					Status:   500,
  2880  				}
  2881  				assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err)
  2882  			},
  2883  		},
  2884  	}
  2885  
  2886  	for name, test := range tests {
  2887  		t.Run(name, func(t *testing.T) {
  2888  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  2889  				assert.Equal(t, test.expectedPath, r.URL.String())
  2890  				assert.Equal(t, http.MethodPost, r.Method)
  2891  				w.WriteHeader(test.responseStatus)
  2892  				_, err := w.Write([]byte(test.responseBody))
  2893  				assert.NoError(t, err)
  2894  				if test.expectedRequestBody != "" {
  2895  					body, err := io.ReadAll(r.Body)
  2896  					assert.NoError(t, err)
  2897  					assert.JSONEq(t, test.expectedRequestBody, string(body))
  2898  				}
  2899  			}))
  2900  			client := mockAPIClient(t, mockServer)
  2901  			err := client.ActivateConfiguration(context.Background(), test.params)
  2902  			if test.withError != nil {
  2903  				test.withError(t, err)
  2904  				return
  2905  			}
  2906  			require.NoError(t, err)
  2907  		})
  2908  	}
  2909  }