github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/papi/propertyhostname_test.go (about) 1 package papi 2 3 import ( 4 "context" 5 "errors" 6 "net/http" 7 "net/http/httptest" 8 "testing" 9 10 "github.com/stretchr/testify/require" 11 "github.com/tj/assert" 12 ) 13 14 func TestPapi_GetPropertyVersionHostnames(t *testing.T) { 15 tests := map[string]struct { 16 params GetPropertyVersionHostnamesRequest 17 responseStatus int 18 responseBody string 19 expectedPath string 20 expectedResponse *GetPropertyVersionHostnamesResponse 21 withError func(*testing.T, error) 22 }{ 23 "200 OK": { 24 params: GetPropertyVersionHostnamesRequest{ 25 PropertyID: "prp_175780", 26 PropertyVersion: 3, 27 GroupID: "grp_15225", 28 ContractID: "ctr_1-1TJZH5", 29 IncludeCertStatus: false, 30 }, 31 responseStatus: http.StatusOK, 32 responseBody: ` 33 { 34 "accountId": "act_1-1TJZFB", 35 "contractId": "ctr_1-1TJZH5", 36 "groupId": "grp_15225", 37 "propertyId": "prp_175780", 38 "propertyVersion": 3, 39 "etag": "6aed418629b4e5c0", 40 "hostnames": { 41 "items": [ 42 { 43 "cnameType": "EDGE_HOSTNAME", 44 "edgeHostnameId": "ehn_895822", 45 "cnameFrom": "example.com", 46 "cnameTo": "example.com.edgesuite.net" 47 }, 48 { 49 "cnameType": "EDGE_HOSTNAME", 50 "edgeHostnameId": "ehn_895833", 51 "cnameFrom": "m.example.com", 52 "cnameTo": "m.example.com.edgesuite.net" 53 } 54 ] 55 } 56 } 57 58 `, 59 expectedPath: "/papi/v1/properties/prp_175780/versions/3/hostnames?contractId=ctr_1-1TJZH5&groupId=grp_15225&includeCertStatus=false&validateHostnames=false", 60 expectedResponse: &GetPropertyVersionHostnamesResponse{ 61 AccountID: "act_1-1TJZFB", 62 ContractID: "ctr_1-1TJZH5", 63 GroupID: "grp_15225", 64 PropertyID: "prp_175780", 65 PropertyVersion: 3, 66 Etag: "6aed418629b4e5c0", 67 Hostnames: HostnameResponseItems{ 68 Items: []Hostname{ 69 { 70 CnameType: "EDGE_HOSTNAME", 71 EdgeHostnameID: "ehn_895822", 72 CnameFrom: "example.com", 73 CnameTo: "example.com.edgesuite.net", 74 }, 75 { 76 CnameType: "EDGE_HOSTNAME", 77 EdgeHostnameID: "ehn_895833", 78 CnameFrom: "m.example.com", 79 CnameTo: "m.example.com.edgesuite.net", 80 }, 81 }, 82 }, 83 }, 84 }, 85 "validation error PropertyID missing": { 86 params: GetPropertyVersionHostnamesRequest{ 87 PropertyVersion: 3, 88 }, 89 withError: func(t *testing.T, err error) { 90 want := ErrStructValidation 91 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 92 assert.Contains(t, err.Error(), "PropertyID") 93 }, 94 }, 95 "validation error PropertyVersion missing": { 96 params: GetPropertyVersionHostnamesRequest{ 97 PropertyID: "prp_175780", 98 }, 99 withError: func(t *testing.T, err error) { 100 want := ErrStructValidation 101 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 102 assert.Contains(t, err.Error(), "PropertyVersion") 103 }, 104 }, 105 "500 internal server status error": { 106 params: GetPropertyVersionHostnamesRequest{ 107 PropertyID: "prp_175780", 108 PropertyVersion: 3, 109 }, 110 responseStatus: http.StatusInternalServerError, 111 responseBody: ` 112 { 113 "type": "internal_error", 114 "title": "Internal Server Error", 115 "detail": "Error fetching hostnames", 116 "status": 500 117 }`, 118 expectedPath: "/papi/v1/properties/prp_175780/versions/3/hostnames?contractId=&groupId=&includeCertStatus=false&validateHostnames=false", 119 withError: func(t *testing.T, err error) { 120 want := &Error{ 121 Type: "internal_error", 122 Title: "Internal Server Error", 123 Detail: "Error fetching hostnames", 124 StatusCode: http.StatusInternalServerError, 125 } 126 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 127 }, 128 }, 129 } 130 131 for name, test := range tests { 132 t.Run(name, func(t *testing.T) { 133 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 134 assert.Equal(t, test.expectedPath, r.URL.String()) 135 assert.Equal(t, http.MethodGet, r.Method) 136 w.WriteHeader(test.responseStatus) 137 _, err := w.Write([]byte(test.responseBody)) 138 assert.NoError(t, err) 139 })) 140 client := mockAPIClient(t, mockServer) 141 result, err := client.GetPropertyVersionHostnames(context.Background(), test.params) 142 if test.withError != nil { 143 test.withError(t, err) 144 return 145 } 146 require.NoError(t, err) 147 assert.Equal(t, test.expectedResponse, result) 148 }) 149 } 150 } 151 152 func TestPapi_UpdatePropertyVersionHostnames(t *testing.T) { 153 tests := map[string]struct { 154 params UpdatePropertyVersionHostnamesRequest 155 responseStatus int 156 responseBody string 157 expectedPath string 158 expectedResponse *UpdatePropertyVersionHostnamesResponse 159 withError func(*testing.T, error) 160 }{ 161 "200 OK": { 162 params: UpdatePropertyVersionHostnamesRequest{ 163 PropertyID: "prp_175780", 164 PropertyVersion: 3, 165 GroupID: "grp_15225", 166 ContractID: "ctr_1-1TJZH5", 167 IncludeCertStatus: true, 168 Hostnames: []Hostname{ 169 { 170 CnameType: "EDGE_HOSTNAME", 171 CnameFrom: "m.example.com", 172 CnameTo: "example.com.edgekey.net", 173 CertProvisioningType: "DEFAULT", 174 }, 175 { 176 CnameType: "EDGE_HOSTNAME", 177 EdgeHostnameID: "ehn_895824", 178 CnameFrom: "example3.com", 179 CertProvisioningType: "CPS_MANAGED", 180 }, 181 }, 182 }, 183 responseStatus: http.StatusOK, 184 responseBody: ` 185 { 186 "accountId": "act_1-1TJZFB", 187 "contractId": "ctr_1-1TJZH5", 188 "groupId": "grp_15225", 189 "propertyId": "prp_175780", 190 "propertyVersion": 3, 191 "etag": "6aed418629b4e5c0", 192 "hostnames": { 193 "items": [ 194 { 195 "cnameType": "EDGE_HOSTNAME", 196 "edgeHostnameId": "ehn_895822", 197 "cnameFrom": "m.example.com", 198 "cnameTo": "example.com.edgekey.net", 199 "certProvisioningType": "DEFAULT", 200 "certStatus": { 201 "validationCname": { 202 "hostname": "_acme-challenge.www.example.com", 203 "target": "{token}.www.example.com.akamai-domain.com" 204 }, 205 "staging": [ 206 { 207 "status": "NEEDS_VALIDATION" 208 } 209 ], 210 "production": [ 211 { 212 "status": "NEEDS_VALIDATION" 213 } 214 ] 215 } 216 }, 217 { 218 "cnameType": "EDGE_HOSTNAME", 219 "edgeHostnameId": "ehn_895833", 220 "cnameFrom": "example3.com", 221 "cnameTo": "m.example.com.edgesuite.net", 222 "certProvisioningType": "CPS_MANAGED" 223 } 224 ] 225 } 226 } 227 `, 228 expectedPath: "/papi/v1/properties/prp_175780/versions/3/hostnames?contractId=ctr_1-1TJZH5&groupId=grp_15225&includeCertStatus=true&validateHostnames=false", 229 expectedResponse: &UpdatePropertyVersionHostnamesResponse{ 230 AccountID: "act_1-1TJZFB", 231 ContractID: "ctr_1-1TJZH5", 232 GroupID: "grp_15225", 233 PropertyID: "prp_175780", 234 PropertyVersion: 3, 235 Etag: "6aed418629b4e5c0", 236 Hostnames: HostnameResponseItems{ 237 Items: []Hostname{ 238 { 239 CnameType: "EDGE_HOSTNAME", 240 EdgeHostnameID: "ehn_895822", 241 CnameFrom: "m.example.com", 242 CnameTo: "example.com.edgekey.net", 243 CertProvisioningType: "DEFAULT", 244 CertStatus: CertStatusItem{ 245 ValidationCname: ValidationCname{ 246 Hostname: "_acme-challenge.www.example.com", 247 Target: "{token}.www.example.com.akamai-domain.com", 248 }, 249 Staging: []StatusItem{{Status: "NEEDS_VALIDATION"}}, 250 Production: []StatusItem{{Status: "NEEDS_VALIDATION"}}, 251 }, 252 }, 253 { 254 CnameType: "EDGE_HOSTNAME", 255 EdgeHostnameID: "ehn_895833", 256 CnameFrom: "example3.com", 257 CnameTo: "m.example.com.edgesuite.net", 258 CertProvisioningType: "CPS_MANAGED", 259 }, 260 }, 261 }, 262 }, 263 }, 264 "200 empty hostnames": { 265 params: UpdatePropertyVersionHostnamesRequest{ 266 PropertyID: "prp_175780", 267 PropertyVersion: 3, 268 GroupID: "grp_15225", 269 ContractID: "ctr_1-1TJZH5", 270 IncludeCertStatus: true, 271 Hostnames: []Hostname{{}}, 272 }, 273 responseStatus: http.StatusOK, 274 responseBody: ` 275 { 276 "accountId": "act_1-1TJZFB", 277 "contractId": "ctr_1-1TJZH5", 278 "groupId": "grp_15225", 279 "propertyId": "prp_175780", 280 "propertyVersion": 3, 281 "etag": "6aed418629b4e5c0", 282 "hostnames": { 283 "items": [] 284 } 285 } 286 287 `, 288 expectedPath: "/papi/v1/properties/prp_175780/versions/3/hostnames?contractId=ctr_1-1TJZH5&groupId=grp_15225&includeCertStatus=true&validateHostnames=false", 289 expectedResponse: &UpdatePropertyVersionHostnamesResponse{ 290 AccountID: "act_1-1TJZFB", 291 ContractID: "ctr_1-1TJZH5", 292 GroupID: "grp_15225", 293 PropertyID: "prp_175780", 294 PropertyVersion: 3, 295 Etag: "6aed418629b4e5c0", 296 Hostnames: HostnameResponseItems{ 297 Items: []Hostname{}, 298 }, 299 }, 300 }, 301 "200 VerifyHostnames true empty hostnames": { 302 params: UpdatePropertyVersionHostnamesRequest{ 303 PropertyID: "prp_175780", 304 PropertyVersion: 3, 305 GroupID: "grp_15225", 306 ContractID: "ctr_1-1TJZH5", 307 ValidateHostnames: true, 308 IncludeCertStatus: true, 309 Hostnames: []Hostname{{}}, 310 }, 311 responseStatus: http.StatusOK, 312 responseBody: ` 313 { 314 "accountId": "act_1-1TJZFB", 315 "contractId": "ctr_1-1TJZH5", 316 "groupId": "grp_15225", 317 "propertyId": "prp_175780", 318 "propertyVersion": 3, 319 "etag": "6aed418629b4e5c0", 320 "validateHostnames": true, 321 "hostnames": { 322 "items": [] 323 } 324 } 325 `, 326 expectedPath: "/papi/v1/properties/prp_175780/versions/3/hostnames?contractId=ctr_1-1TJZH5&groupId=grp_15225&includeCertStatus=true&validateHostnames=true", 327 expectedResponse: &UpdatePropertyVersionHostnamesResponse{ 328 AccountID: "act_1-1TJZFB", 329 ContractID: "ctr_1-1TJZH5", 330 GroupID: "grp_15225", 331 PropertyID: "prp_175780", 332 PropertyVersion: 3, 333 Etag: "6aed418629b4e5c0", 334 Hostnames: HostnameResponseItems{ 335 Items: []Hostname{}, 336 }, 337 }, 338 }, 339 "validation error PropertyID missing": { 340 params: UpdatePropertyVersionHostnamesRequest{ 341 PropertyVersion: 3, 342 Hostnames: []Hostname{{}}, 343 }, 344 withError: func(t *testing.T, err error) { 345 want := ErrStructValidation 346 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 347 assert.Contains(t, err.Error(), "PropertyID") 348 }, 349 }, 350 "validation error PropertyVersion missing": { 351 params: UpdatePropertyVersionHostnamesRequest{ 352 PropertyID: "prp_175780", 353 Hostnames: []Hostname{{}}, 354 }, 355 withError: func(t *testing.T, err error) { 356 want := ErrStructValidation 357 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 358 assert.Contains(t, err.Error(), "PropertyVersion") 359 }, 360 }, 361 "200 Hostnames missing": { 362 params: UpdatePropertyVersionHostnamesRequest{ 363 PropertyID: "prp_175780", 364 PropertyVersion: 3, 365 GroupID: "grp_15225", 366 ContractID: "ctr_1-1TJZH5", 367 IncludeCertStatus: true, 368 }, 369 responseStatus: http.StatusOK, 370 responseBody: ` 371 { 372 "accountId": "act_1-1TJZFB", 373 "contractId": "ctr_1-1TJZH5", 374 "groupId": "grp_15225", 375 "propertyId": "prp_175780", 376 "propertyVersion": 3, 377 "etag": "6aed418629b4e5c0", 378 "validateHostnames": false, 379 "hostnames": { 380 "items": [] 381 } 382 }`, 383 expectedPath: "/papi/v1/properties/prp_175780/versions/3/hostnames?contractId=ctr_1-1TJZH5&groupId=grp_15225&includeCertStatus=true&validateHostnames=false", 384 expectedResponse: &UpdatePropertyVersionHostnamesResponse{ 385 AccountID: "act_1-1TJZFB", 386 ContractID: "ctr_1-1TJZH5", 387 GroupID: "grp_15225", 388 PropertyID: "prp_175780", 389 PropertyVersion: 3, 390 Etag: "6aed418629b4e5c0", 391 Hostnames: HostnameResponseItems{ 392 Items: []Hostname{}, 393 }, 394 }, 395 }, 396 "200 Hostnames items missing": { 397 params: UpdatePropertyVersionHostnamesRequest{ 398 PropertyID: "prp_175780", 399 PropertyVersion: 3, 400 GroupID: "grp_15225", 401 ContractID: "ctr_1-1TJZH5", 402 Hostnames: nil, 403 IncludeCertStatus: true, 404 }, 405 responseStatus: http.StatusOK, 406 responseBody: ` 407 { 408 "accountId": "act_1-1TJZFB", 409 "contractId": "ctr_1-1TJZH5", 410 "groupId": "grp_15225", 411 "propertyId": "prp_175780", 412 "propertyVersion": 3, 413 "etag": "6aed418629b4e5c0", 414 "validateHostnames": false, 415 "hostnames": { 416 "items": [] 417 } 418 }`, 419 expectedPath: "/papi/v1/properties/prp_175780/versions/3/hostnames?contractId=ctr_1-1TJZH5&groupId=grp_15225&includeCertStatus=true&validateHostnames=false", 420 expectedResponse: &UpdatePropertyVersionHostnamesResponse{ 421 AccountID: "act_1-1TJZFB", 422 ContractID: "ctr_1-1TJZH5", 423 GroupID: "grp_15225", 424 PropertyID: "prp_175780", 425 PropertyVersion: 3, 426 Etag: "6aed418629b4e5c0", 427 Hostnames: HostnameResponseItems{ 428 Items: []Hostname{}, 429 }, 430 }, 431 }, 432 "200 Hostnames items empty": { 433 params: UpdatePropertyVersionHostnamesRequest{ 434 PropertyID: "prp_175780", 435 PropertyVersion: 3, 436 GroupID: "grp_15225", 437 ContractID: "ctr_1-1TJZH5", 438 IncludeCertStatus: true, 439 Hostnames: []Hostname{}, 440 }, 441 responseStatus: http.StatusOK, 442 responseBody: ` 443 { 444 "accountId": "act_1-1TJZFB", 445 "contractId": "ctr_1-1TJZH5", 446 "groupId": "grp_15225", 447 "propertyId": "prp_175780", 448 "propertyVersion": 3, 449 "etag": "6aed418629b4e5c0", 450 "validateHostnames": false, 451 "hostnames": { 452 "items": [] 453 } 454 }`, 455 expectedPath: "/papi/v1/properties/prp_175780/versions/3/hostnames?contractId=ctr_1-1TJZH5&groupId=grp_15225&includeCertStatus=true&validateHostnames=false", 456 expectedResponse: &UpdatePropertyVersionHostnamesResponse{ 457 AccountID: "act_1-1TJZFB", 458 ContractID: "ctr_1-1TJZH5", 459 GroupID: "grp_15225", 460 PropertyID: "prp_175780", 461 PropertyVersion: 3, 462 Etag: "6aed418629b4e5c0", 463 Hostnames: HostnameResponseItems{ 464 Items: []Hostname{}, 465 }, 466 }, 467 }, 468 "400 Hostnames cert type is invalid": { 469 params: UpdatePropertyVersionHostnamesRequest{ 470 PropertyID: "prp_175780", 471 PropertyVersion: 3, 472 GroupID: "grp_15225", 473 ContractID: "ctr_1-1TJZH5", 474 IncludeCertStatus: true, 475 Hostnames: []Hostname{ 476 { 477 CnameType: "EDGE_HOSTNAME", 478 CnameFrom: "m.example.com", 479 CnameTo: "example.com.edgesuite.net", 480 CertProvisioningType: "INVALID_TYPE", 481 }, 482 }, 483 }, 484 responseStatus: http.StatusBadRequest, 485 responseBody: ` 486 { 487 "type": "https://problems.luna.akamaiapis.net/papi/v0/json-mapping-error", 488 "title": "Unable to interpret JSON", 489 "detail": "Your input could not be interpreted as the expected JSON format. Cannot deserialize value of type com.akamai.platformtk.entities.HostnameRelation$CertProvisioningType from String INVALID_TYPE: not one of the values accepted for Enum class: [DEFAULT, CPS_MANAGED]\n at [Source: (org.apache.catalina.connector.CoyoteInputStream); line: 6, column: 41] (through reference chain: java.util.ArrayList[0]->com.akamai.luna.papi.model.HostnameItem[certProvisioningType]).", 490 "status": 400 491 }`, 492 expectedPath: "/papi/v1/properties/prp_175780/versions/3/hostnames?contractId=ctr_1-1TJZH5&groupId=grp_15225&includeCertStatus=true&validateHostnames=false", 493 withError: func(t *testing.T, err error) { 494 want := &Error{ 495 Type: "https://problems.luna.akamaiapis.net/papi/v0/json-mapping-error", 496 Title: "Unable to interpret JSON", 497 Detail: "Your input could not be interpreted as the expected JSON format. Cannot deserialize value of type com.akamai.platformtk.entities.HostnameRelation$CertProvisioningType from String INVALID_TYPE: not one of the values accepted for Enum class: [DEFAULT, CPS_MANAGED]\n at [Source: (org.apache.catalina.connector.CoyoteInputStream); line: 6, column: 41] (through reference chain: java.util.ArrayList[0]->com.akamai.luna.papi.model.HostnameItem[certProvisioningType]).", 498 StatusCode: http.StatusBadRequest, 499 } 500 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 501 }, 502 }, 503 "500 internal server status error": { 504 params: UpdatePropertyVersionHostnamesRequest{ 505 PropertyID: "prp_175780", 506 PropertyVersion: 3, 507 Hostnames: []Hostname{{}}, 508 IncludeCertStatus: true, 509 }, 510 responseStatus: http.StatusInternalServerError, 511 responseBody: ` 512 { 513 "type": "internal_error", 514 "title": "Internal Server Error", 515 "detail": "Error updating hostnames", 516 "status": 500 517 }`, 518 expectedPath: "/papi/v1/properties/prp_175780/versions/3/hostnames?contractId=&groupId=&includeCertStatus=true&validateHostnames=false", 519 withError: func(t *testing.T, err error) { 520 want := &Error{ 521 Type: "internal_error", 522 Title: "Internal Server Error", 523 Detail: "Error updating hostnames", 524 StatusCode: http.StatusInternalServerError, 525 } 526 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 527 }, 528 }, 529 } 530 531 for name, test := range tests { 532 t.Run(name, func(t *testing.T) { 533 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 534 assert.Equal(t, test.expectedPath, r.URL.String()) 535 assert.Equal(t, http.MethodPut, r.Method) 536 w.WriteHeader(test.responseStatus) 537 _, err := w.Write([]byte(test.responseBody)) 538 assert.NoError(t, err) 539 })) 540 client := mockAPIClient(t, mockServer) 541 result, err := client.UpdatePropertyVersionHostnames(context.Background(), test.params) 542 if test.withError != nil { 543 test.withError(t, err) 544 return 545 } 546 require.NoError(t, err) 547 assert.Equal(t, test.expectedResponse, result) 548 }) 549 } 550 }