github.com/akamai/AkamaiOPEN-edgegrid-golang/v4@v4.1.0/pkg/papi/include_activations_test.go (about) 1 package papi 2 3 import ( 4 "context" 5 "errors" 6 "io/ioutil" 7 "net/http" 8 "net/http/httptest" 9 "testing" 10 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 ) 14 15 func TestActivateInclude(t *testing.T) { 16 tests := map[string]struct { 17 params ActivateIncludeRequest 18 expectedRequestBody string 19 responseStatus int 20 responseBody string 21 expectedPath string 22 expectedResponse *ActivationIncludeResponse 23 withError error 24 assertError func(*testing.T, error) 25 }{ 26 "201 Activate include acknowledging all the warnings": { 27 params: ActivateIncludeRequest{ 28 IncludeID: "inc_12345", 29 Version: 4, 30 Network: ActivationNetworkStaging, 31 Note: "test activation", 32 NotifyEmails: []string{"jbond@example.com"}, 33 AcknowledgeAllWarnings: true, 34 }, 35 expectedRequestBody: `{"acknowledgeAllWarnings":true,"activationType":"ACTIVATE","ignoreHttpErrors":true,"includeVersion":4,"network":"STAGING","note":"test activation","notifyEmails":["jbond@example.com"]}`, 36 expectedPath: "/papi/v1/includes/inc_12345/activations", 37 responseStatus: http.StatusCreated, 38 responseBody: ` 39 { 40 "activationLink": "/papi/v1/includes/inc_12345/activations/temporary-activation-id" 41 }`, 42 expectedResponse: &ActivationIncludeResponse{ 43 ActivationID: "temporary-activation-id", 44 ActivationLink: "/papi/v1/includes/inc_12345/activations/temporary-activation-id", 45 }, 46 }, 47 "201 Activate include": { 48 params: ActivateIncludeRequest{ 49 IncludeID: "inc_12345", 50 Version: 4, 51 Network: ActivationNetworkStaging, 52 Note: "test activation", 53 NotifyEmails: []string{"jbond@example.com"}, 54 }, 55 expectedRequestBody: `{"acknowledgeAllWarnings":false,"activationType":"ACTIVATE","ignoreHttpErrors":true,"includeVersion":4,"network":"STAGING","note":"test activation","notifyEmails":["jbond@example.com"]}`, 56 expectedPath: "/papi/v1/includes/inc_12345/activations", 57 responseStatus: http.StatusCreated, 58 responseBody: ` 59 { 60 "activationLink": "/papi/v1/includes/inc_12345/activations/temporary-activation-id" 61 }`, 62 expectedResponse: &ActivationIncludeResponse{ 63 ActivationID: "temporary-activation-id", 64 ActivationLink: "/papi/v1/includes/inc_12345/activations/temporary-activation-id", 65 }, 66 }, 67 "201 Activate include with ComplianceRecord None": { 68 params: ActivateIncludeRequest{ 69 IncludeID: "inc_12345", 70 Version: 4, 71 Network: ActivationNetworkProduction, 72 Note: "test activation", 73 NotifyEmails: []string{"jbond@example.com"}, 74 ComplianceRecord: &ComplianceRecordNone{ 75 CustomerEmail: "sb@akamai.com", 76 PeerReviewedBy: "sb@akamai.com", 77 UnitTested: true, 78 TicketID: "123", 79 }, 80 }, 81 expectedRequestBody: `{"acknowledgeAllWarnings":false,"activationType":"ACTIVATE","ignoreHttpErrors":true,"includeVersion":4,"network":"PRODUCTION","note":"test activation","notifyEmails":["jbond@example.com"], "complianceRecord":{"customerEmail":"sb@akamai.com", "noncomplianceReason":"NONE", "peerReviewedBy":"sb@akamai.com", "unitTested":true, "ticketId":"123"}}`, 82 expectedPath: "/papi/v1/includes/inc_12345/activations", 83 responseStatus: http.StatusCreated, 84 responseBody: ` 85 { 86 "activationLink": "/papi/v1/includes/inc_12345/activations/temporary-activation-id" 87 }`, 88 expectedResponse: &ActivationIncludeResponse{ 89 ActivationID: "temporary-activation-id", 90 ActivationLink: "/papi/v1/includes/inc_12345/activations/temporary-activation-id", 91 }, 92 }, 93 "201 Activate include with ComplianceRecord Other": { 94 params: ActivateIncludeRequest{ 95 IncludeID: "inc_12345", 96 Version: 4, 97 Network: ActivationNetworkProduction, 98 Note: "test activation", 99 NotifyEmails: []string{"jbond@example.com"}, 100 ComplianceRecord: &ComplianceRecordOther{ 101 OtherNoncomplianceReason: "some other reason", 102 TicketID: "123", 103 }, 104 }, 105 expectedRequestBody: `{"acknowledgeAllWarnings":false,"activationType":"ACTIVATE","ignoreHttpErrors":true,"includeVersion":4,"network":"PRODUCTION","note":"test activation","notifyEmails":["jbond@example.com"], "complianceRecord":{"otherNoncomplianceReason":"some other reason", "noncomplianceReason":"OTHER", "ticketId":"123"}}`, 106 expectedPath: "/papi/v1/includes/inc_12345/activations", 107 responseStatus: http.StatusCreated, 108 responseBody: ` 109 { 110 "activationLink": "/papi/v1/includes/inc_12345/activations/temporary-activation-id" 111 }`, 112 expectedResponse: &ActivationIncludeResponse{ 113 ActivationID: "temporary-activation-id", 114 ActivationLink: "/papi/v1/includes/inc_12345/activations/temporary-activation-id", 115 }, 116 }, 117 "201 Activate include with ComplianceRecord No_Production_Traffic": { 118 params: ActivateIncludeRequest{ 119 IncludeID: "inc_12345", 120 Version: 4, 121 Network: ActivationNetworkProduction, 122 Note: "test activation", 123 NotifyEmails: []string{"jbond@example.com"}, 124 ComplianceRecord: &ComplianceRecordNoProductionTraffic{ 125 TicketID: "123", 126 }, 127 }, 128 expectedRequestBody: `{"acknowledgeAllWarnings":false,"activationType":"ACTIVATE","ignoreHttpErrors":true,"includeVersion":4,"network":"PRODUCTION","note":"test activation","notifyEmails":["jbond@example.com"], "complianceRecord":{"noncomplianceReason":"NO_PRODUCTION_TRAFFIC", "ticketId":"123"}}`, 129 expectedPath: "/papi/v1/includes/inc_12345/activations", 130 responseStatus: http.StatusCreated, 131 responseBody: ` 132 { 133 "activationLink": "/papi/v1/includes/inc_12345/activations/temporary-activation-id" 134 }`, 135 expectedResponse: &ActivationIncludeResponse{ 136 ActivationID: "temporary-activation-id", 137 ActivationLink: "/papi/v1/includes/inc_12345/activations/temporary-activation-id", 138 }, 139 }, 140 "201 Activate include with ComplianceRecord Emergency": { 141 params: ActivateIncludeRequest{ 142 IncludeID: "inc_12345", 143 Version: 4, 144 Network: ActivationNetworkProduction, 145 Note: "test activation", 146 NotifyEmails: []string{"jbond@example.com"}, 147 ComplianceRecord: &ComplianceRecordEmergency{ 148 TicketID: "123", 149 }, 150 }, 151 expectedRequestBody: `{"acknowledgeAllWarnings":false,"activationType":"ACTIVATE","ignoreHttpErrors":true,"includeVersion":4,"network":"PRODUCTION","note":"test activation","notifyEmails":["jbond@example.com"], "complianceRecord":{"noncomplianceReason":"EMERGENCY", "ticketId":"123"}}`, 152 expectedPath: "/papi/v1/includes/inc_12345/activations", 153 responseStatus: http.StatusCreated, 154 responseBody: ` 155 { 156 "activationLink": "/papi/v1/includes/inc_12345/activations/temporary-activation-id" 157 }`, 158 expectedResponse: &ActivationIncludeResponse{ 159 ActivationID: "temporary-activation-id", 160 ActivationLink: "/papi/v1/includes/inc_12345/activations/temporary-activation-id", 161 }, 162 }, 163 "500 internal server error": { 164 params: ActivateIncludeRequest{ 165 IncludeID: "inc_12345", 166 Version: 4, 167 Network: ActivationNetworkStaging, 168 Note: "test activation", 169 NotifyEmails: []string{"jbond@example.com"}, 170 AcknowledgeAllWarnings: true, 171 }, 172 expectedPath: "/papi/v1/includes/inc_12345/activations", 173 responseStatus: http.StatusInternalServerError, 174 responseBody: ` 175 { 176 "type": "internal_error", 177 "title": "Internal Server Error", 178 "detail": "Error getting include", 179 "status": 500 180 }`, 181 withError: &Error{ 182 Type: "internal_error", 183 Title: "Internal Server Error", 184 Detail: "Error getting include", 185 StatusCode: http.StatusInternalServerError, 186 }, 187 }, 188 "validation error - missing include id": { 189 params: ActivateIncludeRequest{ 190 Version: 4, 191 Network: ActivationNetworkStaging, 192 NotifyEmails: []string{"jbond@example.com"}, 193 }, 194 withError: ErrStructValidation, 195 }, 196 "validation error - missing version": { 197 params: ActivateIncludeRequest{ 198 IncludeID: "inc_12345", 199 Network: ActivationNetworkStaging, 200 NotifyEmails: []string{"jbond@example.com"}, 201 }, 202 withError: ErrStructValidation, 203 }, 204 "validation error - missing network": { 205 params: ActivateIncludeRequest{ 206 IncludeID: "inc_12345", 207 Version: 4, 208 NotifyEmails: []string{"jbond@example.com"}, 209 }, 210 withError: ErrStructValidation, 211 }, 212 "validation error - missing notify emails": { 213 params: ActivateIncludeRequest{ 214 IncludeID: "inc_12345", 215 Version: 4, 216 Network: ActivationNetworkStaging, 217 }, 218 withError: ErrStructValidation, 219 }, 220 "validation error - missing compliance record for production network": { 221 params: ActivateIncludeRequest{ 222 IncludeID: "inc_12345", 223 Version: 4, 224 Network: ActivationNetworkProduction, 225 Note: "test activation", 226 NotifyEmails: []string{"jbond@example.com"}, 227 AcknowledgeAllWarnings: true, 228 }, 229 withError: ErrStructValidation, 230 }, 231 "validation error - not valid ComplianceRecordNone": { 232 params: ActivateIncludeRequest{ 233 IncludeID: "inc_12345", 234 Version: 4, 235 Network: ActivationNetworkProduction, 236 Note: "test activation", 237 NotifyEmails: []string{"jbond@example.com"}, 238 AcknowledgeAllWarnings: true, 239 ComplianceRecord: &ComplianceRecordNone{ 240 UnitTested: true, 241 TicketID: "123", 242 }, 243 }, 244 withError: ErrStructValidation, 245 assertError: func(t *testing.T, err error) { 246 assert.Contains(t, err.Error(), "CustomerEmail: cannot be blank") 247 assert.Contains(t, err.Error(), "PeerReviewedBy: cannot be blank") 248 }, 249 }, 250 "validation error - not valid UnitTested field for PRODUCTION activation network and ComplianceRecordNone": { 251 params: ActivateIncludeRequest{ 252 IncludeID: "inc_12345", 253 Version: 4, 254 Network: ActivationNetworkProduction, 255 Note: "test activation", 256 NotifyEmails: []string{"jbond@example.com"}, 257 ComplianceRecord: &ComplianceRecordNone{ 258 CustomerEmail: "sb@akamai.com", 259 PeerReviewedBy: "sb@akamai.com", 260 UnitTested: false, 261 TicketID: "123", 262 }, 263 }, 264 withError: ErrStructValidation, 265 assertError: func(t *testing.T, err error) { 266 assert.Contains(t, err.Error(), "for PRODUCTION activation network and nonComplianceRecord, UnitTested value has to be set to true, otherwise API will not work correctly") 267 }, 268 }, 269 "validation error - not valid ComplianceRecordOther": { 270 params: ActivateIncludeRequest{ 271 IncludeID: "inc_12345", 272 Version: 4, 273 Network: ActivationNetworkProduction, 274 Note: "test activation", 275 NotifyEmails: []string{"jbond@example.com"}, 276 AcknowledgeAllWarnings: true, 277 ComplianceRecord: &ComplianceRecordOther{}, 278 }, 279 withError: ErrStructValidation, 280 assertError: func(t *testing.T, err error) { 281 assert.Contains(t, err.Error(), "OtherNoncomplianceReason: cannot be blank") 282 }, 283 }, 284 } 285 for name, test := range tests { 286 t.Run(name, func(t *testing.T) { 287 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 288 assert.Equal(t, test.expectedPath, r.URL.String()) 289 assert.Equal(t, http.MethodPost, r.Method) 290 w.WriteHeader(test.responseStatus) 291 _, err := w.Write([]byte(test.responseBody)) 292 assert.NoError(t, err) 293 294 if len(test.expectedRequestBody) > 0 { 295 body, err := ioutil.ReadAll(r.Body) 296 require.NoError(t, err) 297 assert.JSONEq(t, test.expectedRequestBody, string(body)) 298 } 299 })) 300 client := mockAPIClient(t, mockServer) 301 result, err := client.ActivateInclude(context.Background(), test.params) 302 303 if test.withError != nil || test.assertError != nil { 304 if test.withError != nil { 305 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 306 } 307 if test.assertError != nil { 308 test.assertError(t, err) 309 } 310 return 311 } 312 313 require.NoError(t, err) 314 assert.Equal(t, test.expectedResponse, result) 315 }) 316 } 317 } 318 319 func TestDeactivateInclude(t *testing.T) { 320 tests := map[string]struct { 321 params DeactivateIncludeRequest 322 expectedRequestBody string 323 responseStatus int 324 responseBody string 325 expectedPath string 326 expectedResponse *DeactivationIncludeResponse 327 withError error 328 }{ 329 "201 Activate include acknowledging all the warnings": { 330 params: DeactivateIncludeRequest{ 331 IncludeID: "inc_12345", 332 Version: 4, 333 Network: ActivationNetworkStaging, 334 Note: "test activation", 335 NotifyEmails: []string{"jbond@example.com"}, 336 AcknowledgeAllWarnings: true, 337 }, 338 expectedRequestBody: `{"acknowledgeAllWarnings":true,"activationType":"DEACTIVATE","ignoreHttpErrors":true,"includeVersion":4,"network":"STAGING","note":"test activation","notifyEmails":["jbond@example.com"]}`, 339 expectedPath: "/papi/v1/includes/inc_12345/activations", 340 responseStatus: http.StatusCreated, 341 responseBody: ` 342 { 343 "activationLink": "/papi/v1/includes/inc_12345/activations/temporary-activation-id" 344 }`, 345 expectedResponse: &DeactivationIncludeResponse{ 346 ActivationID: "temporary-activation-id", 347 ActivationLink: "/papi/v1/includes/inc_12345/activations/temporary-activation-id", 348 }, 349 }, 350 "201 Activate include": { 351 params: DeactivateIncludeRequest{ 352 IncludeID: "inc_12345", 353 Version: 4, 354 Network: ActivationNetworkStaging, 355 Note: "test activation", 356 NotifyEmails: []string{"jbond@example.com"}, 357 }, 358 expectedRequestBody: `{"acknowledgeAllWarnings":false,"activationType":"DEACTIVATE","ignoreHttpErrors":true,"includeVersion":4,"network":"STAGING","note":"test activation","notifyEmails":["jbond@example.com"]}`, 359 expectedPath: "/papi/v1/includes/inc_12345/activations", 360 responseStatus: http.StatusCreated, 361 responseBody: ` 362 { 363 "activationLink": "/papi/v1/includes/inc_12345/activations/temporary-activation-id" 364 }`, 365 expectedResponse: &DeactivationIncludeResponse{ 366 ActivationID: "temporary-activation-id", 367 ActivationLink: "/papi/v1/includes/inc_12345/activations/temporary-activation-id", 368 }, 369 }, 370 "422 Unprocessable entity - deactivate version which is not active on some network": { 371 params: DeactivateIncludeRequest{ 372 IncludeID: "inc_12345", 373 Version: 4, 374 Network: ActivationNetworkProduction, 375 Note: "test activation", 376 NotifyEmails: []string{"jbond@example.com"}, 377 AcknowledgeAllWarnings: true, 378 }, 379 expectedPath: "/papi/v1/includes/inc_12345/activations", 380 responseStatus: http.StatusUnprocessableEntity, 381 responseBody: ` 382 { 383 "type": "https://problems.luna.akamaiapis.net/papi/v0/deactivation/include-not-active-in-production", 384 "title": "Include not active in PRODUCTION", 385 "detail": "The include cannot be deactivated because it is not active in PRODUCTION.", 386 "instance": "https://akaa-gcplhccxrheyl6kw-bcfnozqkbaydivqp.luna-dev.akamaiapis.net/papi/v1/includes/inc_12345/activations#12345", 387 "status": 422 388 }`, 389 withError: &Error{ 390 Type: "https://problems.luna.akamaiapis.net/papi/v0/deactivation/include-not-active-in-production", 391 Title: "Include not active in PRODUCTION", 392 Detail: "The include cannot be deactivated because it is not active in PRODUCTION.", 393 Instance: "https://akaa-gcplhccxrheyl6kw-bcfnozqkbaydivqp.luna-dev.akamaiapis.net/papi/v1/includes/inc_12345/activations#12345", 394 StatusCode: http.StatusUnprocessableEntity, 395 }, 396 }, 397 "500 internal server error": { 398 params: DeactivateIncludeRequest{ 399 IncludeID: "inc_12345", 400 Version: 4, 401 Network: ActivationNetworkStaging, 402 Note: "test activation", 403 NotifyEmails: []string{"jbond@example.com"}, 404 AcknowledgeAllWarnings: true, 405 }, 406 expectedPath: "/papi/v1/includes/inc_12345/activations", 407 responseStatus: http.StatusInternalServerError, 408 responseBody: ` 409 { 410 "type": "internal_error", 411 "title": "Internal Server Error", 412 "detail": "Error getting include", 413 "status": 500 414 }`, 415 withError: &Error{ 416 Type: "internal_error", 417 Title: "Internal Server Error", 418 Detail: "Error getting include", 419 StatusCode: http.StatusInternalServerError, 420 }, 421 }, 422 "validation error - missing include id": { 423 params: DeactivateIncludeRequest{ 424 Version: 4, 425 Network: ActivationNetworkStaging, 426 NotifyEmails: []string{"jbond@example.com"}, 427 }, 428 withError: ErrStructValidation, 429 }, 430 "validation error - missing version": { 431 params: DeactivateIncludeRequest{ 432 IncludeID: "inc_12345", 433 Network: ActivationNetworkStaging, 434 NotifyEmails: []string{"jbond@example.com"}, 435 }, 436 withError: ErrStructValidation, 437 }, 438 "validation error - missing network": { 439 params: DeactivateIncludeRequest{ 440 IncludeID: "inc_12345", 441 Version: 4, 442 NotifyEmails: []string{"jbond@example.com"}, 443 }, 444 withError: ErrStructValidation, 445 }, 446 "validation error - missing notify emails": { 447 params: DeactivateIncludeRequest{ 448 IncludeID: "inc_12345", 449 Version: 4, 450 Network: ActivationNetworkStaging, 451 }, 452 withError: ErrStructValidation, 453 }, 454 } 455 for name, test := range tests { 456 t.Run(name, func(t *testing.T) { 457 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 458 assert.Equal(t, test.expectedPath, r.URL.String()) 459 assert.Equal(t, http.MethodPost, r.Method) 460 w.WriteHeader(test.responseStatus) 461 _, err := w.Write([]byte(test.responseBody)) 462 assert.NoError(t, err) 463 464 if len(test.expectedRequestBody) > 0 { 465 body, err := ioutil.ReadAll(r.Body) 466 require.NoError(t, err) 467 assert.JSONEq(t, test.expectedRequestBody, string(body)) 468 } 469 })) 470 client := mockAPIClient(t, mockServer) 471 result, err := client.DeactivateInclude(context.Background(), test.params) 472 if test.withError != nil { 473 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 474 return 475 } 476 require.NoError(t, err) 477 assert.Equal(t, test.expectedResponse, result) 478 }) 479 } 480 } 481 482 func TestCancelIncludeActivation(t *testing.T) { 483 tests := map[string]struct { 484 params CancelIncludeActivationRequest 485 responseStatus int 486 responseBody string 487 expectedPath string 488 expectedResponse *CancelIncludeActivationResponse 489 withError error 490 }{ 491 "200 cancel include activation": { 492 params: CancelIncludeActivationRequest{ 493 IncludeID: "inc_12345", 494 ContractID: "test_contract", 495 GroupID: "test_group", 496 ActivationID: "test_activation_123", 497 }, 498 expectedPath: "/papi/v1/includes/inc_12345/activations/test_activation_123?contractId=test_contract&groupId=test_group", 499 responseStatus: http.StatusOK, 500 responseBody: ` 501 { 502 "accountId": "test_account", 503 "contractId": "test_contract", 504 "groupId": "test_group", 505 "activations": { 506 "items": [ 507 { 508 "network": "STAGING", 509 "activationType": "ACTIVATE", 510 "status": "PENDING_CANCELLATION", 511 "submitDate": "2022-12-01T13:18:57Z", 512 "updateDate": "2022-12-01T13:19:04Z", 513 "note": "test_note_1", 514 "notifyEmails": [ 515 "nomail@nomail.com" 516 ], 517 "fmaActivationState": "received", 518 "includeId": "inc_12345", 519 "includeName": "test_include_name", 520 "includeVersion": 1, 521 "includeActivationId": "test_activation_123" 522 } 523 ] 524 } 525 }`, 526 expectedResponse: &CancelIncludeActivationResponse{ 527 AccountID: "test_account", 528 ContractID: "test_contract", 529 GroupID: "test_group", 530 Activations: IncludeActivationsRes{ 531 Items: []IncludeActivation{ 532 { 533 Network: "STAGING", 534 ActivationType: ActivationTypeActivate, 535 Status: ActivationStatusCancelling, 536 SubmitDate: "2022-12-01T13:18:57Z", 537 UpdateDate: "2022-12-01T13:19:04Z", 538 Note: "test_note_1", 539 NotifyEmails: []string{"nomail@nomail.com"}, 540 FMAActivationState: "received", 541 IncludeID: "inc_12345", 542 IncludeName: "test_include_name", 543 IncludeVersion: 1, 544 IncludeActivationID: "test_activation_123", 545 }, 546 }, 547 }, 548 }, 549 }, 550 "500 internal server error": { 551 params: CancelIncludeActivationRequest{ 552 IncludeID: "inc_12345", 553 ContractID: "test_contract", 554 GroupID: "test_group", 555 ActivationID: "test_activation_123", 556 }, 557 expectedPath: "/papi/v1/includes/inc_12345/activations/test_activation_123?contractId=test_contract&groupId=test_group", 558 responseStatus: http.StatusInternalServerError, 559 responseBody: ` 560 { 561 "type": "internal_error", 562 "title": "Internal Server Error", 563 "detail": "Error cancelling include activation", 564 "status": 500 565 }`, 566 withError: &Error{ 567 Type: "internal_error", 568 Title: "Internal Server Error", 569 Detail: "Error cancelling include activation", 570 StatusCode: http.StatusInternalServerError, 571 }, 572 }, 573 "validation error - missing include id": { 574 params: CancelIncludeActivationRequest{ 575 ContractID: "test_contract", 576 GroupID: "test_group", 577 ActivationID: "test_activation_123", 578 }, 579 withError: ErrStructValidation, 580 }, 581 "validation error - contract id": { 582 params: CancelIncludeActivationRequest{ 583 IncludeID: "inc_12345", 584 GroupID: "test_group", 585 ActivationID: "test_activation_123", 586 }, 587 withError: ErrStructValidation, 588 }, 589 "validation error - group id": { 590 params: CancelIncludeActivationRequest{ 591 IncludeID: "inc_12345", 592 ContractID: "test_contract", 593 ActivationID: "test_activation_123", 594 }, 595 withError: ErrStructValidation, 596 }, 597 "validation error - activation id": { 598 params: CancelIncludeActivationRequest{ 599 IncludeID: "inc_12345", 600 ContractID: "test_contract", 601 GroupID: "test_group", 602 }, 603 withError: ErrStructValidation, 604 }, 605 } 606 for name, test := range tests { 607 t.Run(name, func(t *testing.T) { 608 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 609 assert.Equal(t, test.expectedPath, r.URL.String()) 610 assert.Equal(t, http.MethodDelete, r.Method) 611 w.WriteHeader(test.responseStatus) 612 _, err := w.Write([]byte(test.responseBody)) 613 assert.NoError(t, err) 614 })) 615 client := mockAPIClient(t, mockServer) 616 result, err := client.CancelIncludeActivation(context.Background(), test.params) 617 if test.withError != nil { 618 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 619 return 620 } 621 require.NoError(t, err) 622 assert.Equal(t, test.expectedResponse, result) 623 }) 624 } 625 } 626 627 func TestGetIncludeActivation(t *testing.T) { 628 tests := map[string]struct { 629 params GetIncludeActivationRequest 630 responseStatus int 631 responseBody string 632 expectedPath string 633 expectedResponse *GetIncludeActivationResponse 634 withError error 635 }{ 636 "200 Get include activation": { 637 params: GetIncludeActivationRequest{ 638 IncludeID: "inc_12345", 639 ActivationID: "atv_12345", 640 }, 641 expectedPath: "/papi/v1/includes/inc_12345/activations/atv_12345", 642 responseStatus: http.StatusOK, 643 responseBody: ` 644 { 645 "accountId": "test_account", 646 "contractId": "test_contract", 647 "groupId": "test_group", 648 "activations": { 649 "items": [ 650 { 651 "activationId": "atv_12345", 652 "network": "STAGING", 653 "activationType": "ACTIVATE", 654 "status": "ACTIVE", 655 "submitDate": "2022-10-27T12:27:54Z", 656 "updateDate": "2022-10-27T12:28:54Z", 657 "note": "DXE test activation", 658 "notifyEmails": [ 659 "test@example.com" 660 ], 661 "fmaActivationState": "steady", 662 "fallbackInfo": { 663 "fastFallbackAttempted": false, 664 "fallbackVersion": 3, 665 "canFastFallback": false, 666 "steadyStateTime": 1666873734, 667 "fastFallbackExpirationTime": 1666877334, 668 "fastFallbackRecoveryState": null 669 }, 670 "includeId": "inc_12345", 671 "includeName": "tfp_test1", 672 "includeType": "MICROSERVICES", 673 "includeVersion": 4 674 } 675 ] 676 } 677 }`, 678 expectedResponse: &GetIncludeActivationResponse{ 679 AccountID: "test_account", 680 ContractID: "test_contract", 681 GroupID: "test_group", 682 Activations: IncludeActivationsRes{ 683 Items: []IncludeActivation{ 684 { 685 ActivationID: "atv_12345", 686 Network: "STAGING", 687 ActivationType: ActivationTypeActivate, 688 Status: ActivationStatusActive, 689 SubmitDate: "2022-10-27T12:27:54Z", 690 UpdateDate: "2022-10-27T12:28:54Z", 691 Note: "DXE test activation", 692 NotifyEmails: []string{"test@example.com"}, 693 FMAActivationState: "steady", 694 FallbackInfo: &ActivationFallbackInfo{ 695 FastFallbackAttempted: false, 696 FallbackVersion: 3, 697 CanFastFallback: false, 698 SteadyStateTime: 1666873734, 699 FastFallbackExpirationTime: 1666877334, 700 }, 701 IncludeID: "inc_12345", 702 IncludeName: "tfp_test1", 703 IncludeType: "MICROSERVICES", 704 IncludeVersion: 4, 705 }, 706 }, 707 }, 708 Activation: IncludeActivation{ 709 ActivationID: "atv_12345", 710 Network: "STAGING", 711 ActivationType: ActivationTypeActivate, 712 Status: ActivationStatusActive, 713 SubmitDate: "2022-10-27T12:27:54Z", 714 UpdateDate: "2022-10-27T12:28:54Z", 715 Note: "DXE test activation", 716 NotifyEmails: []string{"test@example.com"}, 717 FMAActivationState: "steady", 718 FallbackInfo: &ActivationFallbackInfo{ 719 FastFallbackAttempted: false, 720 FallbackVersion: 3, 721 CanFastFallback: false, 722 SteadyStateTime: 1666873734, 723 FastFallbackExpirationTime: 1666877334, 724 }, 725 IncludeID: "inc_12345", 726 IncludeName: "tfp_test1", 727 IncludeType: "MICROSERVICES", 728 IncludeVersion: 4, 729 }, 730 }, 731 }, 732 "200 Get include activation with includeActivationId": { 733 params: GetIncludeActivationRequest{ 734 IncludeID: "inc_12345", 735 ActivationID: "5e597860-1107-461e-8dbe-4e7526e8dd02", 736 }, 737 expectedPath: "/papi/v1/includes/inc_12345/activations/5e597860-1107-461e-8dbe-4e7526e8dd02", 738 responseStatus: http.StatusOK, 739 responseBody: ` 740 { 741 "accountId": "test_account", 742 "contractId": "test_contract", 743 "groupId": "test_group", 744 "activations": { 745 "items": [ 746 { 747 "includeActivationId": "5e597860-1107-461e-8dbe-4e7526e8dd02", 748 "network": "STAGING", 749 "activationType": "ACTIVATE", 750 "status": "ACTIVE", 751 "submitDate": "2022-10-27T12:27:54Z", 752 "updateDate": "2022-10-27T12:28:54Z", 753 "note": "DXE test activation", 754 "notifyEmails": [ 755 "test@example.com" 756 ], 757 "fmaActivationState": "steady", 758 "fallbackInfo": { 759 "fastFallbackAttempted": false, 760 "fallbackVersion": 3, 761 "canFastFallback": false, 762 "steadyStateTime": 1666873734, 763 "fastFallbackExpirationTime": 1666877334, 764 "fastFallbackRecoveryState": null 765 }, 766 "includeId": "inc_12345", 767 "includeName": "tfp_test1", 768 "includeType": "MICROSERVICES", 769 "includeVersion": 4 770 } 771 ] 772 } 773 }`, 774 expectedResponse: &GetIncludeActivationResponse{ 775 AccountID: "test_account", 776 ContractID: "test_contract", 777 GroupID: "test_group", 778 Activations: IncludeActivationsRes{ 779 Items: []IncludeActivation{ 780 { 781 IncludeActivationID: "5e597860-1107-461e-8dbe-4e7526e8dd02", 782 Network: "STAGING", 783 ActivationType: ActivationTypeActivate, 784 Status: ActivationStatusActive, 785 SubmitDate: "2022-10-27T12:27:54Z", 786 UpdateDate: "2022-10-27T12:28:54Z", 787 Note: "DXE test activation", 788 NotifyEmails: []string{"test@example.com"}, 789 FMAActivationState: "steady", 790 FallbackInfo: &ActivationFallbackInfo{ 791 FastFallbackAttempted: false, 792 FallbackVersion: 3, 793 CanFastFallback: false, 794 SteadyStateTime: 1666873734, 795 FastFallbackExpirationTime: 1666877334, 796 }, 797 IncludeID: "inc_12345", 798 IncludeName: "tfp_test1", 799 IncludeType: "MICROSERVICES", 800 IncludeVersion: 4, 801 }, 802 }, 803 }, 804 Activation: IncludeActivation{ 805 IncludeActivationID: "5e597860-1107-461e-8dbe-4e7526e8dd02", 806 Network: "STAGING", 807 ActivationType: ActivationTypeActivate, 808 Status: ActivationStatusActive, 809 SubmitDate: "2022-10-27T12:27:54Z", 810 UpdateDate: "2022-10-27T12:28:54Z", 811 Note: "DXE test activation", 812 NotifyEmails: []string{"test@example.com"}, 813 FMAActivationState: "steady", 814 FallbackInfo: &ActivationFallbackInfo{ 815 FastFallbackAttempted: false, 816 FallbackVersion: 3, 817 CanFastFallback: false, 818 SteadyStateTime: 1666873734, 819 FastFallbackExpirationTime: 1666877334, 820 }, 821 IncludeID: "inc_12345", 822 IncludeName: "tfp_test1", 823 IncludeType: "MICROSERVICES", 824 IncludeVersion: 4, 825 }, 826 }, 827 }, 828 "500 internal server error": { 829 params: GetIncludeActivationRequest{ 830 IncludeID: "inc_12345", 831 ActivationID: "atv_12345", 832 }, 833 expectedPath: "/papi/v1/includes/inc_12345/activations/atv_12345", 834 responseStatus: http.StatusInternalServerError, 835 responseBody: ` 836 { 837 "type": "internal_error", 838 "title": "Internal Server Error", 839 "detail": "Error getting include", 840 "status": 500 841 }`, 842 withError: &Error{ 843 Type: "internal_error", 844 Title: "Internal Server Error", 845 Detail: "Error getting include", 846 StatusCode: http.StatusInternalServerError, 847 }, 848 }, 849 "validation error - missing include id": { 850 params: GetIncludeActivationRequest{ 851 ActivationID: "atv_12345", 852 }, 853 withError: ErrStructValidation, 854 }, 855 "validation error - activation id": { 856 params: GetIncludeActivationRequest{ 857 IncludeID: "inc_12345", 858 }, 859 withError: ErrStructValidation, 860 }, 861 } 862 for name, test := range tests { 863 t.Run(name, func(t *testing.T) { 864 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 865 assert.Equal(t, test.expectedPath, r.URL.String()) 866 assert.Equal(t, http.MethodGet, r.Method) 867 w.WriteHeader(test.responseStatus) 868 _, err := w.Write([]byte(test.responseBody)) 869 assert.NoError(t, err) 870 })) 871 client := mockAPIClient(t, mockServer) 872 result, err := client.GetIncludeActivation(context.Background(), test.params) 873 if test.withError != nil { 874 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 875 return 876 } 877 require.NoError(t, err) 878 assert.Equal(t, test.expectedResponse, result) 879 }) 880 } 881 } 882 883 func TestListIncludeActivations(t *testing.T) { 884 tests := map[string]struct { 885 params ListIncludeActivationsRequest 886 responseStatus int 887 responseBody string 888 expectedPath string 889 expectedResponse *ListIncludeActivationsResponse 890 withError error 891 }{ 892 "200 List include activations": { 893 params: ListIncludeActivationsRequest{ 894 IncludeID: "inc_12345", 895 ContractID: "test_contract", 896 GroupID: "test_group", 897 }, 898 expectedPath: "/papi/v1/includes/inc_12345/activations?contractId=test_contract&groupId=test_group", 899 responseStatus: http.StatusOK, 900 responseBody: ` 901 { 902 "accountId": "test_account", 903 "contractId": "test_contract", 904 "groupId": "test_group", 905 "activations": { 906 "items": [ 907 { 908 "activationId": "atv_12344", 909 "network": "STAGING", 910 "activationType": "ACTIVATE", 911 "status": "ACTIVE", 912 "submitDate": "2022-10-27T12:27:54Z", 913 "updateDate": "2022-10-27T12:28:54Z", 914 "note": "test activation", 915 "notifyEmails": [ 916 "test@example.com" 917 ], 918 "fmaActivationState": "steady", 919 "fallbackInfo": { 920 "fastFallbackAttempted": false, 921 "fallbackVersion": 3, 922 "canFastFallback": false, 923 "steadyStateTime": 1666873734, 924 "fastFallbackExpirationTime": 1666877334, 925 "fastFallbackRecoveryState": null 926 }, 927 "includeId": "inc_12345", 928 "includeName": "tfp_test1", 929 "includeType": "MICROSERVICES", 930 "includeVersion": 4 931 }, 932 { 933 "activationId": "atv_12343", 934 "network": "STAGING", 935 "activationType": "ACTIVATE", 936 "status": "ACTIVE", 937 "submitDate": "2022-10-27T11:21:40Z", 938 "updateDate": "2022-10-27T11:22:54Z", 939 "note": "test activation", 940 "notifyEmails": [ 941 "test@example.com" 942 ], 943 "fmaActivationState": "steady", 944 "fallbackInfo": { 945 "fastFallbackAttempted": false, 946 "fallbackVersion": 4, 947 "canFastFallback": false, 948 "steadyStateTime": 1666869774, 949 "fastFallbackExpirationTime": 1666873374, 950 "fastFallbackRecoveryState": null 951 }, 952 "includeId": "inc_12345", 953 "includeName": "tfp_test1", 954 "includeType": "MICROSERVICES", 955 "includeVersion": 3 956 }, 957 { 958 "activationId": "atv_12343", 959 "network": "STAGING", 960 "activationType": "DEACTIVATE", 961 "status": "ACTIVE", 962 "submitDate": "2022-10-26T12:41:58Z", 963 "updateDate": "2022-10-26T13:03:04Z", 964 "note": "test activation", 965 "notifyEmails": [ 966 "test@example.com" 967 ], 968 "includeId": "inc_12345", 969 "includeName": "tfp_test1", 970 "includeType": "MICROSERVICES", 971 "includeVersion": 3 972 }, 973 { 974 "activationId": "atv_12342", 975 "network": "STAGING", 976 "activationType": "ACTIVATE", 977 "status": "ACTIVE", 978 "submitDate": "2022-10-26T12:37:49Z", 979 "updateDate": "2022-10-26T12:38:59Z", 980 "note": "test activation", 981 "notifyEmails": [ 982 "test@example.com" 983 ], 984 "fmaActivationState": "steady", 985 "fallbackInfo": { 986 "fastFallbackAttempted": false, 987 "fallbackVersion": 4, 988 "canFastFallback": false, 989 "steadyStateTime": 1666787939, 990 "fastFallbackExpirationTime": 1666791539, 991 "fastFallbackRecoveryState": null 992 }, 993 "includeId": "inc_12345", 994 "includeName": "tfp_test1", 995 "includeType": "MICROSERVICES", 996 "includeVersion": 2 997 }, 998 { 999 "activationId": "atv_12341", 1000 "network": "STAGING", 1001 "activationType": "ACTIVATE", 1002 "status": "ACTIVE", 1003 "submitDate": "2022-08-17T09:13:18Z", 1004 "updateDate": "2022-08-17T09:15:35Z", 1005 "note": "test activation", 1006 "notifyEmails": [ 1007 "test@example.com" 1008 ], 1009 "fmaActivationState": "steady", 1010 "fallbackInfo": { 1011 "fastFallbackAttempted": false, 1012 "fallbackVersion": 4, 1013 "canFastFallback": false, 1014 "steadyStateTime": 1660727735, 1015 "fastFallbackExpirationTime": 1660731335, 1016 "fastFallbackRecoveryState": null 1017 }, 1018 "includeId": "inc_12345", 1019 "includeName": "tfp_test1", 1020 "includeType": "MICROSERVICES", 1021 "includeVersion": 1 1022 } 1023 ] 1024 } 1025 }`, 1026 expectedResponse: &ListIncludeActivationsResponse{ 1027 AccountID: "test_account", 1028 ContractID: "test_contract", 1029 GroupID: "test_group", 1030 Activations: IncludeActivationsRes{ 1031 Items: []IncludeActivation{ 1032 { 1033 ActivationID: "atv_12344", 1034 Network: "STAGING", 1035 ActivationType: ActivationTypeActivate, 1036 Status: ActivationStatusActive, 1037 SubmitDate: "2022-10-27T12:27:54Z", 1038 UpdateDate: "2022-10-27T12:28:54Z", 1039 Note: "test activation", 1040 NotifyEmails: []string{"test@example.com"}, 1041 FMAActivationState: "steady", 1042 FallbackInfo: &ActivationFallbackInfo{ 1043 FastFallbackAttempted: false, 1044 FallbackVersion: 3, 1045 CanFastFallback: false, 1046 SteadyStateTime: 1666873734, 1047 FastFallbackExpirationTime: 1666877334, 1048 }, 1049 IncludeID: "inc_12345", 1050 IncludeName: "tfp_test1", 1051 IncludeType: "MICROSERVICES", 1052 IncludeVersion: 4, 1053 }, 1054 { 1055 ActivationID: "atv_12343", 1056 Network: "STAGING", 1057 ActivationType: ActivationTypeActivate, 1058 Status: ActivationStatusActive, 1059 SubmitDate: "2022-10-27T11:21:40Z", 1060 UpdateDate: "2022-10-27T11:22:54Z", 1061 Note: "test activation", 1062 NotifyEmails: []string{"test@example.com"}, 1063 FMAActivationState: "steady", 1064 FallbackInfo: &ActivationFallbackInfo{ 1065 FastFallbackAttempted: false, 1066 FallbackVersion: 4, 1067 CanFastFallback: false, 1068 SteadyStateTime: 1666869774, 1069 FastFallbackExpirationTime: 1666873374, 1070 }, 1071 IncludeID: "inc_12345", 1072 IncludeName: "tfp_test1", 1073 IncludeType: "MICROSERVICES", 1074 IncludeVersion: 3, 1075 }, 1076 { 1077 ActivationID: "atv_12343", 1078 Network: "STAGING", 1079 ActivationType: ActivationTypeDeactivate, 1080 Status: ActivationStatusActive, 1081 SubmitDate: "2022-10-26T12:41:58Z", 1082 UpdateDate: "2022-10-26T13:03:04Z", 1083 Note: "test activation", 1084 NotifyEmails: []string{"test@example.com"}, 1085 IncludeID: "inc_12345", 1086 IncludeName: "tfp_test1", 1087 IncludeType: "MICROSERVICES", 1088 IncludeVersion: 3, 1089 }, 1090 { 1091 ActivationID: "atv_12342", 1092 Network: "STAGING", 1093 ActivationType: ActivationTypeActivate, 1094 Status: ActivationStatusActive, 1095 SubmitDate: "2022-10-26T12:37:49Z", 1096 UpdateDate: "2022-10-26T12:38:59Z", 1097 Note: "test activation", 1098 NotifyEmails: []string{"test@example.com"}, 1099 FMAActivationState: "steady", 1100 FallbackInfo: &ActivationFallbackInfo{ 1101 FastFallbackAttempted: false, 1102 FallbackVersion: 4, 1103 CanFastFallback: false, 1104 SteadyStateTime: 1666787939, 1105 FastFallbackExpirationTime: 1666791539, 1106 }, 1107 IncludeID: "inc_12345", 1108 IncludeName: "tfp_test1", 1109 IncludeType: "MICROSERVICES", 1110 IncludeVersion: 2, 1111 }, 1112 { 1113 ActivationID: "atv_12341", 1114 Network: "STAGING", 1115 ActivationType: ActivationTypeActivate, 1116 Status: ActivationStatusActive, 1117 SubmitDate: "2022-08-17T09:13:18Z", 1118 UpdateDate: "2022-08-17T09:15:35Z", 1119 Note: "test activation", 1120 NotifyEmails: []string{"test@example.com"}, 1121 FMAActivationState: "steady", 1122 FallbackInfo: &ActivationFallbackInfo{ 1123 FastFallbackAttempted: false, 1124 FallbackVersion: 4, 1125 CanFastFallback: false, 1126 SteadyStateTime: 1660727735, 1127 FastFallbackExpirationTime: 1660731335, 1128 }, 1129 IncludeID: "inc_12345", 1130 IncludeName: "tfp_test1", 1131 IncludeType: "MICROSERVICES", 1132 IncludeVersion: 1, 1133 }, 1134 }, 1135 }, 1136 }, 1137 }, 1138 "500 internal server error": { 1139 params: ListIncludeActivationsRequest{ 1140 IncludeID: "inc_12345", 1141 ContractID: "test_contract", 1142 GroupID: "test_group", 1143 }, 1144 expectedPath: "/papi/v1/includes/inc_12345/activations?contractId=test_contract&groupId=test_group", 1145 responseStatus: http.StatusInternalServerError, 1146 responseBody: ` 1147 { 1148 "type": "internal_error", 1149 "title": "Internal Server Error", 1150 "detail": "Error getting include", 1151 "status": 500 1152 }`, 1153 withError: &Error{ 1154 Type: "internal_error", 1155 Title: "Internal Server Error", 1156 Detail: "Error getting include", 1157 StatusCode: http.StatusInternalServerError, 1158 }, 1159 }, 1160 "validation error - missing include id": { 1161 params: ListIncludeActivationsRequest{ 1162 ContractID: "test_contract", 1163 GroupID: "test_group", 1164 }, 1165 withError: ErrStructValidation, 1166 }, 1167 "validation error - contract id": { 1168 params: ListIncludeActivationsRequest{ 1169 IncludeID: "inc_12345", 1170 GroupID: "test_group", 1171 }, 1172 withError: ErrStructValidation, 1173 }, 1174 "validation error - group id": { 1175 params: ListIncludeActivationsRequest{ 1176 IncludeID: "inc_12345", 1177 ContractID: "test_contract", 1178 }, 1179 withError: ErrStructValidation, 1180 }, 1181 } 1182 for name, test := range tests { 1183 t.Run(name, func(t *testing.T) { 1184 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 1185 assert.Equal(t, test.expectedPath, r.URL.String()) 1186 assert.Equal(t, http.MethodGet, r.Method) 1187 w.WriteHeader(test.responseStatus) 1188 _, err := w.Write([]byte(test.responseBody)) 1189 assert.NoError(t, err) 1190 })) 1191 client := mockAPIClient(t, mockServer) 1192 result, err := client.ListIncludeActivations(context.Background(), test.params) 1193 if test.withError != nil { 1194 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 1195 return 1196 } 1197 require.NoError(t, err) 1198 assert.Equal(t, test.expectedResponse, result) 1199 }) 1200 } 1201 }