github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/cloudlets/v3/policy_test.go (about) 1 package v3 2 3 import ( 4 "context" 5 "errors" 6 "io" 7 "net/http" 8 "net/http/httptest" 9 "strings" 10 "testing" 11 12 "github.com/akamai/AkamaiOPEN-edgegrid-golang/v8/pkg/tools" 13 "github.com/stretchr/testify/assert" 14 "github.com/stretchr/testify/require" 15 ) 16 17 func TestListPolicies(t *testing.T) { 18 tests := map[string]struct { 19 params ListPoliciesRequest 20 responseStatus int 21 responseBody string 22 expectedPath string 23 expectedResponse *ListPoliciesResponse 24 withError func(*testing.T, error) 25 }{ 26 "200 OK - two policies, one minimal and one with activation data": { 27 params: ListPoliciesRequest{}, 28 responseStatus: http.StatusOK, 29 responseBody: ` 30 { 31 "content": [ 32 { 33 "cloudletType": "CD", 34 "createdBy": "User1", 35 "createdDate": "2023-10-23T11:21:19.896Z", 36 "currentActivations": { 37 "production": { 38 "effective": null, 39 "latest": null 40 }, 41 "staging": { 42 "effective": null, 43 "latest": null 44 } 45 }, 46 "description": null, 47 "groupId": 1, 48 "id": 11, 49 "links": [ 50 { 51 "href": "Link1", 52 "rel": "self" 53 } 54 ], 55 "modifiedBy": "User2", 56 "modifiedDate": "2023-10-23T11:21:19.896Z", 57 "name": "Name1", 58 "policyType": "SHARED" 59 }, 60 { 61 "cloudletType": "CD", 62 "createdBy": "User1", 63 "createdDate": "2023-10-23T11:21:19.896Z", 64 "currentActivations": { 65 "production": { 66 "effective": { 67 "createdBy": "User1", 68 "createdDate": "2023-10-23T11:21:19.896Z", 69 "finishDate": "2023-10-23T11:22:57.589Z", 70 "id": 123, 71 "links": [ 72 { 73 "href": "Link1", 74 "rel": "self" 75 } 76 ], 77 "network": "PRODUCTION", 78 "operation": "ACTIVATION", 79 "policyId": 1234, 80 "policyVersion": 1, 81 "policyVersionDeleted": false, 82 "status": "SUCCESS" 83 }, 84 "latest": { 85 "createdBy": "User1", 86 "createdDate": "2023-10-23T11:21:19.896Z", 87 "finishDate": "2023-10-23T11:22:57.589Z", 88 "id": 321, 89 "links": [ 90 { 91 "href": "Link2", 92 "rel": "self" 93 } 94 ], 95 "network": "PRODUCTION", 96 "operation": "ACTIVATION", 97 "policyId": 4321, 98 "policyVersion": 1, 99 "policyVersionDeleted": false, 100 "status": "SUCCESS" 101 } 102 }, 103 "staging": { 104 "effective": { 105 "createdBy": "User3", 106 "createdDate": "2023-10-23T11:21:19.896Z", 107 "finishDate": "2023-10-23T11:22:57.589Z", 108 "id": 789, 109 "links": [ 110 { 111 "href": "Link3", 112 "rel": "self" 113 } 114 ], 115 "network": "STAGING", 116 "operation": "ACTIVATION", 117 "policyId": 6789, 118 "policyVersion": 1, 119 "policyVersionDeleted": false, 120 "status": "SUCCESS" 121 }, 122 "latest": { 123 "createdBy": "User3", 124 "createdDate": "2023-10-23T11:21:19.896Z", 125 "finishDate": "2023-10-23T11:22:57.589Z", 126 "id": 987, 127 "links": [ 128 { 129 "href": "Link4", 130 "rel": "self" 131 } 132 ], 133 "network": "STAGING", 134 "operation": "ACTIVATION", 135 "policyId": 9876, 136 "policyVersion": 1, 137 "policyVersionDeleted": false, 138 "status": "SUCCESS" 139 } 140 } 141 }, 142 "description": "Test", 143 "groupId": 1, 144 "id": 22, 145 "links": [ 146 { 147 "href": "Link5", 148 "rel": "self" 149 } 150 ], 151 "modifiedBy": "User1", 152 "modifiedDate": "2023-10-23T11:21:19.896Z", 153 "name": "TestName", 154 "policyType": "SHARED" 155 } 156 ], 157 "links": [ 158 { 159 "href": "/cloudlets/v3/policies?page=0&size=1000", 160 "rel": "self" 161 } 162 ], 163 "page": { 164 "number": 0, 165 "size": 1000, 166 "totalElements": 54, 167 "totalPages": 1 168 } 169 } 170 `, 171 expectedPath: "/cloudlets/v3/policies", 172 expectedResponse: &ListPoliciesResponse{ 173 Content: []Policy{ 174 { 175 CloudletType: CloudletTypeCD, 176 CreatedBy: "User1", 177 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 178 CurrentActivations: CurrentActivations{}, 179 Description: nil, 180 GroupID: 1, 181 ID: 11, 182 Links: []Link{ 183 { 184 Href: "Link1", 185 Rel: "self", 186 }, 187 }, 188 ModifiedBy: "User2", 189 ModifiedDate: newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 190 Name: "Name1", 191 PolicyType: PolicyTypeShared, 192 }, 193 { 194 CloudletType: CloudletTypeCD, 195 CreatedBy: "User1", 196 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 197 CurrentActivations: CurrentActivations{ 198 Production: ActivationInfo{ 199 Effective: &PolicyActivation{ 200 CreatedBy: "User1", 201 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 202 FinishDate: newTimeFromString(t, "2023-10-23T11:22:57.589Z"), 203 ID: 123, 204 Links: []Link{ 205 { 206 Href: "Link1", 207 Rel: "self", 208 }, 209 }, 210 Network: ProductionNetwork, 211 Operation: OperationActivation, 212 PolicyID: 1234, 213 PolicyVersion: 1, 214 PolicyVersionDeleted: false, 215 Status: ActivationStatusSuccess, 216 }, 217 Latest: &PolicyActivation{ 218 CreatedBy: "User1", 219 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 220 FinishDate: newTimeFromString(t, "2023-10-23T11:22:57.589Z"), 221 ID: 321, 222 Links: []Link{ 223 { 224 Href: "Link2", 225 Rel: "self", 226 }, 227 }, 228 Network: ProductionNetwork, 229 Operation: OperationActivation, 230 PolicyID: 4321, 231 PolicyVersion: 1, 232 PolicyVersionDeleted: false, 233 Status: ActivationStatusSuccess, 234 }, 235 }, 236 Staging: ActivationInfo{ 237 Effective: &PolicyActivation{ 238 CreatedBy: "User3", 239 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 240 FinishDate: newTimeFromString(t, "2023-10-23T11:22:57.589Z"), 241 ID: 789, 242 Links: []Link{ 243 { 244 Href: "Link3", 245 Rel: "self", 246 }, 247 }, 248 Network: StagingNetwork, 249 Operation: OperationActivation, 250 PolicyID: 6789, 251 PolicyVersion: 1, 252 PolicyVersionDeleted: false, 253 Status: ActivationStatusSuccess, 254 }, 255 Latest: &PolicyActivation{ 256 CreatedBy: "User3", 257 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 258 FinishDate: newTimeFromString(t, "2023-10-23T11:22:57.589Z"), 259 ID: 987, 260 Links: []Link{ 261 { 262 Href: "Link4", 263 Rel: "self", 264 }, 265 }, 266 Network: StagingNetwork, 267 Operation: OperationActivation, 268 PolicyID: 9876, 269 PolicyVersion: 1, 270 PolicyVersionDeleted: false, 271 Status: ActivationStatusSuccess, 272 }, 273 }, 274 }, 275 Description: tools.StringPtr("Test"), 276 GroupID: 1, 277 ID: 22, 278 Links: []Link{ 279 { 280 Href: "Link5", 281 Rel: "self", 282 }, 283 }, 284 ModifiedBy: "User1", 285 ModifiedDate: newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 286 Name: "TestName", 287 PolicyType: PolicyTypeShared, 288 }, 289 }, 290 Links: []Link{ 291 { 292 Href: "/cloudlets/v3/policies?page=0&size=1000", 293 Rel: "self", 294 }, 295 }, 296 Page: Page{ 297 Number: 0, 298 Size: 1000, 299 TotalElements: 54, 300 TotalPages: 1, 301 }, 302 }, 303 }, 304 "200 OK - with query params": { 305 params: ListPoliciesRequest{ 306 Page: 2, 307 Size: 12, 308 }, 309 responseStatus: http.StatusOK, 310 responseBody: ` 311 { 312 "content": [ 313 { 314 "cloudletType": "CD", 315 "createdBy": "User1", 316 "createdDate": "2023-10-23T11:21:19.896Z", 317 "currentActivations": { 318 "production": { 319 "effective": null, 320 "latest": null 321 }, 322 "staging": { 323 "effective": null, 324 "latest": null 325 } 326 }, 327 "description": null, 328 "groupId": 1, 329 "id": 11, 330 "links": [ 331 { 332 "href": "Link1", 333 "rel": "self" 334 } 335 ], 336 "modifiedBy": "User2", 337 "modifiedDate": "2023-10-23T11:21:19.896Z", 338 "name": "Name1", 339 "policyType": "SHARED" 340 } 341 ], 342 "links": [ 343 { 344 "href": "/cloudlets/v3/policies?page=0&size=1000", 345 "rel": "self" 346 } 347 ], 348 "page": { 349 "number": 0, 350 "size": 1000, 351 "totalElements": 54, 352 "totalPages": 1 353 } 354 } 355 `, 356 expectedPath: "/cloudlets/v3/policies?page=2&size=12", 357 expectedResponse: &ListPoliciesResponse{ 358 Content: []Policy{ 359 { 360 CloudletType: CloudletTypeCD, 361 CreatedBy: "User1", 362 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 363 CurrentActivations: CurrentActivations{}, 364 Description: nil, 365 GroupID: 1, 366 ID: 11, 367 Links: []Link{ 368 { 369 Href: "Link1", 370 Rel: "self", 371 }, 372 }, 373 ModifiedBy: "User2", 374 ModifiedDate: newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 375 Name: "Name1", 376 PolicyType: PolicyTypeShared, 377 }, 378 }, 379 Links: []Link{ 380 { 381 Href: "/cloudlets/v3/policies?page=0&size=1000", 382 Rel: "self", 383 }, 384 }, 385 Page: Page{ 386 Number: 0, 387 Size: 1000, 388 TotalElements: 54, 389 TotalPages: 1, 390 }, 391 }, 392 }, 393 "200 OK - empty content": { 394 params: ListPoliciesRequest{}, 395 responseStatus: http.StatusOK, 396 responseBody: ` 397 { 398 "content": [], 399 "links": [ 400 { 401 "href": "/cloudlets/v3/policies?page=0&size=1000", 402 "rel": "self" 403 } 404 ], 405 "page": { 406 "number": 0, 407 "size": 1000, 408 "totalElements": 0, 409 "totalPages": 1 410 } 411 } 412 `, 413 expectedPath: "/cloudlets/v3/policies", 414 expectedResponse: &ListPoliciesResponse{ 415 Content: []Policy{}, 416 Links: []Link{ 417 { 418 Href: "/cloudlets/v3/policies?page=0&size=1000", 419 Rel: "self", 420 }, 421 }, 422 Page: Page{ 423 Number: 0, 424 Size: 1000, 425 TotalElements: 0, 426 TotalPages: 1, 427 }, 428 }, 429 }, 430 "validation errors - size lower than 10, negative page number": { 431 params: ListPoliciesRequest{ 432 Page: -2, 433 Size: 5, 434 }, 435 withError: func(t *testing.T, err error) { 436 assert.Equal(t, "list shared policies: struct validation: Page: must be no less than 0\nSize: must be no less than 10", err.Error()) 437 }, 438 }, 439 "500 Internal Server Error": { 440 params: ListPoliciesRequest{}, 441 responseStatus: http.StatusInternalServerError, 442 responseBody: ` 443 { 444 "type": "internal_error", 445 "title": "Internal Server Error", 446 "status": 500, 447 "requestId": "1", 448 "requestTime": "12:00", 449 "clientIp": "1.1.1.1", 450 "serverIp": "2.2.2.2", 451 "method": "GET" 452 }`, 453 expectedPath: "/cloudlets/v3/policies", 454 withError: func(t *testing.T, err error) { 455 want := &Error{ 456 Type: "internal_error", 457 Title: "Internal Server Error", 458 Status: http.StatusInternalServerError, 459 RequestID: "1", 460 RequestTime: "12:00", 461 ClientIP: "1.1.1.1", 462 ServerIP: "2.2.2.2", 463 Method: "GET", 464 } 465 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 466 }, 467 }, 468 } 469 470 for name, test := range tests { 471 t.Run(name, func(t *testing.T) { 472 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 473 assert.Equal(t, test.expectedPath, r.URL.String()) 474 assert.Equal(t, http.MethodGet, r.Method) 475 w.WriteHeader(test.responseStatus) 476 _, err := w.Write([]byte(test.responseBody)) 477 assert.NoError(t, err) 478 })) 479 client := mockAPIClient(t, mockServer) 480 result, err := client.ListPolicies(context.Background(), test.params) 481 if test.withError != nil { 482 test.withError(t, err) 483 return 484 } 485 require.NoError(t, err) 486 assert.Equal(t, test.expectedResponse, result) 487 }) 488 } 489 } 490 491 func TestCreatePolicy(t *testing.T) { 492 tests := map[string]struct { 493 params CreatePolicyRequest 494 responseStatus int 495 responseBody string 496 expectedPath string 497 expectedRequestBody string 498 expectedResponse *Policy 499 withError func(*testing.T, error) 500 }{ 501 "200 OK - minimal data": { 502 params: CreatePolicyRequest{ 503 CloudletType: CloudletTypeFR, 504 GroupID: 1, 505 Name: "TestName", 506 }, 507 responseStatus: http.StatusCreated, 508 responseBody: ` 509 { 510 "cloudletType": "FR", 511 "createdBy": "User1", 512 "createdDate": "2023-10-23T11:21:19.896Z", 513 "currentActivations": { 514 "production": { 515 "effective": null, 516 "latest": null 517 }, 518 "staging": { 519 "effective": null, 520 "latest": null 521 } 522 }, 523 "description": null, 524 "groupId": 1, 525 "id": 11, 526 "links": [ 527 { 528 "href": "Link1", 529 "rel": "self" 530 } 531 ], 532 "modifiedBy": "User1", 533 "modifiedDate": "2023-10-23T11:21:19.896Z", 534 "name": "TestName", 535 "policyType": "SHARED" 536 } 537 `, 538 expectedPath: "/cloudlets/v3/policies", 539 expectedRequestBody: ` 540 { 541 "cloudletType": "FR", 542 "groupId": 1, 543 "name": "TestName" 544 }`, 545 expectedResponse: &Policy{ 546 CloudletType: CloudletTypeFR, 547 CreatedBy: "User1", 548 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 549 CurrentActivations: CurrentActivations{}, 550 Description: nil, 551 GroupID: 1, 552 ID: 11, 553 Links: []Link{ 554 { 555 Href: "Link1", 556 Rel: "self", 557 }, 558 }, 559 ModifiedBy: "User1", 560 ModifiedDate: newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 561 Name: "TestName", 562 PolicyType: PolicyTypeShared, 563 }, 564 }, 565 "200 OK - all data": { 566 params: CreatePolicyRequest{ 567 CloudletType: CloudletTypeFR, 568 Description: tools.StringPtr("Description"), 569 GroupID: 1, 570 Name: "TestName", 571 PolicyType: PolicyTypeShared, 572 }, 573 responseStatus: http.StatusCreated, 574 responseBody: ` 575 { 576 "cloudletType": "FR", 577 "createdBy": "User1", 578 "createdDate": "2023-10-23T11:21:19.896Z", 579 "currentActivations": { 580 "production": { 581 "effective": null, 582 "latest": null 583 }, 584 "staging": { 585 "effective": null, 586 "latest": null 587 } 588 }, 589 "description": "Description", 590 "groupId": 1, 591 "id": 11, 592 "links": [ 593 { 594 "href": "Link1", 595 "rel": "self" 596 } 597 ], 598 "modifiedBy": "User1", 599 "modifiedDate": "2023-10-23T11:21:19.896Z", 600 "name": "TestName", 601 "policyType": "SHARED" 602 } 603 `, 604 expectedPath: "/cloudlets/v3/policies", 605 expectedRequestBody: ` 606 { 607 "cloudletType": "FR", 608 "description": "Description", 609 "groupId": 1, 610 "name": "TestName", 611 "policyType": "SHARED" 612 } 613 `, 614 expectedResponse: &Policy{ 615 CloudletType: CloudletTypeFR, 616 CreatedBy: "User1", 617 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 618 CurrentActivations: CurrentActivations{}, 619 Description: tools.StringPtr("Description"), 620 GroupID: 1, 621 ID: 11, 622 Links: []Link{ 623 { 624 Href: "Link1", 625 Rel: "self", 626 }, 627 }, 628 ModifiedBy: "User1", 629 ModifiedDate: newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 630 Name: "TestName", 631 PolicyType: PolicyTypeShared, 632 }, 633 }, 634 "validation errors": { 635 params: CreatePolicyRequest{ 636 CloudletType: "Wrong Cloudlet Type", 637 Description: tools.StringPtr(strings.Repeat("Too long description", 20)), 638 GroupID: 1, 639 Name: "TestName not match", 640 PolicyType: "Wrong Policy Type", 641 }, 642 withError: func(t *testing.T, err error) { 643 assert.Equal(t, "create shared policy: struct validation: CloudletType: value 'Wrong Cloudlet Type' is invalid. Must be one of: 'AP', 'AS', 'CD', 'ER', 'FR', 'IG'\nDescription: the length must be no more than 255\nName: value 'TestName not match' is invalid. Must be of format: ^[a-z_A-Z0-9]+$\nPolicyType: value 'Wrong Policy Type' is invalid. Must be 'SHARED'", err.Error()) 644 }, 645 }, 646 "validation errors - missing required params": { 647 params: CreatePolicyRequest{}, 648 withError: func(t *testing.T, err error) { 649 assert.Equal(t, "create shared policy: struct validation: CloudletType: cannot be blank\nGroupID: cannot be blank\nName: cannot be blank", err.Error()) 650 }, 651 }, 652 } 653 654 for name, test := range tests { 655 t.Run(name, func(t *testing.T) { 656 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 657 assert.Equal(t, test.expectedPath, r.URL.String()) 658 assert.Equal(t, http.MethodPost, r.Method) 659 w.WriteHeader(test.responseStatus) 660 _, err := w.Write([]byte(test.responseBody)) 661 assert.NoError(t, err) 662 if test.expectedRequestBody != "" { 663 body, err := io.ReadAll(r.Body) 664 assert.NoError(t, err) 665 assert.JSONEq(t, test.expectedRequestBody, string(body)) 666 } 667 })) 668 client := mockAPIClient(t, mockServer) 669 result, err := client.CreatePolicy(context.Background(), test.params) 670 if test.withError != nil { 671 test.withError(t, err) 672 return 673 } 674 require.NoError(t, err) 675 assert.Equal(t, test.expectedResponse, result) 676 }) 677 } 678 } 679 680 func TestDeletePolicy(t *testing.T) { 681 tests := map[string]struct { 682 params DeletePolicyRequest 683 responseStatus int 684 responseBody string 685 expectedPath string 686 withError func(*testing.T, error) 687 }{ 688 "204": { 689 params: DeletePolicyRequest{ 690 PolicyID: 1, 691 }, 692 responseStatus: http.StatusNoContent, 693 expectedPath: "/cloudlets/v3/policies/1", 694 }, 695 "validation errors - missing required param": { 696 params: DeletePolicyRequest{}, 697 withError: func(t *testing.T, err error) { 698 assert.Equal(t, "delete shared policy: struct validation: PolicyID: cannot be blank", err.Error()) 699 }, 700 }, 701 } 702 703 for name, test := range tests { 704 t.Run(name, func(t *testing.T) { 705 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 706 assert.Equal(t, test.expectedPath, r.URL.String()) 707 assert.Equal(t, http.MethodDelete, r.Method) 708 w.WriteHeader(test.responseStatus) 709 _, err := w.Write([]byte(test.responseBody)) 710 assert.NoError(t, err) 711 })) 712 client := mockAPIClient(t, mockServer) 713 err := client.DeletePolicy(context.Background(), test.params) 714 if test.withError != nil { 715 test.withError(t, err) 716 return 717 } 718 require.NoError(t, err) 719 }) 720 } 721 } 722 723 func TestGetPolicy(t *testing.T) { 724 tests := map[string]struct { 725 params GetPolicyRequest 726 responseStatus int 727 responseBody string 728 expectedPath string 729 expectedResponse *Policy 730 withError func(*testing.T, error) 731 }{ 732 "200 OK - minimal data": { 733 params: GetPolicyRequest{ 734 PolicyID: 1, 735 }, 736 responseStatus: http.StatusOK, 737 responseBody: ` 738 739 { 740 "cloudletType": "FR", 741 "createdBy": "User1", 742 "createdDate": "2023-10-23T11:21:19.896Z", 743 "currentActivations": { 744 "production": { 745 "effective": null, 746 "latest": null 747 }, 748 "staging": { 749 "effective": null, 750 "latest": null 751 } 752 }, 753 "description": null, 754 "groupId": 1, 755 "id": 11, 756 "links": [ 757 { 758 "href": "Link1", 759 "rel": "self" 760 } 761 ], 762 "modifiedBy": "User1", 763 "modifiedDate": "2023-10-23T11:21:19.896Z", 764 "name": "TestName", 765 "policyType": "SHARED" 766 } 767 768 `, 769 770 expectedPath: "/cloudlets/v3/policies/1", 771 expectedResponse: &Policy{ 772 CloudletType: CloudletTypeFR, 773 CreatedBy: "User1", 774 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 775 CurrentActivations: CurrentActivations{}, 776 Description: nil, 777 GroupID: 1, 778 ID: 11, 779 Links: []Link{ 780 { 781 Href: "Link1", 782 Rel: "self", 783 }, 784 }, 785 ModifiedBy: "User1", 786 ModifiedDate: newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 787 Name: "TestName", 788 PolicyType: PolicyTypeShared, 789 }, 790 }, 791 "200 OK - with activation information": { 792 params: GetPolicyRequest{ 793 PolicyID: 1, 794 }, 795 responseStatus: http.StatusOK, 796 responseBody: ` 797 798 { 799 "cloudletType": "FR", 800 "createdBy": "User1", 801 "createdDate": "2023-10-23T11:21:19.896Z", 802 "currentActivations": { 803 "production": { 804 "effective": { 805 "createdBy": "User1", 806 "createdDate": "2023-10-23T11:21:19.896Z", 807 "finishDate": "2023-10-23T11:22:57.589Z", 808 "id": 123, 809 "links": [ 810 { 811 "href": "Link1", 812 "rel": "self" 813 } 814 ], 815 "network": "PRODUCTION", 816 "operation": "ACTIVATION", 817 "policyId": 1234, 818 "policyVersion": 1, 819 "policyVersionDeleted": false, 820 "status": "SUCCESS" 821 }, 822 "latest": { 823 "createdBy": "User1", 824 "createdDate": "2023-10-23T11:21:19.896Z", 825 "finishDate": "2023-10-23T11:22:57.589Z", 826 "id": 321, 827 "links": [ 828 { 829 "href": "Link2", 830 "rel": "self" 831 } 832 ], 833 "network": "PRODUCTION", 834 "operation": "ACTIVATION", 835 "policyId": 4321, 836 "policyVersion": 1, 837 "policyVersionDeleted": false, 838 "status": "SUCCESS" 839 } 840 }, 841 "staging": { 842 "effective": { 843 "createdBy": "User3", 844 "createdDate": "2023-10-23T11:21:19.896Z", 845 "finishDate": "2023-10-23T11:22:57.589Z", 846 "id": 789, 847 "links": [ 848 { 849 "href": "Link3", 850 "rel": "self" 851 } 852 ], 853 "network": "STAGING", 854 "operation": "ACTIVATION", 855 "policyId": 6789, 856 "policyVersion": 1, 857 "policyVersionDeleted": false, 858 "status": "SUCCESS" 859 }, 860 "latest": { 861 "createdBy": "User3", 862 "createdDate": "2023-10-23T11:21:19.896Z", 863 "finishDate": "2023-10-23T11:22:57.589Z", 864 "id": 987, 865 "links": [ 866 { 867 "href": "Link4", 868 "rel": "self" 869 } 870 ], 871 "network": "STAGING", 872 "operation": "ACTIVATION", 873 "policyId": 9876, 874 "policyVersion": 1, 875 "policyVersionDeleted": false, 876 "status": "SUCCESS" 877 } 878 } 879 }, 880 "description": "Description", 881 "groupId": 1, 882 "id": 11, 883 "links": [ 884 { 885 "href": "Link1", 886 "rel": "self" 887 } 888 ], 889 "modifiedBy": "User1", 890 "modifiedDate": "2023-10-23T11:21:19.896Z", 891 "name": "TestName", 892 "policyType": "SHARED" 893 } 894 895 `, 896 897 expectedPath: "/cloudlets/v3/policies/1", 898 expectedResponse: &Policy{ 899 CloudletType: CloudletTypeFR, 900 CreatedBy: "User1", 901 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 902 CurrentActivations: CurrentActivations{ 903 Production: ActivationInfo{ 904 Effective: &PolicyActivation{ 905 CreatedBy: "User1", 906 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 907 FinishDate: newTimeFromString(t, "2023-10-23T11:22:57.589Z"), 908 ID: 123, 909 Links: []Link{ 910 { 911 Href: "Link1", 912 Rel: "self", 913 }, 914 }, 915 Network: ProductionNetwork, 916 Operation: OperationActivation, 917 PolicyID: 1234, 918 PolicyVersion: 1, 919 PolicyVersionDeleted: false, 920 Status: ActivationStatusSuccess, 921 }, 922 Latest: &PolicyActivation{ 923 CreatedBy: "User1", 924 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 925 FinishDate: newTimeFromString(t, "2023-10-23T11:22:57.589Z"), 926 ID: 321, 927 Links: []Link{ 928 { 929 Href: "Link2", 930 Rel: "self", 931 }, 932 }, 933 Network: ProductionNetwork, 934 Operation: OperationActivation, 935 PolicyID: 4321, 936 PolicyVersion: 1, 937 PolicyVersionDeleted: false, 938 Status: ActivationStatusSuccess, 939 }, 940 }, 941 Staging: ActivationInfo{ 942 Effective: &PolicyActivation{ 943 CreatedBy: "User3", 944 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 945 FinishDate: newTimeFromString(t, "2023-10-23T11:22:57.589Z"), 946 ID: 789, 947 Links: []Link{ 948 { 949 Href: "Link3", 950 Rel: "self", 951 }, 952 }, 953 Network: StagingNetwork, 954 Operation: OperationActivation, 955 PolicyID: 6789, 956 PolicyVersion: 1, 957 PolicyVersionDeleted: false, 958 Status: ActivationStatusSuccess, 959 }, 960 Latest: &PolicyActivation{ 961 CreatedBy: "User3", 962 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 963 FinishDate: newTimeFromString(t, "2023-10-23T11:22:57.589Z"), 964 ID: 987, 965 Links: []Link{ 966 { 967 Href: "Link4", 968 Rel: "self", 969 }, 970 }, 971 Network: StagingNetwork, 972 Operation: OperationActivation, 973 PolicyID: 9876, 974 PolicyVersion: 1, 975 PolicyVersionDeleted: false, 976 Status: ActivationStatusSuccess, 977 }, 978 }, 979 }, 980 Description: tools.StringPtr("Description"), 981 GroupID: 1, 982 ID: 11, 983 Links: []Link{ 984 { 985 Href: "Link1", 986 Rel: "self", 987 }, 988 }, 989 ModifiedBy: "User1", 990 ModifiedDate: newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 991 Name: "TestName", 992 PolicyType: PolicyTypeShared, 993 }, 994 }, 995 "200 OK - one network is active": { 996 params: GetPolicyRequest{ 997 PolicyID: 1, 998 }, 999 responseStatus: http.StatusOK, 1000 responseBody: ` 1001 1002 { 1003 "cloudletType": "FR", 1004 "createdBy": "User1", 1005 "createdDate": "2023-10-23T11:21:19.896Z", 1006 "currentActivations": { 1007 "production": { 1008 "effective": null, 1009 "latest": null 1010 }, 1011 "staging": { 1012 "effective": { 1013 "createdBy": "User3", 1014 "createdDate": "2023-10-23T11:21:19.896Z", 1015 "finishDate": "2023-10-23T11:22:57.589Z", 1016 "id": 789, 1017 "links": [ 1018 { 1019 "href": "Link3", 1020 "rel": "self" 1021 } 1022 ], 1023 "network": "STAGING", 1024 "operation": "ACTIVATION", 1025 "policyId": 6789, 1026 "policyVersion": 1, 1027 "policyVersionDeleted": false, 1028 "status": "SUCCESS" 1029 }, 1030 "latest": { 1031 "createdBy": "User3", 1032 "createdDate": "2023-10-23T11:21:19.896Z", 1033 "finishDate": "2023-10-23T11:22:57.589Z", 1034 "id": 987, 1035 "links": [ 1036 { 1037 "href": "Link4", 1038 "rel": "self" 1039 } 1040 ], 1041 "network": "STAGING", 1042 "operation": "ACTIVATION", 1043 "policyId": 9876, 1044 "policyVersion": 1, 1045 "policyVersionDeleted": false, 1046 "status": "SUCCESS" 1047 } 1048 } 1049 }, 1050 "description": "Description", 1051 "groupId": 1, 1052 "id": 11, 1053 "links": [ 1054 { 1055 "href": "Link1", 1056 "rel": "self" 1057 } 1058 ], 1059 "modifiedBy": "User1", 1060 "modifiedDate": "2023-10-23T11:21:19.896Z", 1061 "name": "TestName", 1062 "policyType": "SHARED" 1063 } 1064 1065 `, 1066 1067 expectedPath: "/cloudlets/v3/policies/1", 1068 expectedResponse: &Policy{ 1069 CloudletType: CloudletTypeFR, 1070 CreatedBy: "User1", 1071 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 1072 CurrentActivations: CurrentActivations{ 1073 Production: ActivationInfo{ 1074 Effective: nil, 1075 Latest: nil, 1076 }, 1077 Staging: ActivationInfo{ 1078 Effective: &PolicyActivation{ 1079 CreatedBy: "User3", 1080 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 1081 FinishDate: newTimeFromString(t, "2023-10-23T11:22:57.589Z"), 1082 ID: 789, 1083 Links: []Link{ 1084 { 1085 Href: "Link3", 1086 Rel: "self", 1087 }, 1088 }, 1089 Network: StagingNetwork, 1090 Operation: OperationActivation, 1091 PolicyID: 6789, 1092 PolicyVersion: 1, 1093 PolicyVersionDeleted: false, 1094 Status: ActivationStatusSuccess, 1095 }, 1096 Latest: &PolicyActivation{ 1097 CreatedBy: "User3", 1098 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 1099 FinishDate: newTimeFromString(t, "2023-10-23T11:22:57.589Z"), 1100 ID: 987, 1101 Links: []Link{ 1102 { 1103 Href: "Link4", 1104 Rel: "self", 1105 }, 1106 }, 1107 Network: StagingNetwork, 1108 Operation: OperationActivation, 1109 PolicyID: 9876, 1110 PolicyVersion: 1, 1111 PolicyVersionDeleted: false, 1112 Status: ActivationStatusSuccess, 1113 }, 1114 }, 1115 }, 1116 Description: tools.StringPtr("Description"), 1117 GroupID: 1, 1118 ID: 11, 1119 Links: []Link{ 1120 { 1121 Href: "Link1", 1122 Rel: "self", 1123 }, 1124 }, 1125 ModifiedBy: "User1", 1126 ModifiedDate: newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 1127 Name: "TestName", 1128 PolicyType: PolicyTypeShared, 1129 }, 1130 }, 1131 "validation errors - missing required params": { 1132 params: GetPolicyRequest{}, 1133 withError: func(t *testing.T, err error) { 1134 assert.Equal(t, "get shared policy: struct validation: PolicyID: cannot be blank", err.Error()) 1135 }, 1136 }, 1137 } 1138 1139 for name, test := range tests { 1140 t.Run(name, func(t *testing.T) { 1141 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 1142 assert.Equal(t, test.expectedPath, r.URL.String()) 1143 assert.Equal(t, http.MethodGet, r.Method) 1144 w.WriteHeader(test.responseStatus) 1145 _, err := w.Write([]byte(test.responseBody)) 1146 assert.NoError(t, err) 1147 })) 1148 client := mockAPIClient(t, mockServer) 1149 result, err := client.GetPolicy(context.Background(), test.params) 1150 if test.withError != nil { 1151 test.withError(t, err) 1152 return 1153 } 1154 require.NoError(t, err) 1155 assert.Equal(t, test.expectedResponse, result) 1156 }) 1157 } 1158 } 1159 1160 func TestUpdatePolicy(t *testing.T) { 1161 tests := map[string]struct { 1162 params UpdatePolicyRequest 1163 responseStatus int 1164 responseBody string 1165 expectedPath string 1166 expectedRequestBody string 1167 expectedResponse *Policy 1168 withError func(*testing.T, error) 1169 }{ 1170 "200 OK - minimal data": { 1171 params: UpdatePolicyRequest{ 1172 PolicyID: 1, 1173 BodyParams: UpdatePolicyBodyParams{ 1174 GroupID: 11, 1175 }, 1176 }, 1177 responseStatus: http.StatusOK, 1178 responseBody: ` 1179 { 1180 "cloudletType": "FR", 1181 "createdBy": "User1", 1182 "createdDate": "2023-10-23T11:21:19.896Z", 1183 "currentActivations": { 1184 "production": { 1185 "effective": null, 1186 "latest": null 1187 }, 1188 "staging": { 1189 "effective": null, 1190 "latest": null 1191 } 1192 }, 1193 "description": null, 1194 "groupId": 1, 1195 "id": 11, 1196 "links": [ 1197 { 1198 "href": "Link1", 1199 "rel": "self" 1200 } 1201 ], 1202 "modifiedBy": "User1", 1203 "modifiedDate": "2023-10-23T11:21:19.896Z", 1204 "name": "TestName", 1205 "policyType": "SHARED" 1206 } 1207 `, 1208 expectedPath: "/cloudlets/v3/policies/1", 1209 expectedRequestBody: ` 1210 { 1211 "groupId": 11 1212 } 1213 `, 1214 expectedResponse: &Policy{ 1215 CloudletType: CloudletTypeFR, 1216 CreatedBy: "User1", 1217 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 1218 CurrentActivations: CurrentActivations{}, 1219 Description: nil, 1220 GroupID: 1, 1221 ID: 11, 1222 Links: []Link{ 1223 { 1224 Href: "Link1", 1225 Rel: "self", 1226 }, 1227 }, 1228 ModifiedBy: "User1", 1229 ModifiedDate: newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 1230 Name: "TestName", 1231 PolicyType: PolicyTypeShared, 1232 }, 1233 }, 1234 "200 OK - with description and activations": { 1235 params: UpdatePolicyRequest{ 1236 PolicyID: 1, 1237 BodyParams: UpdatePolicyBodyParams{ 1238 GroupID: 11, 1239 Description: tools.StringPtr("Description"), 1240 }, 1241 }, 1242 responseStatus: http.StatusOK, 1243 responseBody: ` 1244 { 1245 "cloudletType": "FR", 1246 "createdBy": "User1", 1247 "createdDate": "2023-10-23T11:21:19.896Z", 1248 "currentActivations": { 1249 "production": { 1250 "effective": { 1251 "createdBy": "User1", 1252 "createdDate": "2023-10-23T11:21:19.896Z", 1253 "finishDate": "2023-10-23T11:22:57.589Z", 1254 "id": 123, 1255 "links": [ 1256 { 1257 "href": "Link1", 1258 "rel": "self" 1259 } 1260 ], 1261 "network": "PRODUCTION", 1262 "operation": "ACTIVATION", 1263 "policyId": 1234, 1264 "policyVersion": 1, 1265 "policyVersionDeleted": false, 1266 "status": "SUCCESS" 1267 }, 1268 "latest": { 1269 "createdBy": "User1", 1270 "createdDate": "2023-10-23T11:21:19.896Z", 1271 "finishDate": "2023-10-23T11:22:57.589Z", 1272 "id": 321, 1273 "links": [ 1274 { 1275 "href": "Link2", 1276 "rel": "self" 1277 } 1278 ], 1279 "network": "PRODUCTION", 1280 "operation": "ACTIVATION", 1281 "policyId": 4321, 1282 "policyVersion": 1, 1283 "policyVersionDeleted": false, 1284 "status": "SUCCESS" 1285 } 1286 }, 1287 "staging": { 1288 "effective": { 1289 "createdBy": "User3", 1290 "createdDate": "2023-10-23T11:21:19.896Z", 1291 "finishDate": "2023-10-23T11:22:57.589Z", 1292 "id": 789, 1293 "links": [ 1294 { 1295 "href": "Link3", 1296 "rel": "self" 1297 } 1298 ], 1299 "network": "STAGING", 1300 "operation": "ACTIVATION", 1301 "policyId": 6789, 1302 "policyVersion": 1, 1303 "policyVersionDeleted": false, 1304 "status": "SUCCESS" 1305 }, 1306 "latest": { 1307 "createdBy": "User3", 1308 "createdDate": "2023-10-23T11:21:19.896Z", 1309 "finishDate": "2023-10-23T11:22:57.589Z", 1310 "id": 987, 1311 "links": [ 1312 { 1313 "href": "Link4", 1314 "rel": "self" 1315 } 1316 ], 1317 "network": "STAGING", 1318 "operation": "ACTIVATION", 1319 "policyId": 9876, 1320 "policyVersion": 1, 1321 "policyVersionDeleted": false, 1322 "status": "SUCCESS" 1323 } 1324 } 1325 }, 1326 "description": "Description", 1327 "groupId": 1, 1328 "id": 11, 1329 "links": [ 1330 { 1331 "href": "Link1", 1332 "rel": "self" 1333 } 1334 ], 1335 "modifiedBy": "User1", 1336 "modifiedDate": "2023-10-23T11:21:19.896Z", 1337 "name": "TestName", 1338 "policyType": "SHARED" 1339 } 1340 `, 1341 expectedPath: "/cloudlets/v3/policies/1", 1342 expectedRequestBody: ` 1343 { 1344 "groupId": 11, 1345 "description": "Description" 1346 } 1347 `, 1348 expectedResponse: &Policy{ 1349 CloudletType: CloudletTypeFR, 1350 CreatedBy: "User1", 1351 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 1352 CurrentActivations: CurrentActivations{ 1353 Production: ActivationInfo{ 1354 Effective: &PolicyActivation{ 1355 CreatedBy: "User1", 1356 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 1357 FinishDate: newTimeFromString(t, "2023-10-23T11:22:57.589Z"), 1358 ID: 123, 1359 Links: []Link{ 1360 { 1361 Href: "Link1", 1362 Rel: "self", 1363 }, 1364 }, 1365 Network: ProductionNetwork, 1366 Operation: OperationActivation, 1367 PolicyID: 1234, 1368 PolicyVersion: 1, 1369 PolicyVersionDeleted: false, 1370 Status: ActivationStatusSuccess, 1371 }, 1372 Latest: &PolicyActivation{ 1373 CreatedBy: "User1", 1374 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 1375 FinishDate: newTimeFromString(t, "2023-10-23T11:22:57.589Z"), 1376 ID: 321, 1377 Links: []Link{ 1378 { 1379 Href: "Link2", 1380 Rel: "self", 1381 }, 1382 }, 1383 Network: ProductionNetwork, 1384 Operation: OperationActivation, 1385 PolicyID: 4321, 1386 PolicyVersion: 1, 1387 PolicyVersionDeleted: false, 1388 Status: ActivationStatusSuccess, 1389 }, 1390 }, 1391 Staging: ActivationInfo{ 1392 Effective: &PolicyActivation{ 1393 CreatedBy: "User3", 1394 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 1395 FinishDate: newTimeFromString(t, "2023-10-23T11:22:57.589Z"), 1396 ID: 789, 1397 Links: []Link{ 1398 { 1399 Href: "Link3", 1400 Rel: "self", 1401 }, 1402 }, 1403 Network: StagingNetwork, 1404 Operation: OperationActivation, 1405 PolicyID: 6789, 1406 PolicyVersion: 1, 1407 PolicyVersionDeleted: false, 1408 Status: ActivationStatusSuccess, 1409 }, 1410 Latest: &PolicyActivation{ 1411 CreatedBy: "User3", 1412 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 1413 FinishDate: newTimeFromString(t, "2023-10-23T11:22:57.589Z"), 1414 ID: 987, 1415 Links: []Link{ 1416 { 1417 Href: "Link4", 1418 Rel: "self", 1419 }, 1420 }, 1421 Network: StagingNetwork, 1422 Operation: OperationActivation, 1423 PolicyID: 9876, 1424 PolicyVersion: 1, 1425 PolicyVersionDeleted: false, 1426 Status: ActivationStatusSuccess, 1427 }, 1428 }, 1429 }, 1430 Description: tools.StringPtr("Description"), 1431 GroupID: 1, 1432 ID: 11, 1433 Links: []Link{ 1434 { 1435 Href: "Link1", 1436 Rel: "self", 1437 }, 1438 }, 1439 ModifiedBy: "User1", 1440 ModifiedDate: newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 1441 Name: "TestName", 1442 PolicyType: PolicyTypeShared, 1443 }, 1444 }, 1445 "validation errors - missing required params": { 1446 params: UpdatePolicyRequest{}, 1447 withError: func(t *testing.T, err error) { 1448 assert.Equal(t, "update shared policy: struct validation: GroupID: cannot be blank\nPolicyID: cannot be blank", err.Error()) 1449 }, 1450 }, 1451 "validation errors - description too long": { 1452 params: UpdatePolicyRequest{ 1453 PolicyID: 1, 1454 BodyParams: UpdatePolicyBodyParams{ 1455 GroupID: 11, 1456 Description: tools.StringPtr(strings.Repeat("TestDescription", 30)), 1457 }, 1458 }, 1459 withError: func(t *testing.T, err error) { 1460 assert.Equal(t, "update shared policy: struct validation: Description: the length must be no more than 255", err.Error()) 1461 }, 1462 }, 1463 } 1464 1465 for name, test := range tests { 1466 t.Run(name, func(t *testing.T) { 1467 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 1468 assert.Equal(t, test.expectedPath, r.URL.String()) 1469 assert.Equal(t, http.MethodPut, r.Method) 1470 if test.expectedRequestBody != "" { 1471 body, err := io.ReadAll(r.Body) 1472 require.NoError(t, err) 1473 assert.JSONEq(t, test.expectedRequestBody, string(body)) 1474 } 1475 w.WriteHeader(test.responseStatus) 1476 _, err := w.Write([]byte(test.responseBody)) 1477 assert.NoError(t, err) 1478 })) 1479 client := mockAPIClient(t, mockServer) 1480 result, err := client.UpdatePolicy(context.Background(), test.params) 1481 if test.withError != nil { 1482 test.withError(t, err) 1483 return 1484 } 1485 require.NoError(t, err) 1486 assert.Equal(t, test.expectedResponse, result) 1487 }) 1488 } 1489 } 1490 1491 func TestClonePolicy(t *testing.T) { 1492 tests := map[string]struct { 1493 params ClonePolicyRequest 1494 responseStatus int 1495 responseBody string 1496 expectedPath string 1497 expectedRequestBody string 1498 expectedResponse *Policy 1499 withError func(*testing.T, error) 1500 }{ 1501 "200 OK - minimal data": { 1502 params: ClonePolicyRequest{ 1503 PolicyID: 1, 1504 BodyParams: ClonePolicyBodyParams{ 1505 NewName: "NewName", 1506 }, 1507 }, 1508 responseStatus: http.StatusOK, 1509 responseBody: ` 1510 { 1511 "cloudletType": "FR", 1512 "createdBy": "User1", 1513 "createdDate": "2023-10-23T11:21:19.896Z", 1514 "currentActivations": { 1515 "production": { 1516 "effective": null, 1517 "latest": null 1518 }, 1519 "staging": { 1520 "effective": null, 1521 "latest": null 1522 } 1523 }, 1524 "description": null, 1525 "groupId": 1, 1526 "id": 11, 1527 "links": [ 1528 { 1529 "href": "Link1", 1530 "rel": "self" 1531 } 1532 ], 1533 "modifiedBy": "User1", 1534 "modifiedDate": "2023-10-23T11:21:19.896Z", 1535 "name": "NewName", 1536 "policyType": "SHARED" 1537 } 1538 `, 1539 expectedPath: "/cloudlets/v3/policies/1/clone", 1540 expectedRequestBody: ` 1541 { 1542 "newName": "NewName" 1543 } 1544 `, 1545 expectedResponse: &Policy{ 1546 CloudletType: "FR", 1547 CreatedBy: "User1", 1548 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 1549 CurrentActivations: CurrentActivations{}, 1550 Description: nil, 1551 GroupID: 1, 1552 ID: 11, 1553 Links: []Link{ 1554 { 1555 Href: "Link1", 1556 Rel: "self", 1557 }, 1558 }, 1559 ModifiedBy: "User1", 1560 ModifiedDate: newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 1561 Name: "NewName", 1562 PolicyType: PolicyTypeShared, 1563 }, 1564 }, 1565 "200 OK - all data": { 1566 params: ClonePolicyRequest{ 1567 PolicyID: 1, 1568 BodyParams: ClonePolicyBodyParams{ 1569 AdditionalVersions: []int64{1, 2}, 1570 GroupID: 11, 1571 NewName: "NewName", 1572 }, 1573 }, 1574 responseStatus: http.StatusOK, 1575 responseBody: ` 1576 { 1577 "cloudletType": "FR", 1578 "createdBy": "User1", 1579 "createdDate": "2023-10-23T11:21:19.896Z", 1580 "currentActivations": { 1581 "production": { 1582 "effective": { 1583 "createdBy": "User1", 1584 "createdDate": "2023-10-23T11:21:19.896Z", 1585 "finishDate": "2023-10-23T11:22:57.589Z", 1586 "id": 123, 1587 "links": [ 1588 { 1589 "href": "Link1", 1590 "rel": "self" 1591 } 1592 ], 1593 "network": "PRODUCTION", 1594 "operation": "ACTIVATION", 1595 "policyId": 1234, 1596 "policyVersion": 1, 1597 "policyVersionDeleted": false, 1598 "status": "SUCCESS" 1599 }, 1600 "latest": { 1601 "createdBy": "User1", 1602 "createdDate": "2023-10-23T11:21:19.896Z", 1603 "finishDate": "2023-10-23T11:22:57.589Z", 1604 "id": 321, 1605 "links": [ 1606 { 1607 "href": "Link2", 1608 "rel": "self" 1609 } 1610 ], 1611 "network": "PRODUCTION", 1612 "operation": "ACTIVATION", 1613 "policyId": 4321, 1614 "policyVersion": 1, 1615 "policyVersionDeleted": false, 1616 "status": "SUCCESS" 1617 } 1618 }, 1619 "staging": { 1620 "effective": { 1621 "createdBy": "User3", 1622 "createdDate": "2023-10-23T11:21:19.896Z", 1623 "finishDate": "2023-10-23T11:22:57.589Z", 1624 "id": 789, 1625 "links": [ 1626 { 1627 "href": "Link3", 1628 "rel": "self" 1629 } 1630 ], 1631 "network": "STAGING", 1632 "operation": "ACTIVATION", 1633 "policyId": 6789, 1634 "policyVersion": 1, 1635 "policyVersionDeleted": false, 1636 "status": "SUCCESS" 1637 }, 1638 "latest": { 1639 "createdBy": "User3", 1640 "createdDate": "2023-10-23T11:21:19.896Z", 1641 "finishDate": "2023-10-23T11:22:57.589Z", 1642 "id": 987, 1643 "links": [ 1644 { 1645 "href": "Link4", 1646 "rel": "self" 1647 } 1648 ], 1649 "network": "STAGING", 1650 "operation": "ACTIVATION", 1651 "policyId": 9876, 1652 "policyVersion": 1, 1653 "policyVersionDeleted": false, 1654 "status": "SUCCESS" 1655 } 1656 } 1657 }, 1658 "description": "Description", 1659 "groupId": 1, 1660 "id": 11, 1661 "links": [ 1662 { 1663 "href": "Link1", 1664 "rel": "self" 1665 } 1666 ], 1667 "modifiedBy": "User1", 1668 "modifiedDate": "2023-10-23T11:21:19.896Z", 1669 "name": "NewName", 1670 "policyType": "SHARED" 1671 } 1672 `, 1673 expectedPath: "/cloudlets/v3/policies/1/clone", 1674 expectedRequestBody: ` 1675 { 1676 "additionalVersions": [1, 2], 1677 "groupId": 11, 1678 "newName": "NewName" 1679 } 1680 `, 1681 expectedResponse: &Policy{ 1682 CloudletType: "FR", 1683 CreatedBy: "User1", 1684 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 1685 CurrentActivations: CurrentActivations{ 1686 Production: ActivationInfo{ 1687 Effective: &PolicyActivation{ 1688 CreatedBy: "User1", 1689 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 1690 FinishDate: newTimeFromString(t, "2023-10-23T11:22:57.589Z"), 1691 ID: 123, 1692 Links: []Link{ 1693 { 1694 Href: "Link1", 1695 Rel: "self", 1696 }, 1697 }, 1698 Network: ProductionNetwork, 1699 Operation: OperationActivation, 1700 PolicyID: 1234, 1701 PolicyVersion: 1, 1702 PolicyVersionDeleted: false, 1703 Status: ActivationStatusSuccess, 1704 }, 1705 Latest: &PolicyActivation{ 1706 CreatedBy: "User1", 1707 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 1708 FinishDate: newTimeFromString(t, "2023-10-23T11:22:57.589Z"), 1709 ID: 321, 1710 Links: []Link{ 1711 { 1712 Href: "Link2", 1713 Rel: "self", 1714 }, 1715 }, 1716 Network: ProductionNetwork, 1717 Operation: OperationActivation, 1718 PolicyID: 4321, 1719 PolicyVersion: 1, 1720 PolicyVersionDeleted: false, 1721 Status: ActivationStatusSuccess, 1722 }, 1723 }, 1724 Staging: ActivationInfo{ 1725 Effective: &PolicyActivation{ 1726 CreatedBy: "User3", 1727 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 1728 FinishDate: newTimeFromString(t, "2023-10-23T11:22:57.589Z"), 1729 ID: 789, 1730 Links: []Link{ 1731 { 1732 Href: "Link3", 1733 Rel: "self", 1734 }, 1735 }, 1736 Network: StagingNetwork, 1737 Operation: OperationActivation, 1738 PolicyID: 6789, 1739 PolicyVersion: 1, 1740 PolicyVersionDeleted: false, 1741 Status: ActivationStatusSuccess, 1742 }, 1743 Latest: &PolicyActivation{ 1744 CreatedBy: "User3", 1745 CreatedDate: *newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 1746 FinishDate: newTimeFromString(t, "2023-10-23T11:22:57.589Z"), 1747 ID: 987, 1748 Links: []Link{ 1749 { 1750 Href: "Link4", 1751 Rel: "self", 1752 }, 1753 }, 1754 Network: StagingNetwork, 1755 Operation: OperationActivation, 1756 PolicyID: 9876, 1757 PolicyVersion: 1, 1758 PolicyVersionDeleted: false, 1759 Status: ActivationStatusSuccess, 1760 }, 1761 }, 1762 }, 1763 Description: tools.StringPtr("Description"), 1764 GroupID: 1, 1765 ID: 11, 1766 Links: []Link{ 1767 { 1768 Href: "Link1", 1769 Rel: "self", 1770 }, 1771 }, 1772 ModifiedBy: "User1", 1773 ModifiedDate: newTimeFromString(t, "2023-10-23T11:21:19.896Z"), 1774 Name: "NewName", 1775 PolicyType: PolicyTypeShared, 1776 }, 1777 }, 1778 "validation errors - missing required params": { 1779 params: ClonePolicyRequest{}, 1780 withError: func(t *testing.T, err error) { 1781 assert.Equal(t, "clone policy: struct validation: NewName: cannot be blank\nPolicyID: cannot be blank", err.Error()) 1782 }, 1783 }, 1784 "validation errors - newName too long": { 1785 params: ClonePolicyRequest{ 1786 PolicyID: 1, 1787 BodyParams: ClonePolicyBodyParams{ 1788 GroupID: 11, 1789 NewName: strings.Repeat("TestNameTooLong", 10), 1790 }, 1791 }, 1792 withError: func(t *testing.T, err error) { 1793 assert.Equal(t, "clone policy: struct validation: NewName: the length must be no more than 64", err.Error()) 1794 }, 1795 }, 1796 } 1797 1798 for name, test := range tests { 1799 t.Run(name, func(t *testing.T) { 1800 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 1801 assert.Equal(t, test.expectedPath, r.URL.String()) 1802 assert.Equal(t, http.MethodPost, r.Method) 1803 1804 if test.expectedRequestBody != "" { 1805 body, err := io.ReadAll(r.Body) 1806 require.NoError(t, err) 1807 assert.JSONEq(t, test.expectedRequestBody, string(body)) 1808 } 1809 w.WriteHeader(test.responseStatus) 1810 _, err := w.Write([]byte(test.responseBody)) 1811 assert.NoError(t, err) 1812 })) 1813 client := mockAPIClient(t, mockServer) 1814 result, err := client.ClonePolicy(context.Background(), test.params) 1815 if test.withError != nil { 1816 test.withError(t, err) 1817 return 1818 } 1819 require.NoError(t, err) 1820 assert.Equal(t, test.expectedResponse, result) 1821 }) 1822 } 1823 }