github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/papi/propertyversion_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/akamai/AkamaiOPEN-edgegrid-golang/v8/pkg/tools" 11 12 "github.com/stretchr/testify/assert" 13 "github.com/stretchr/testify/require" 14 ) 15 16 func TestPapi_GetPropertyVersions(t *testing.T) { 17 tests := map[string]struct { 18 params GetPropertyVersionsRequest 19 responseStatus int 20 responseBody string 21 expectedPath string 22 expectedResponse *GetPropertyVersionsResponse 23 withError func(*testing.T, error) 24 }{ 25 "200 OK": { 26 params: GetPropertyVersionsRequest{ 27 PropertyID: "propertyID", 28 ContractID: "contract", 29 GroupID: "group", 30 Limit: 5, 31 Offset: 6, 32 }, 33 responseStatus: http.StatusOK, 34 responseBody: ` 35 { 36 "propertyId": "propertyID", 37 "propertyName": "property_name", 38 "accountId": "accountID", 39 "contractId": "contract", 40 "groupId": "group", 41 "assetId": "assetID", 42 "versions": { 43 "items": [ 44 { 45 "propertyVersion": 2, 46 "updatedByUser": "user", 47 "updatedDate": "2020-09-14T19:06:13Z", 48 "productionStatus": "INACTIVE", 49 "stagingStatus": "ACTIVE", 50 "etag": "etag", 51 "productId": "productID", 52 "note": "version note" 53 } 54 ] 55 } 56 }`, 57 expectedPath: "/papi/v1/properties/propertyID/versions?contractId=contract&groupId=group&limit=5&offset=6", 58 expectedResponse: &GetPropertyVersionsResponse{ 59 PropertyID: "propertyID", 60 PropertyName: "property_name", 61 AccountID: "accountID", 62 ContractID: "contract", 63 GroupID: "group", 64 AssetID: "assetID", 65 Versions: PropertyVersionItems{ 66 Items: []PropertyVersionGetItem{ 67 { 68 Etag: "etag", 69 Note: "version note", 70 ProductID: "productID", 71 ProductionStatus: "INACTIVE", 72 PropertyVersion: 2, 73 StagingStatus: "ACTIVE", 74 UpdatedByUser: "user", 75 UpdatedDate: "2020-09-14T19:06:13Z", 76 }}}, 77 }, 78 }, 79 "500 Internal Server Error": { 80 params: GetPropertyVersionsRequest{ 81 PropertyID: "propertyID", 82 ContractID: "contract", 83 GroupID: "group", 84 Limit: 5, 85 Offset: 6, 86 }, 87 responseStatus: http.StatusInternalServerError, 88 responseBody: ` 89 { 90 "type": "internal_error", 91 "title": "Internal Server Error", 92 "detail": "Error fetching property versions", 93 "status": 505 94 }`, 95 expectedPath: "/papi/v1/properties/propertyID/versions?contractId=contract&groupId=group&limit=5&offset=6", 96 withError: func(t *testing.T, err error) { 97 want := &Error{ 98 Type: "internal_error", 99 Title: "Internal Server Error", 100 Detail: "Error fetching property versions", 101 StatusCode: http.StatusInternalServerError, 102 } 103 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 104 }, 105 }, 106 "empty property ID": { 107 params: GetPropertyVersionsRequest{ 108 PropertyID: "", 109 ContractID: "contract", 110 GroupID: "group", 111 }, 112 withError: func(t *testing.T, err error) { 113 want := ErrStructValidation 114 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 115 assert.Contains(t, err.Error(), "PropertyID") 116 }, 117 }, 118 } 119 120 for name, test := range tests { 121 t.Run(name, func(t *testing.T) { 122 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 123 assert.Equal(t, test.expectedPath, r.URL.String()) 124 assert.Equal(t, http.MethodGet, r.Method) 125 w.WriteHeader(test.responseStatus) 126 _, err := w.Write([]byte(test.responseBody)) 127 assert.NoError(t, err) 128 })) 129 client := mockAPIClient(t, mockServer) 130 result, err := client.GetPropertyVersions(context.Background(), test.params) 131 if test.withError != nil { 132 test.withError(t, err) 133 return 134 } 135 require.NoError(t, err) 136 assert.Equal(t, test.expectedResponse, result) 137 }) 138 } 139 } 140 141 func TestPapi_GetPropertyVersion(t *testing.T) { 142 tests := map[string]struct { 143 params GetPropertyVersionRequest 144 responseStatus int 145 responseBody string 146 expectedPath string 147 expectedResponse *GetPropertyVersionsResponse 148 withError func(*testing.T, error) 149 }{ 150 "200 OK": { 151 params: GetPropertyVersionRequest{ 152 PropertyID: "propertyID", 153 PropertyVersion: 2, 154 ContractID: "contract", 155 GroupID: "group", 156 }, 157 responseStatus: http.StatusOK, 158 responseBody: ` 159 { 160 "propertyId": "propertyID", 161 "propertyName": "property_name", 162 "accountId": "accountID", 163 "contractId": "contract", 164 "groupId": "group", 165 "assetId": "assetID", 166 "versions": { 167 "items": [ 168 { 169 "propertyVersion": 2, 170 "updatedByUser": "user", 171 "updatedDate": "2020-09-14T19:06:13Z", 172 "productionStatus": "INACTIVE", 173 "stagingStatus": "ACTIVE", 174 "etag": "etag", 175 "productId": "productID", 176 "note": "version note" 177 } 178 ] 179 } 180 }`, 181 expectedPath: "/papi/v1/properties/propertyID/versions/2?contractId=contract&groupId=group", 182 expectedResponse: &GetPropertyVersionsResponse{ 183 PropertyID: "propertyID", 184 PropertyName: "property_name", 185 AccountID: "accountID", 186 ContractID: "contract", 187 GroupID: "group", 188 AssetID: "assetID", 189 Versions: PropertyVersionItems{ 190 Items: []PropertyVersionGetItem{ 191 { 192 Etag: "etag", 193 Note: "version note", 194 ProductID: "productID", 195 ProductionStatus: "INACTIVE", 196 PropertyVersion: 2, 197 StagingStatus: "ACTIVE", 198 UpdatedByUser: "user", 199 UpdatedDate: "2020-09-14T19:06:13Z", 200 }}}, 201 Version: PropertyVersionGetItem{ 202 203 Etag: "etag", 204 Note: "version note", 205 ProductID: "productID", 206 ProductionStatus: "INACTIVE", 207 PropertyVersion: 2, 208 StagingStatus: "ACTIVE", 209 UpdatedByUser: "user", 210 UpdatedDate: "2020-09-14T19:06:13Z", 211 }, 212 }, 213 }, 214 "version not found": { 215 params: GetPropertyVersionRequest{ 216 PropertyID: "propertyID", 217 PropertyVersion: 2, 218 ContractID: "contract", 219 GroupID: "group", 220 }, 221 responseStatus: http.StatusOK, 222 responseBody: ` 223 { 224 "propertyId": "propertyID", 225 "propertyName": "property_name", 226 "accountId": "accountID", 227 "contractId": "contract", 228 "groupId": "group", 229 "assetId": "assetID", 230 "versions": { 231 "items": [ 232 ] 233 } 234 }`, 235 expectedPath: "/papi/v1/properties/propertyID/versions/2?contractId=contract&groupId=group", 236 withError: func(t *testing.T, err error) { 237 assert.True(t, errors.Is(err, ErrNotFound), "want: %s; got: %s", ErrNotFound, err) 238 }, 239 }, 240 "500 Internal Server Error": { 241 params: GetPropertyVersionRequest{ 242 PropertyID: "propertyID", 243 PropertyVersion: 2, 244 ContractID: "contract", 245 GroupID: "group", 246 }, 247 responseStatus: http.StatusInternalServerError, 248 responseBody: ` 249 { 250 "type": "internal_error", 251 "title": "Internal Server Error", 252 "detail": "Error fetching property version", 253 "status": 505 254 }`, 255 expectedPath: "/papi/v1/properties/propertyID/versions/2?contractId=contract&groupId=group", 256 withError: func(t *testing.T, err error) { 257 want := &Error{ 258 Type: "internal_error", 259 Title: "Internal Server Error", 260 Detail: "Error fetching property version", 261 StatusCode: http.StatusInternalServerError, 262 } 263 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 264 }, 265 }, 266 "empty property ID": { 267 params: GetPropertyVersionRequest{ 268 PropertyID: "", 269 PropertyVersion: 2, 270 ContractID: "contract", 271 GroupID: "group", 272 }, 273 withError: func(t *testing.T, err error) { 274 want := ErrStructValidation 275 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 276 assert.Contains(t, err.Error(), "PropertyID") 277 }, 278 }, 279 "empty property version": { 280 params: GetPropertyVersionRequest{ 281 PropertyID: "propertyID", 282 ContractID: "contract", 283 GroupID: "group", 284 }, 285 withError: func(t *testing.T, err error) { 286 want := ErrStructValidation 287 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 288 assert.Contains(t, err.Error(), "PropertyVersion") 289 }, 290 }, 291 } 292 293 for name, test := range tests { 294 t.Run(name, func(t *testing.T) { 295 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 296 assert.Equal(t, test.expectedPath, r.URL.String()) 297 assert.Equal(t, http.MethodGet, r.Method) 298 w.WriteHeader(test.responseStatus) 299 _, err := w.Write([]byte(test.responseBody)) 300 assert.NoError(t, err) 301 })) 302 client := mockAPIClient(t, mockServer) 303 result, err := client.GetPropertyVersion(context.Background(), test.params) 304 if test.withError != nil { 305 test.withError(t, err) 306 return 307 } 308 require.NoError(t, err) 309 assert.Equal(t, test.expectedResponse, result) 310 }) 311 } 312 } 313 314 func TestPapi_CreatePropertyVersion(t *testing.T) { 315 tests := map[string]struct { 316 params CreatePropertyVersionRequest 317 responseStatus int 318 responseBody string 319 expectedPath string 320 expectedResponse *CreatePropertyVersionResponse 321 withError func(*testing.T, error) 322 }{ 323 "201 Created": { 324 params: CreatePropertyVersionRequest{ 325 PropertyID: "propertyID", 326 ContractID: "contract", 327 GroupID: "group", 328 Version: PropertyVersionCreate{ 329 CreateFromVersion: 1, 330 }, 331 }, 332 responseStatus: http.StatusCreated, 333 responseBody: ` 334 { 335 "versionLink": "/papi/v1/properties/propertyID/versions/2?contractId=contract&groupId=group" 336 }`, 337 expectedPath: "/papi/v1/properties/propertyID/versions?contractId=contract&groupId=group", 338 expectedResponse: &CreatePropertyVersionResponse{ 339 VersionLink: "/papi/v1/properties/propertyID/versions/2?contractId=contract&groupId=group", 340 PropertyVersion: 2, 341 }, 342 }, 343 "500 Internal Server Error": { 344 params: CreatePropertyVersionRequest{ 345 PropertyID: "propertyID", 346 ContractID: "contract", 347 GroupID: "group", 348 Version: PropertyVersionCreate{ 349 CreateFromVersion: 1, 350 }, 351 }, 352 responseStatus: http.StatusInternalServerError, 353 responseBody: ` 354 { 355 "type": "internal_error", 356 "title": "Internal Server Error", 357 "detail": "Error creating property version", 358 "status": 500 359 }`, 360 expectedPath: "/papi/v1/properties/propertyID/versions?contractId=contract&groupId=group", 361 withError: func(t *testing.T, err error) { 362 want := &Error{ 363 Type: "internal_error", 364 Title: "Internal Server Error", 365 Detail: "Error creating property version", 366 StatusCode: http.StatusInternalServerError, 367 } 368 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 369 }, 370 }, 371 "empty property ID": { 372 params: CreatePropertyVersionRequest{ 373 PropertyID: "", 374 ContractID: "contract", 375 GroupID: "group", 376 Version: PropertyVersionCreate{ 377 CreateFromVersion: 1, 378 }, 379 }, 380 withError: func(t *testing.T, err error) { 381 want := ErrStructValidation 382 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 383 assert.Contains(t, err.Error(), "PropertyID") 384 }, 385 }, 386 "empty CreateFromVersion": { 387 params: CreatePropertyVersionRequest{ 388 PropertyID: "propertyID", 389 ContractID: "contract", 390 GroupID: "group", 391 Version: PropertyVersionCreate{}, 392 }, 393 withError: func(t *testing.T, err error) { 394 want := ErrStructValidation 395 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 396 assert.Contains(t, err.Error(), "CreateFromVersion") 397 }, 398 }, 399 "invalid location": { 400 params: CreatePropertyVersionRequest{ 401 PropertyID: "propertyID", 402 ContractID: "contract", 403 GroupID: "group", 404 Version: PropertyVersionCreate{ 405 CreateFromVersion: 1, 406 }, 407 }, 408 responseStatus: http.StatusCreated, 409 responseBody: ` 410 { 411 "versionLink": ":" 412 }`, 413 expectedPath: "/papi/v1/properties/propertyID/versions?contractId=contract&groupId=group", 414 withError: func(t *testing.T, err error) { 415 want := ErrInvalidResponseLink 416 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 417 }, 418 }, 419 "invalid version format": { 420 params: CreatePropertyVersionRequest{ 421 PropertyID: "propertyID", 422 ContractID: "contract", 423 GroupID: "group", 424 Version: PropertyVersionCreate{ 425 CreateFromVersion: 1, 426 }, 427 }, 428 responseStatus: http.StatusCreated, 429 responseBody: ` 430 { 431 "versionLink": "/papi/v1/properties/propertyID/versions/abc?contractId=contract&groupId=group" 432 }`, 433 expectedPath: "/papi/v1/properties/propertyID/versions?contractId=contract&groupId=group", 434 withError: func(t *testing.T, err error) { 435 want := ErrInvalidResponseLink 436 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 437 }, 438 }, 439 } 440 441 for name, test := range tests { 442 t.Run(name, func(t *testing.T) { 443 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 444 assert.Equal(t, test.expectedPath, r.URL.String()) 445 assert.Equal(t, http.MethodPost, r.Method) 446 w.WriteHeader(test.responseStatus) 447 _, err := w.Write([]byte(test.responseBody)) 448 assert.NoError(t, err) 449 })) 450 client := mockAPIClient(t, mockServer) 451 result, err := client.CreatePropertyVersion(context.Background(), test.params) 452 if test.withError != nil { 453 test.withError(t, err) 454 return 455 } 456 require.NoError(t, err) 457 assert.Equal(t, test.expectedResponse, result) 458 }) 459 } 460 } 461 462 func TestPapi_GetLatestVersion(t *testing.T) { 463 tests := map[string]struct { 464 params GetLatestVersionRequest 465 responseStatus int 466 responseBody string 467 expectedPath string 468 expectedResponse *GetPropertyVersionsResponse 469 withError func(*testing.T, error) 470 }{ 471 "200 OK": { 472 params: GetLatestVersionRequest{ 473 PropertyID: "propertyID", 474 ActivatedOn: "STAGING", 475 ContractID: "contract", 476 GroupID: "group", 477 }, 478 responseStatus: http.StatusOK, 479 expectedPath: "/papi/v1/properties/propertyID/versions/latest?activatedOn=STAGING&contractId=contract&groupId=group", 480 responseBody: ` 481 { 482 "propertyId": "propertyID", 483 "propertyName": "property_name", 484 "accountId": "accountID", 485 "contractId": "contract", 486 "groupId": "group", 487 "assetId": "assetID", 488 "versions": { 489 "items": [ 490 { 491 "propertyVersion": 2, 492 "updatedByUser": "user", 493 "updatedDate": "2020-09-14T19:06:13Z", 494 "productionStatus": "INACTIVE", 495 "stagingStatus": "ACTIVE", 496 "etag": "etag", 497 "productId": "productID", 498 "note": "version note" 499 } 500 ] 501 } 502 }`, 503 expectedResponse: &GetPropertyVersionsResponse{ 504 PropertyID: "propertyID", 505 PropertyName: "property_name", 506 AccountID: "accountID", 507 ContractID: "contract", 508 GroupID: "group", 509 AssetID: "assetID", 510 Versions: PropertyVersionItems{ 511 Items: []PropertyVersionGetItem{ 512 { 513 Etag: "etag", 514 Note: "version note", 515 ProductID: "productID", 516 ProductionStatus: "INACTIVE", 517 PropertyVersion: 2, 518 StagingStatus: "ACTIVE", 519 UpdatedByUser: "user", 520 UpdatedDate: "2020-09-14T19:06:13Z", 521 }, 522 }, 523 }, 524 Version: PropertyVersionGetItem{ 525 Etag: "etag", 526 Note: "version note", 527 ProductID: "productID", 528 ProductionStatus: "INACTIVE", 529 PropertyVersion: 2, 530 StagingStatus: "ACTIVE", 531 UpdatedByUser: "user", 532 UpdatedDate: "2020-09-14T19:06:13Z", 533 }, 534 }, 535 }, 536 "Version not found": { 537 params: GetLatestVersionRequest{ 538 PropertyID: "propertyID", 539 ActivatedOn: "STAGING", 540 ContractID: "contract", 541 GroupID: "group", 542 }, 543 responseStatus: http.StatusOK, 544 expectedPath: "/papi/v1/properties/propertyID/versions/latest?activatedOn=STAGING&contractId=contract&groupId=group", 545 responseBody: ` 546 { 547 "propertyId": "propertyID", 548 "propertyName": "property_name", 549 "accountId": "accountID", 550 "contractId": "contract", 551 "groupId": "group", 552 "assetId": "assetID", 553 "versions": { 554 "items": [ 555 ] 556 } 557 }`, 558 withError: func(t *testing.T, err error) { 559 assert.True(t, errors.Is(err, ErrNotFound), "want: %v; got: %v", ErrNotFound, err) 560 }, 561 }, 562 "500 Internal Server Error": { 563 params: GetLatestVersionRequest{ 564 PropertyID: "propertyID", 565 ContractID: "contract", 566 GroupID: "group", 567 }, 568 responseStatus: http.StatusInternalServerError, 569 responseBody: ` 570 { 571 "type": "internal_error", 572 "title": "Internal Server Error", 573 "detail": "Error fetching latest version", 574 "status": 500 575 }`, 576 expectedPath: "/papi/v1/properties/propertyID/versions/latest?contractId=contract&groupId=group", 577 withError: func(t *testing.T, err error) { 578 want := &Error{ 579 Type: "internal_error", 580 Title: "Internal Server Error", 581 Detail: "Error fetching latest version", 582 StatusCode: http.StatusInternalServerError, 583 } 584 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 585 }, 586 }, 587 "empty property ID": { 588 params: GetLatestVersionRequest{ 589 PropertyID: "", 590 ActivatedOn: "STAGING", 591 ContractID: "contract", 592 GroupID: "group", 593 }, 594 withError: func(t *testing.T, err error) { 595 want := ErrStructValidation 596 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 597 assert.Contains(t, err.Error(), "PropertyID") 598 }, 599 }, 600 "invalid ActivatedOn": { 601 params: GetLatestVersionRequest{ 602 PropertyID: "propertyID", 603 ActivatedOn: "test", 604 ContractID: "contract", 605 GroupID: "group", 606 }, 607 withError: func(t *testing.T, err error) { 608 want := ErrStructValidation 609 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 610 assert.Contains(t, err.Error(), "ActivatedOn") 611 }, 612 }, 613 } 614 615 for name, test := range tests { 616 t.Run(name, func(t *testing.T) { 617 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 618 assert.Equal(t, test.expectedPath, r.URL.String()) 619 assert.Equal(t, http.MethodGet, r.Method) 620 w.WriteHeader(test.responseStatus) 621 _, err := w.Write([]byte(test.responseBody)) 622 assert.NoError(t, err) 623 })) 624 client := mockAPIClient(t, mockServer) 625 result, err := client.GetLatestVersion(context.Background(), test.params) 626 if test.withError != nil { 627 test.withError(t, err) 628 return 629 } 630 require.NoError(t, err) 631 assert.Equal(t, test.expectedResponse, result) 632 }) 633 } 634 } 635 636 func TestPapi_GetAvailableBehaviors(t *testing.T) { 637 tests := map[string]struct { 638 params GetAvailableBehaviorsRequest 639 responseStatus int 640 responseBody string 641 expectedPath string 642 expectedResponse *GetBehaviorsResponse 643 withError func(*testing.T, error) 644 }{ 645 "200 OK": { 646 params: GetAvailableBehaviorsRequest{ 647 PropertyID: "propertyID", 648 PropertyVersion: 2, 649 }, 650 responseStatus: http.StatusOK, 651 expectedPath: "/papi/v1/properties/propertyID/versions/2/available-behaviors", 652 responseBody: ` 653 { 654 "contractId": "contract", 655 "groupId": "group", 656 "productId": "productID", 657 "ruleFormat": "v2020-09-15", 658 "behaviors": { 659 "items": [ 660 { 661 "name": "allHttpInCacheHierarchy", 662 "schemaLink": "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fbehaviors%2FallHttpInCacheHierarchy" 663 }, 664 { 665 "name": "allowDelete", 666 "schemaLink": "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fbehaviors%2FallowDelete" 667 }, 668 { 669 "name": "allowOptions", 670 "schemaLink": "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fbehaviors%2FallowOptions" 671 } 672 ] 673 } 674 }`, 675 expectedResponse: &GetBehaviorsResponse{ 676 ContractID: "contract", 677 GroupID: "group", 678 ProductID: "productID", 679 RuleFormat: "v2020-09-15", 680 AvailableBehaviors: AvailableBehaviors{Items: []Behavior{ 681 { 682 Name: "allHttpInCacheHierarchy", 683 SchemaLink: "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fbehaviors%2FallHttpInCacheHierarchy", 684 }, 685 { 686 Name: "allowDelete", 687 SchemaLink: "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fbehaviors%2FallowDelete", 688 }, 689 { 690 Name: "allowOptions", 691 SchemaLink: "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fbehaviors%2FallowOptions", 692 }, 693 }}, 694 }, 695 }, 696 "200 OK with query parameters": { 697 params: GetAvailableBehaviorsRequest{ 698 PropertyID: "propertyID", 699 PropertyVersion: 2, 700 GroupID: "groupID", 701 ContractID: "contractID", 702 }, 703 responseStatus: http.StatusOK, 704 expectedPath: "/papi/v1/properties/propertyID/versions/2/available-behaviors?contractId=contractID&groupId=groupID", 705 responseBody: ` 706 { 707 "contractId": "contract", 708 "groupId": "group", 709 "productId": "productID", 710 "ruleFormat": "v2020-09-15", 711 "behaviors": { 712 "items": [ 713 { 714 "name": "allHttpInCacheHierarchy", 715 "schemaLink": "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fbehaviors%2FallHttpInCacheHierarchy" 716 }, 717 { 718 "name": "allowDelete", 719 "schemaLink": "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fbehaviors%2FallowDelete" 720 }, 721 { 722 "name": "allowOptions", 723 "schemaLink": "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fbehaviors%2FallowOptions" 724 } 725 ] 726 } 727 }`, 728 expectedResponse: &GetBehaviorsResponse{ 729 ContractID: "contract", 730 GroupID: "group", 731 ProductID: "productID", 732 RuleFormat: "v2020-09-15", 733 AvailableBehaviors: AvailableBehaviors{Items: []Behavior{ 734 { 735 Name: "allHttpInCacheHierarchy", 736 SchemaLink: "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fbehaviors%2FallHttpInCacheHierarchy", 737 }, 738 { 739 Name: "allowDelete", 740 SchemaLink: "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fbehaviors%2FallowDelete", 741 }, 742 { 743 Name: "allowOptions", 744 SchemaLink: "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fbehaviors%2FallowOptions", 745 }, 746 }}, 747 }, 748 }, 749 "500 Internal Server Error": { 750 params: GetAvailableBehaviorsRequest{ 751 PropertyID: "propertyID", 752 PropertyVersion: 2, 753 }, 754 responseStatus: http.StatusInternalServerError, 755 responseBody: ` 756 { 757 "type": "internal_error", 758 "title": "Internal Server Error", 759 "detail": "Error fetching available behaviors", 760 "status": 500 761 }`, 762 expectedPath: "/papi/v1/properties/propertyID/versions/2/available-behaviors", 763 withError: func(t *testing.T, err error) { 764 want := &Error{ 765 Type: "internal_error", 766 Title: "Internal Server Error", 767 Detail: "Error fetching available behaviors", 768 StatusCode: http.StatusInternalServerError, 769 } 770 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 771 }, 772 }, 773 "empty property ID": { 774 params: GetAvailableBehaviorsRequest{ 775 PropertyID: "", 776 PropertyVersion: 2, 777 }, 778 withError: func(t *testing.T, err error) { 779 want := ErrStructValidation 780 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 781 assert.Contains(t, err.Error(), "PropertyID") 782 }, 783 }, 784 "empty property version": { 785 params: GetAvailableBehaviorsRequest{ 786 PropertyID: "propertyID", 787 }, 788 withError: func(t *testing.T, err error) { 789 want := ErrStructValidation 790 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 791 assert.Contains(t, err.Error(), "PropertyVersion") 792 }, 793 }, 794 } 795 796 for name, test := range tests { 797 t.Run(name, func(t *testing.T) { 798 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 799 assert.Equal(t, test.expectedPath, r.URL.String()) 800 assert.Equal(t, http.MethodGet, r.Method) 801 w.WriteHeader(test.responseStatus) 802 _, err := w.Write([]byte(test.responseBody)) 803 assert.NoError(t, err) 804 })) 805 client := mockAPIClient(t, mockServer) 806 result, err := client.GetAvailableBehaviors(context.Background(), test.params) 807 if test.withError != nil { 808 test.withError(t, err) 809 return 810 } 811 require.NoError(t, err) 812 assert.Equal(t, test.expectedResponse, result) 813 }) 814 } 815 } 816 817 func TestPapi_GetAvailableCriteria(t *testing.T) { 818 tests := map[string]struct { 819 params GetAvailableCriteriaRequest 820 responseStatus int 821 responseBody string 822 expectedPath string 823 expectedResponse *GetCriteriaResponse 824 withError func(*testing.T, error) 825 }{ 826 "200 OK": { 827 params: GetAvailableCriteriaRequest{ 828 PropertyID: "propertyID", 829 PropertyVersion: 2, 830 }, 831 responseStatus: http.StatusOK, 832 expectedPath: "/papi/v1/properties/propertyID/versions/2/available-criteria", 833 responseBody: ` 834 { 835 "contractId": "contract", 836 "groupId": "group", 837 "productId": "productID", 838 "ruleFormat": "v2020-09-15", 839 "criteria": { 840 "items": [ 841 { 842 "name": "bucket", 843 "schemaLink": "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fcriteria%2Fbucket" 844 }, 845 { 846 "name": "cacheability", 847 "schemaLink": "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fcriteria%2Fcacheability" 848 }, 849 { 850 "name": "chinaCdnRegion", 851 "schemaLink": "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fcriteria%2FchinaCdnRegion" 852 } 853 ] 854 } 855 }`, 856 expectedResponse: &GetCriteriaResponse{ 857 ContractID: "contract", 858 GroupID: "group", 859 ProductID: "productID", 860 RuleFormat: "v2020-09-15", 861 AvailableCriteria: AvailableCriteria{Items: []Criteria{ 862 { 863 Name: "bucket", 864 SchemaLink: "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fcriteria%2Fbucket", 865 }, 866 { 867 Name: "cacheability", 868 SchemaLink: "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fcriteria%2Fcacheability", 869 }, 870 { 871 Name: "chinaCdnRegion", 872 SchemaLink: "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fcriteria%2FchinaCdnRegion", 873 }, 874 }}, 875 }, 876 }, 877 "200 OK with query parameters": { 878 params: GetAvailableCriteriaRequest{ 879 PropertyID: "propertyID", 880 PropertyVersion: 2, 881 GroupID: "groupID", 882 ContractID: "contractID", 883 }, 884 responseStatus: http.StatusOK, 885 expectedPath: "/papi/v1/properties/propertyID/versions/2/available-criteria?contractId=contractID&groupId=groupID", 886 responseBody: ` 887 { 888 "contractId": "contract", 889 "groupId": "group", 890 "productId": "productID", 891 "ruleFormat": "v2020-09-15", 892 "criteria": { 893 "items": [ 894 { 895 "name": "bucket", 896 "schemaLink": "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fcriteria%2Fbucket" 897 }, 898 { 899 "name": "cacheability", 900 "schemaLink": "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fcriteria%2Fcacheability" 901 }, 902 { 903 "name": "chinaCdnRegion", 904 "schemaLink": "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fcriteria%2FchinaCdnRegion" 905 } 906 ] 907 } 908 }`, 909 expectedResponse: &GetCriteriaResponse{ 910 ContractID: "contract", 911 GroupID: "group", 912 ProductID: "productID", 913 RuleFormat: "v2020-09-15", 914 AvailableCriteria: AvailableCriteria{Items: []Criteria{ 915 { 916 Name: "bucket", 917 SchemaLink: "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fcriteria%2Fbucket", 918 }, 919 { 920 Name: "cacheability", 921 SchemaLink: "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fcriteria%2Fcacheability", 922 }, 923 { 924 Name: "chinaCdnRegion", 925 SchemaLink: "/papi/v0/schemas/products/prd_Rich_Media_Accel/latest#%2Fdefinitions%2Fcatalog%2Fcriteria%2FchinaCdnRegion", 926 }, 927 }}, 928 }, 929 }, 930 "500 Internal Server Error": { 931 params: GetAvailableCriteriaRequest{ 932 PropertyID: "propertyID", 933 PropertyVersion: 2, 934 }, 935 responseStatus: http.StatusInternalServerError, 936 responseBody: ` 937 { 938 "type": "internal_error", 939 "title": "Internal Server Error", 940 "detail": "Error fetching available behaviors", 941 "status": 500 942 }`, 943 expectedPath: "/papi/v1/properties/propertyID/versions/2/available-criteria", 944 withError: func(t *testing.T, err error) { 945 want := &Error{ 946 Type: "internal_error", 947 Title: "Internal Server Error", 948 Detail: "Error fetching available behaviors", 949 StatusCode: http.StatusInternalServerError, 950 } 951 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 952 }, 953 }, 954 "empty property ID": { 955 params: GetAvailableCriteriaRequest{ 956 PropertyID: "", 957 PropertyVersion: 2, 958 }, 959 withError: func(t *testing.T, err error) { 960 want := ErrStructValidation 961 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 962 assert.Contains(t, err.Error(), "PropertyID") 963 }, 964 }, 965 "empty property version": { 966 params: GetAvailableCriteriaRequest{ 967 PropertyID: "propertyID", 968 }, 969 withError: func(t *testing.T, err error) { 970 want := ErrStructValidation 971 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 972 assert.Contains(t, err.Error(), "PropertyVersion") 973 }, 974 }, 975 } 976 977 for name, test := range tests { 978 t.Run(name, func(t *testing.T) { 979 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 980 assert.Equal(t, test.expectedPath, r.URL.String()) 981 assert.Equal(t, http.MethodGet, r.Method) 982 w.WriteHeader(test.responseStatus) 983 _, err := w.Write([]byte(test.responseBody)) 984 assert.NoError(t, err) 985 })) 986 client := mockAPIClient(t, mockServer) 987 result, err := client.GetAvailableCriteria(context.Background(), test.params) 988 if test.withError != nil { 989 test.withError(t, err) 990 return 991 } 992 require.NoError(t, err) 993 assert.Equal(t, test.expectedResponse, result) 994 }) 995 } 996 } 997 998 func TestPapi_ListAvailableIncludes(t *testing.T) { 999 tests := map[string]struct { 1000 params ListAvailableIncludesRequest 1001 responseStatus int 1002 responseBody string 1003 expectedPath string 1004 expectedResponse *ListAvailableIncludesResponse 1005 withError error 1006 }{ 1007 "200 OK - available includes given ContractID and GroupID": { 1008 params: ListAvailableIncludesRequest{ 1009 PropertyID: "propertyID", 1010 PropertyVersion: 1, 1011 ContractID: "ctr_1", 1012 GroupID: "grp_2", 1013 }, 1014 responseStatus: http.StatusOK, 1015 expectedPath: "/papi/v1/properties/propertyID/versions/1/external-resources?contractId=ctr_1&groupId=grp_2", 1016 responseBody: ` 1017 { 1018 "externalResources": { 1019 "include": { 1020 "test_include_id1": { 1021 "id": "test_include_id1", 1022 "name": "test_include1", 1023 "includeType": "MICROSERVICES", 1024 "fileName": "test_include1.xml", 1025 "productName": "Example_Name", 1026 "ruleFormat": "v2020-11-02" 1027 }, 1028 "test_include_id2": { 1029 "id": "test_include_id2", 1030 "name": "test_include2", 1031 "includeType": "MICROSERVICES", 1032 "fileName": "test_include2.xml", 1033 "productName": "Example_Name", 1034 "ruleFormat": "v2020-11-02" 1035 } 1036 }, 1037 "cloudletSharedPolicy": { 1038 "123456": { 1039 "cloudletType": "TESTCLOUDLETTYPE", 1040 "id": 123456, 1041 "name": "TestName123456", 1042 "policyType": "SHARED" 1043 } 1044 }, 1045 "availableCnames": [ 1046 { 1047 "id": 123456, 1048 "name": "www.example.com", 1049 "domain": "example.net", 1050 "serialNumber": 123, 1051 "slot": null, 1052 "status": "Created", 1053 "ipv6": false, 1054 "useCases": [], 1055 "cname": "www.example.example.net", 1056 "isSecure": false, 1057 "isEdgeIPBindingEnabled": null 1058 } 1059 ], 1060 "customOverrides": {}, 1061 "customOverrides": {}, 1062 "blacklistedCertDomains": [ 1063 "s3.example.com" 1064 ], 1065 "availableNetStorageGroups": [ 1066 { 1067 "id": 123456, 1068 "name": "aa-example", 1069 "uploadDomainName": "spm.example.example.com", 1070 "downloadDomainName": "spm.example.example.com", 1071 "cpCodeList": [ 1072 { 1073 "cpCode": 123456, 1074 "g2oToken": null 1075 } 1076 ] 1077 } 1078 ], 1079 "availableCpCodes": [ 1080 { 1081 "id": 123123, 1082 "description": "example-test-subgroup", 1083 "products": [ 1084 "EXAMPLE" 1085 ], 1086 "createdDate": 1521566901000, 1087 "cpCodeLimits": null, 1088 "name": "example-test-subgroup" 1089 } 1090 ], 1091 "availablePolicies": { 1092 "applicationLoadBalancer":[ 1093 { 1094 "id": 123456, 1095 "name": "0000000000000000_EXAMPLE_clone" 1096 } 1097 ], 1098 "firstPartyMarketingPlus":[ 1099 { 1100 "id": 123456, 1101 "name": "Example_Name_123456" 1102 } 1103 ], 1104 "firstPartyMarketing":[ 1105 { 1106 "id": 123456, 1107 "name": "Example_first_party" 1108 } 1109 ], 1110 "forwardRewrite":[ 1111 { 1112 "id": 123456, 1113 "name": "ExampleName" 1114 } 1115 ], 1116 "continuousDeployment":[ 1117 { 1118 "id": 123456, 1119 "name": "Example_Name_123456" 1120 } 1121 ], 1122 "requestControl":[ 1123 { 1124 "id": 123456, 1125 "name": "EXAMPLE_MATCH_RULE_SIZE_RC" 1126 } 1127 ], 1128 "inputValidation":[ 1129 { 1130 "id": 123456, 1131 "name": "example_name" 1132 } 1133 ], 1134 "visitorPrioritization":[ 1135 { 1136 "id": 123456, 1137 "name": "0000000000000000000000_EXAMPLE" 1138 } 1139 ], 1140 "audienceSegmentation":[ 1141 { 1142 "id": 123456, 1143 "name": "ExampleTest" 1144 } 1145 ], 1146 "apiPrioritization":[ 1147 { 1148 "id": 123456, 1149 "name": "APIExampleTest" 1150 } 1151 ], 1152 "edgeRedirector":[ 1153 { 1154 "id": 123456, 1155 "name": "00000000_EXAMPLE" 1156 } 1157 ] 1158 }, 1159 "cloudletSharedPolicyVirtualWaitingRoom": { 1160 "123456": { 1161 "cloudletType": "EXAMPLETYPE", 1162 "id": 123456, 1163 "name": "example_name", 1164 "policyType": "SHARED" 1165 } 1166 } 1167 } 1168 }`, 1169 expectedResponse: &ListAvailableIncludesResponse{ 1170 AvailableIncludes: []ExternalIncludeData{ 1171 1172 { 1173 IncludeID: "test_include_id1", 1174 IncludeName: "test_include1", 1175 IncludeType: IncludeTypeMicroServices, 1176 FileName: "test_include1.xml", 1177 ProductName: "Example_Name", 1178 RuleFormat: "v2020-11-02", 1179 }, 1180 { 1181 IncludeID: "test_include_id2", 1182 IncludeName: "test_include2", 1183 IncludeType: IncludeTypeMicroServices, 1184 FileName: "test_include2.xml", 1185 ProductName: "Example_Name", 1186 RuleFormat: "v2020-11-02", 1187 }, 1188 }, 1189 }, 1190 }, 1191 "200 OK - available includes given only ContractID": { 1192 params: ListAvailableIncludesRequest{ 1193 PropertyID: "propertyID", 1194 PropertyVersion: 1, 1195 ContractID: "ctr_1", 1196 }, 1197 responseStatus: http.StatusOK, 1198 expectedPath: "/papi/v1/properties/propertyID/versions/1/external-resources?contractId=ctr_1", 1199 responseBody: ` 1200 { 1201 "externalResources": { 1202 "include": { 1203 "test_include_id1": { 1204 "id": "test_include_id1", 1205 "name": "test_include1", 1206 "includeType": "MICROSERVICES", 1207 "fileName": "test_include1.xml", 1208 "productName": "Example_Name", 1209 "ruleFormat": "v2020-11-02" 1210 }, 1211 "test_include_id2": { 1212 "id": "test_include_id2", 1213 "name": "test_include2", 1214 "includeType": "MICROSERVICES", 1215 "fileName": "test_include2.xml", 1216 "productName": "Example_Name", 1217 "ruleFormat": "v2020-11-02" 1218 } 1219 }, 1220 "cloudletSharedPolicy": { 1221 "123456": { 1222 "cloudletType": "TESTCLOUDLETTYPE", 1223 "id": 123456, 1224 "name": "TestName123456", 1225 "policyType": "SHARED" 1226 } 1227 }, 1228 "availableCnames": [ 1229 { 1230 "id": 123456, 1231 "name": "www.example.com", 1232 "domain": "example.net", 1233 "serialNumber": 123, 1234 "slot": null, 1235 "status": "Created", 1236 "ipv6": false, 1237 "useCases": [], 1238 "cname": "www.example.example.net", 1239 "isSecure": false, 1240 "isEdgeIPBindingEnabled": null 1241 } 1242 ], 1243 "customOverrides": {}, 1244 "customOverrides": {}, 1245 "blacklistedCertDomains": [ 1246 "s3.example.com" 1247 ], 1248 "availableNetStorageGroups": [ 1249 { 1250 "id": 123456, 1251 "name": "aa-example", 1252 "uploadDomainName": "spm.example.example.com", 1253 "downloadDomainName": "spm.example.example.com", 1254 "cpCodeList": [ 1255 { 1256 "cpCode": 123456, 1257 "g2oToken": null 1258 } 1259 ] 1260 } 1261 ], 1262 "availableCpCodes": [ 1263 { 1264 "id": 123123, 1265 "description": "example-test-subgroup", 1266 "products": [ 1267 "EXAMPLE" 1268 ], 1269 "createdDate": 1521566901000, 1270 "cpCodeLimits": null, 1271 "name": "example-test-subgroup" 1272 } 1273 ], 1274 "availablePolicies": { 1275 "applicationLoadBalancer":[ 1276 { 1277 "id": 123456, 1278 "name": "0000000000000000_EXAMPLE_clone" 1279 } 1280 ], 1281 "firstPartyMarketingPlus":[ 1282 { 1283 "id": 123456, 1284 "name": "Example_Name_123456" 1285 } 1286 ], 1287 "firstPartyMarketing":[ 1288 { 1289 "id": 123456, 1290 "name": "Example_first_party" 1291 } 1292 ], 1293 "forwardRewrite":[ 1294 { 1295 "id": 123456, 1296 "name": "ExampleName" 1297 } 1298 ], 1299 "continuousDeployment":[ 1300 { 1301 "id": 123456, 1302 "name": "Example_Name_123456" 1303 } 1304 ], 1305 "requestControl":[ 1306 { 1307 "id": 123456, 1308 "name": "EXAMPLE_MATCH_RULE_SIZE_RC" 1309 } 1310 ], 1311 "inputValidation":[ 1312 { 1313 "id": 123456, 1314 "name": "example_name" 1315 } 1316 ], 1317 "visitorPrioritization":[ 1318 { 1319 "id": 123456, 1320 "name": "0000000000000000000000_EXAMPLE" 1321 } 1322 ], 1323 "audienceSegmentation":[ 1324 { 1325 "id": 123456, 1326 "name": "ExampleTest" 1327 } 1328 ], 1329 "apiPrioritization":[ 1330 { 1331 "id": 123456, 1332 "name": "APIExampleTest" 1333 } 1334 ], 1335 "edgeRedirector":[ 1336 { 1337 "id": 123456, 1338 "name": "00000000_EXAMPLE" 1339 } 1340 ] 1341 }, 1342 "cloudletSharedPolicyVirtualWaitingRoom": { 1343 "123456": { 1344 "cloudletType": "EXAMPLETYPE", 1345 "id": 123456, 1346 "name": "example_name", 1347 "policyType": "SHARED" 1348 } 1349 } 1350 } 1351 }`, 1352 expectedResponse: &ListAvailableIncludesResponse{ 1353 AvailableIncludes: []ExternalIncludeData{ 1354 1355 { 1356 IncludeID: "test_include_id1", 1357 IncludeName: "test_include1", 1358 IncludeType: IncludeTypeMicroServices, 1359 FileName: "test_include1.xml", 1360 ProductName: "Example_Name", 1361 RuleFormat: "v2020-11-02", 1362 }, 1363 { 1364 IncludeID: "test_include_id2", 1365 IncludeName: "test_include2", 1366 IncludeType: IncludeTypeMicroServices, 1367 FileName: "test_include2.xml", 1368 ProductName: "Example_Name", 1369 RuleFormat: "v2020-11-02", 1370 }, 1371 }, 1372 }, 1373 }, 1374 "200 OK - available includes given only GroupID": { 1375 params: ListAvailableIncludesRequest{ 1376 PropertyID: "propertyID", 1377 PropertyVersion: 1, 1378 GroupID: "grp_2", 1379 }, 1380 responseStatus: http.StatusOK, 1381 expectedPath: "/papi/v1/properties/propertyID/versions/1/external-resources?groupId=grp_2", 1382 responseBody: ` 1383 { 1384 "externalResources": { 1385 "include": { 1386 "test_include_id1": { 1387 "id": "test_include_id1", 1388 "name": "test_include1", 1389 "includeType": "MICROSERVICES", 1390 "fileName": "test_include1.xml", 1391 "productName": "Example_Name", 1392 "ruleFormat": "v2020-11-02" 1393 }, 1394 "test_include_id2": { 1395 "id": "test_include_id2", 1396 "name": "test_include2", 1397 "includeType": "MICROSERVICES", 1398 "fileName": "test_include2.xml", 1399 "productName": "Example_Name", 1400 "ruleFormat": "v2020-11-02" 1401 } 1402 }, 1403 "cloudletSharedPolicy": { 1404 "123456": { 1405 "cloudletType": "TESTCLOUDLETTYPE", 1406 "id": 123456, 1407 "name": "TestName123456", 1408 "policyType": "SHARED" 1409 } 1410 }, 1411 "availableCnames": [ 1412 { 1413 "id": 123456, 1414 "name": "www.example.com", 1415 "domain": "example.net", 1416 "serialNumber": 123, 1417 "slot": null, 1418 "status": "Created", 1419 "ipv6": false, 1420 "useCases": [], 1421 "cname": "www.example.example.net", 1422 "isSecure": false, 1423 "isEdgeIPBindingEnabled": null 1424 } 1425 ], 1426 "customOverrides": {}, 1427 "customOverrides": {}, 1428 "blacklistedCertDomains": [ 1429 "s3.example.com" 1430 ], 1431 "availableNetStorageGroups": [ 1432 { 1433 "id": 123456, 1434 "name": "aa-example", 1435 "uploadDomainName": "spm.example.example.com", 1436 "downloadDomainName": "spm.example.example.com", 1437 "cpCodeList": [ 1438 { 1439 "cpCode": 123456, 1440 "g2oToken": null 1441 } 1442 ] 1443 } 1444 ], 1445 "availableCpCodes": [ 1446 { 1447 "id": 123123, 1448 "description": "example-test-subgroup", 1449 "products": [ 1450 "EXAMPLE" 1451 ], 1452 "createdDate": 1521566901000, 1453 "cpCodeLimits": null, 1454 "name": "example-test-subgroup" 1455 } 1456 ], 1457 "availablePolicies": { 1458 "applicationLoadBalancer":[ 1459 { 1460 "id": 123456, 1461 "name": "0000000000000000_EXAMPLE_clone" 1462 } 1463 ], 1464 "firstPartyMarketingPlus":[ 1465 { 1466 "id": 123456, 1467 "name": "Example_Name_123456" 1468 } 1469 ], 1470 "firstPartyMarketing":[ 1471 { 1472 "id": 123456, 1473 "name": "Example_first_party" 1474 } 1475 ], 1476 "forwardRewrite":[ 1477 { 1478 "id": 123456, 1479 "name": "ExampleName" 1480 } 1481 ], 1482 "continuousDeployment":[ 1483 { 1484 "id": 123456, 1485 "name": "Example_Name_123456" 1486 } 1487 ], 1488 "requestControl":[ 1489 { 1490 "id": 123456, 1491 "name": "EXAMPLE_MATCH_RULE_SIZE_RC" 1492 } 1493 ], 1494 "inputValidation":[ 1495 { 1496 "id": 123456, 1497 "name": "example_name" 1498 } 1499 ], 1500 "visitorPrioritization":[ 1501 { 1502 "id": 123456, 1503 "name": "0000000000000000000000_EXAMPLE" 1504 } 1505 ], 1506 "audienceSegmentation":[ 1507 { 1508 "id": 123456, 1509 "name": "ExampleTest" 1510 } 1511 ], 1512 "apiPrioritization":[ 1513 { 1514 "id": 123456, 1515 "name": "APIExampleTest" 1516 } 1517 ], 1518 "edgeRedirector":[ 1519 { 1520 "id": 123456, 1521 "name": "00000000_EXAMPLE" 1522 } 1523 ] 1524 }, 1525 "cloudletSharedPolicyVirtualWaitingRoom": { 1526 "123456": { 1527 "cloudletType": "EXAMPLETYPE", 1528 "id": 123456, 1529 "name": "example_name", 1530 "policyType": "SHARED" 1531 } 1532 } 1533 } 1534 }`, 1535 expectedResponse: &ListAvailableIncludesResponse{ 1536 AvailableIncludes: []ExternalIncludeData{ 1537 1538 { 1539 IncludeID: "test_include_id1", 1540 IncludeName: "test_include1", 1541 IncludeType: IncludeTypeMicroServices, 1542 FileName: "test_include1.xml", 1543 ProductName: "Example_Name", 1544 RuleFormat: "v2020-11-02", 1545 }, 1546 { 1547 IncludeID: "test_include_id2", 1548 IncludeName: "test_include2", 1549 IncludeType: IncludeTypeMicroServices, 1550 FileName: "test_include2.xml", 1551 ProductName: "Example_Name", 1552 RuleFormat: "v2020-11-02", 1553 }, 1554 }, 1555 }, 1556 }, 1557 "200 OK - available includes ContractID and GroupID not provided": { 1558 params: ListAvailableIncludesRequest{ 1559 PropertyID: "propertyID", 1560 PropertyVersion: 1, 1561 }, 1562 responseStatus: http.StatusOK, 1563 expectedPath: "/papi/v1/properties/propertyID/versions/1/external-resources", 1564 responseBody: ` 1565 { 1566 "externalResources": { 1567 "include": { 1568 "test_include_id1": { 1569 "id": "test_include_id1", 1570 "name": "test_include1", 1571 "includeType": "MICROSERVICES", 1572 "fileName": "test_include1.xml", 1573 "productName": "Example_Name", 1574 "ruleFormat": "v2020-11-02" 1575 }, 1576 "test_include_id2": { 1577 "id": "test_include_id2", 1578 "name": "test_include2", 1579 "includeType": "MICROSERVICES", 1580 "fileName": "test_include2.xml", 1581 "productName": "Example_Name", 1582 "ruleFormat": "v2020-11-02" 1583 } 1584 }, 1585 "cloudletSharedPolicy": { 1586 "123456": { 1587 "cloudletType": "TESTCLOUDLETTYPE", 1588 "id": 123456, 1589 "name": "TestName123456", 1590 "policyType": "SHARED" 1591 } 1592 }, 1593 "availableCnames": [ 1594 { 1595 "id": 123456, 1596 "name": "www.example.com", 1597 "domain": "example.net", 1598 "serialNumber": 123, 1599 "slot": null, 1600 "status": "Created", 1601 "ipv6": false, 1602 "useCases": [], 1603 "cname": "www.example.example.net", 1604 "isSecure": false, 1605 "isEdgeIPBindingEnabled": null 1606 } 1607 ], 1608 "customOverrides": {}, 1609 "customOverrides": {}, 1610 "blacklistedCertDomains": [ 1611 "s3.example.com" 1612 ], 1613 "availableNetStorageGroups": [ 1614 { 1615 "id": 123456, 1616 "name": "aa-example", 1617 "uploadDomainName": "spm.example.example.com", 1618 "downloadDomainName": "spm.example.example.com", 1619 "cpCodeList": [ 1620 { 1621 "cpCode": 123456, 1622 "g2oToken": null 1623 } 1624 ] 1625 } 1626 ], 1627 "availableCpCodes": [ 1628 { 1629 "id": 123123, 1630 "description": "example-test-subgroup", 1631 "products": [ 1632 "EXAMPLE" 1633 ], 1634 "createdDate": 1521566901000, 1635 "cpCodeLimits": null, 1636 "name": "example-test-subgroup" 1637 } 1638 ], 1639 "availablePolicies": { 1640 "applicationLoadBalancer":[ 1641 { 1642 "id": 123456, 1643 "name": "0000000000000000_EXAMPLE_clone" 1644 } 1645 ], 1646 "firstPartyMarketingPlus":[ 1647 { 1648 "id": 123456, 1649 "name": "Example_Name_123456" 1650 } 1651 ], 1652 "firstPartyMarketing":[ 1653 { 1654 "id": 123456, 1655 "name": "Example_first_party" 1656 } 1657 ], 1658 "forwardRewrite":[ 1659 { 1660 "id": 123456, 1661 "name": "ExampleName" 1662 } 1663 ], 1664 "continuousDeployment":[ 1665 { 1666 "id": 123456, 1667 "name": "Example_Name_123456" 1668 } 1669 ], 1670 "requestControl":[ 1671 { 1672 "id": 123456, 1673 "name": "EXAMPLE_MATCH_RULE_SIZE_RC" 1674 } 1675 ], 1676 "inputValidation":[ 1677 { 1678 "id": 123456, 1679 "name": "example_name" 1680 } 1681 ], 1682 "visitorPrioritization":[ 1683 { 1684 "id": 123456, 1685 "name": "0000000000000000000000_EXAMPLE" 1686 } 1687 ], 1688 "audienceSegmentation":[ 1689 { 1690 "id": 123456, 1691 "name": "ExampleTest" 1692 } 1693 ], 1694 "apiPrioritization":[ 1695 { 1696 "id": 123456, 1697 "name": "APIExampleTest" 1698 } 1699 ], 1700 "edgeRedirector":[ 1701 { 1702 "id": 123456, 1703 "name": "00000000_EXAMPLE" 1704 } 1705 ] 1706 }, 1707 "cloudletSharedPolicyVirtualWaitingRoom": { 1708 "123456": { 1709 "cloudletType": "EXAMPLETYPE", 1710 "id": 123456, 1711 "name": "example_name", 1712 "policyType": "SHARED" 1713 } 1714 } 1715 } 1716 }`, 1717 expectedResponse: &ListAvailableIncludesResponse{ 1718 AvailableIncludes: []ExternalIncludeData{ 1719 1720 { 1721 IncludeID: "test_include_id1", 1722 IncludeName: "test_include1", 1723 IncludeType: IncludeTypeMicroServices, 1724 FileName: "test_include1.xml", 1725 ProductName: "Example_Name", 1726 RuleFormat: "v2020-11-02", 1727 }, 1728 { 1729 IncludeID: "test_include_id2", 1730 IncludeName: "test_include2", 1731 IncludeType: IncludeTypeMicroServices, 1732 FileName: "test_include2.xml", 1733 ProductName: "Example_Name", 1734 RuleFormat: "v2020-11-02", 1735 }, 1736 }, 1737 }, 1738 }, 1739 "500 Internal Server Error": { 1740 params: ListAvailableIncludesRequest{ 1741 PropertyID: "propertyID", 1742 PropertyVersion: 1, 1743 ContractID: "ctr_1", 1744 GroupID: "grp_2", 1745 }, 1746 responseStatus: http.StatusInternalServerError, 1747 responseBody: ` 1748 { 1749 "type": "internal_error", 1750 "title": "Internal Server Error", 1751 "detail": "Error fetching available includes", 1752 "status": 500 1753 }`, 1754 expectedPath: "/papi/v1/properties/propertyID/versions/1/external-resources?contractId=ctr_1&groupId=grp_2", 1755 withError: &Error{ 1756 Type: "internal_error", 1757 Title: "Internal Server Error", 1758 Detail: "Error fetching available includes", 1759 StatusCode: http.StatusInternalServerError, 1760 }, 1761 }, 1762 "validation error - missing property ID": { 1763 params: ListAvailableIncludesRequest{ 1764 PropertyVersion: 2, 1765 ContractID: "ctr_1", 1766 GroupID: "grp_2", 1767 }, 1768 withError: ErrStructValidation, 1769 }, 1770 "validation error - missing property version": { 1771 params: ListAvailableIncludesRequest{ 1772 PropertyID: "propertyID", 1773 ContractID: "ctr_1", 1774 GroupID: "grp_2", 1775 }, 1776 withError: ErrStructValidation, 1777 }, 1778 } 1779 1780 for name, test := range tests { 1781 t.Run(name, func(t *testing.T) { 1782 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 1783 assert.Equal(t, test.expectedPath, r.URL.String()) 1784 assert.Equal(t, http.MethodGet, r.Method) 1785 w.WriteHeader(test.responseStatus) 1786 _, err := w.Write([]byte(test.responseBody)) 1787 assert.NoError(t, err) 1788 })) 1789 client := mockAPIClient(t, mockServer) 1790 result, err := client.ListAvailableIncludes(context.Background(), test.params) 1791 if test.withError != nil { 1792 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 1793 return 1794 } 1795 require.NoError(t, err) 1796 assert.Equal(t, len(test.expectedResponse.AvailableIncludes), len(result.AvailableIncludes)) 1797 for _, element := range test.expectedResponse.AvailableIncludes { 1798 assert.Contains(t, result.AvailableIncludes, element) 1799 } 1800 }) 1801 } 1802 } 1803 1804 func TestPapi_ListReferencedIncludes(t *testing.T) { 1805 tests := map[string]struct { 1806 params ListReferencedIncludesRequest 1807 responseStatus int 1808 responseBody string 1809 expectedPath string 1810 expectedResponse *ListReferencedIncludesResponse 1811 withError error 1812 }{ 1813 "200 OK": { 1814 params: ListReferencedIncludesRequest{ 1815 PropertyID: "propertyID", 1816 PropertyVersion: 1, 1817 ContractID: "ctr_1", 1818 GroupID: "grp_2", 1819 }, 1820 responseStatus: http.StatusOK, 1821 expectedPath: "/papi/v1/properties/propertyID/versions/1/includes?contractId=ctr_1&groupId=grp_2", 1822 responseBody: ` 1823 { 1824 "includes": { 1825 "items": [ 1826 { 1827 "accountId": "test_account", 1828 "contractId": "test_contract", 1829 "groupId": "test_group", 1830 "latestVersion": 1, 1831 "stagingVersion": 1, 1832 "productionVersion": null, 1833 "assetId": "test_asset", 1834 "includeId": "inc_123456", 1835 "includeName": "test_include", 1836 "includeType": "MICROSERVICES" 1837 } 1838 ] 1839 } 1840 }`, 1841 expectedResponse: &ListReferencedIncludesResponse{ 1842 Includes: IncludeItems{ 1843 Items: []Include{ 1844 { 1845 AccountID: "test_account", 1846 AssetID: "test_asset", 1847 ContractID: "test_contract", 1848 GroupID: "test_group", 1849 IncludeID: "inc_123456", 1850 IncludeName: "test_include", 1851 IncludeType: IncludeTypeMicroServices, 1852 LatestVersion: 1, 1853 ProductionVersion: nil, 1854 StagingVersion: tools.IntPtr(1), 1855 }, 1856 }, 1857 }, 1858 }, 1859 }, 1860 "500 Internal Server Error": { 1861 params: ListReferencedIncludesRequest{ 1862 PropertyID: "propertyID", 1863 PropertyVersion: 1, 1864 ContractID: "ctr_1", 1865 GroupID: "grp_2", 1866 }, 1867 responseStatus: http.StatusInternalServerError, 1868 responseBody: ` 1869 { 1870 "type": "internal_error", 1871 "title": "Internal Server Error", 1872 "detail": "Error fetching referenced includes", 1873 "status": 500 1874 }`, 1875 expectedPath: "/papi/v1/properties/propertyID/versions/1/includes?contractId=ctr_1&groupId=grp_2", 1876 withError: &Error{ 1877 Type: "internal_error", 1878 Title: "Internal Server Error", 1879 Detail: "Error fetching referenced includes", 1880 StatusCode: http.StatusInternalServerError, 1881 }, 1882 }, 1883 "validation error - missing property ID": { 1884 params: ListReferencedIncludesRequest{ 1885 PropertyVersion: 1, 1886 ContractID: "ctr_1", 1887 GroupID: "grp_2", 1888 }, 1889 withError: ErrStructValidation, 1890 }, 1891 "validation error - missing property version": { 1892 params: ListReferencedIncludesRequest{ 1893 PropertyID: "propertyID", 1894 ContractID: "ctr_1", 1895 GroupID: "grp_2", 1896 }, 1897 withError: ErrStructValidation, 1898 }, 1899 "validation error - missing contractID": { 1900 params: ListReferencedIncludesRequest{ 1901 PropertyID: "propertyID", 1902 PropertyVersion: 1, 1903 GroupID: "grp_2", 1904 }, 1905 withError: ErrStructValidation, 1906 }, 1907 "validation error - missing groupID": { 1908 params: ListReferencedIncludesRequest{ 1909 PropertyID: "propertyID", 1910 PropertyVersion: 1, 1911 ContractID: "ctr_1", 1912 }, 1913 withError: ErrStructValidation, 1914 }, 1915 } 1916 1917 for name, test := range tests { 1918 t.Run(name, func(t *testing.T) { 1919 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 1920 assert.Equal(t, test.expectedPath, r.URL.String()) 1921 assert.Equal(t, http.MethodGet, r.Method) 1922 w.WriteHeader(test.responseStatus) 1923 _, err := w.Write([]byte(test.responseBody)) 1924 assert.NoError(t, err) 1925 })) 1926 client := mockAPIClient(t, mockServer) 1927 result, err := client.ListReferencedIncludes(context.Background(), test.params) 1928 if test.withError != nil { 1929 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 1930 return 1931 } 1932 require.NoError(t, err) 1933 assert.Equal(t, test.expectedResponse, result) 1934 }) 1935 } 1936 }