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