github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/cloudlets/v3/policy_version_test.go (about) 1 package v3 2 3 import ( 4 "bytes" 5 "context" 6 "errors" 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/require" 14 "github.com/tj/assert" 15 ) 16 17 func TestListPolicyVersions(t *testing.T) { 18 t.Parallel() 19 tests := map[string]struct { 20 request ListPolicyVersionsRequest 21 responseStatus int 22 responseBody string 23 expectedPath string 24 expectedResponse *ListPolicyVersions 25 withError func(*testing.T, error) 26 }{ 27 "200 OK": { 28 request: ListPolicyVersionsRequest{ 29 PolicyID: 670790, 30 }, 31 responseStatus: http.StatusOK, 32 responseBody: ` 33 { 34 "content": [ 35 { 36 "createdBy": "jsmith", 37 "createdDate": "2023-10-19T08:50:47.350Z", 38 "description": null, 39 "id": 6551184, 40 "immutable": false, 41 "links": [], 42 "modifiedBy": "jsmith", 43 "modifiedDate": "2023-10-19T08:50:47.350Z", 44 "policyId": 670790, 45 "version": 3 46 }, 47 { 48 "createdBy": "jsmith", 49 "createdDate": "2023-10-19T08:50:46.225Z", 50 "description": null, 51 "id": 6551183, 52 "immutable": false, 53 "links": [], 54 "modifiedBy": "jsmith", 55 "modifiedDate": "2023-10-19T08:50:46.225Z", 56 "policyId": 670790, 57 "version": 2 58 }, 59 { 60 "createdBy": "jsmith", 61 "createdDate": "2023-10-19T08:44:34.398Z", 62 "description": null, 63 "id": 6551182, 64 "immutable": false, 65 "links": [], 66 "modifiedBy": "jsmith", 67 "modifiedDate": "2023-10-19T08:44:34.398Z", 68 "policyId": 670790, 69 "version": 1 70 } 71 ], 72 "links": [ 73 { 74 "href": "/cloudlets/v3/policies/670790/versions?page=0&size=1000", 75 "rel": "self" 76 } 77 ], 78 "page": { 79 "number": 0, 80 "size": 1000, 81 "totalElements": 3, 82 "totalPages": 1 83 } 84 }`, 85 expectedPath: "/cloudlets/v3/policies/670790/versions?page=0", 86 expectedResponse: &ListPolicyVersions{ 87 PolicyVersions: []ListPolicyVersionsItem{ 88 { 89 CreatedBy: "jsmith", 90 CreatedDate: *newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 91 Description: nil, 92 ID: 6551184, 93 Immutable: false, 94 Links: []Link{}, 95 ModifiedBy: "jsmith", 96 ModifiedDate: newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 97 PolicyID: 670790, 98 PolicyVersion: 3, 99 }, 100 { 101 CreatedBy: "jsmith", 102 CreatedDate: *newTimeFromString(t, "2023-10-19T08:50:46.225Z"), 103 Description: nil, 104 ID: 6551183, 105 Immutable: false, 106 Links: []Link{}, 107 ModifiedBy: "jsmith", 108 ModifiedDate: newTimeFromString(t, "2023-10-19T08:50:46.225Z"), 109 PolicyID: 670790, 110 PolicyVersion: 2, 111 }, 112 { 113 CreatedBy: "jsmith", 114 CreatedDate: *newTimeFromString(t, "2023-10-19T08:44:34.398Z"), 115 Description: nil, 116 ID: 6551182, 117 Immutable: false, 118 Links: []Link{}, 119 ModifiedBy: "jsmith", 120 ModifiedDate: newTimeFromString(t, "2023-10-19T08:44:34.398Z"), 121 PolicyID: 670790, 122 PolicyVersion: 1, 123 }, 124 }, 125 Links: []Link{ 126 { 127 Href: "/cloudlets/v3/policies/670790/versions?page=0&size=1000", 128 Rel: "self", 129 }, 130 }, 131 Page: Page{ 132 Number: 0, 133 Size: 1000, 134 TotalElements: 3, 135 TotalPages: 1, 136 }, 137 }, 138 }, 139 "200 OK with params": { 140 request: ListPolicyVersionsRequest{ 141 PolicyID: 670790, 142 Page: 4, 143 Size: 10, 144 }, 145 responseStatus: http.StatusOK, 146 responseBody: ` 147 { 148 "content": [], 149 "links": [ 150 { 151 "href": "/cloudlets/v3/policies/670790/versions?page=0&size=10", 152 "rel": "first" 153 }, 154 { 155 "href": "/cloudlets/v3/policies/670790/versions?page=3&size=10", 156 "rel": "prev" 157 }, 158 { 159 "href": "/cloudlets/v3/policies/670790/versions?page=4&size=10", 160 "rel": "self" 161 }, 162 { 163 "href": "/cloudlets/v3/policies/670790/versions?page=0&size=10", 164 "rel": "last" 165 } 166 ], 167 "page": { 168 "number": 4, 169 "size": 10, 170 "totalElements": 3, 171 "totalPages": 1 172 } 173 }`, 174 expectedPath: "/cloudlets/v3/policies/670790/versions?page=4&size=10", 175 expectedResponse: &ListPolicyVersions{ 176 PolicyVersions: []ListPolicyVersionsItem{}, 177 Links: []Link{ 178 { 179 Href: "/cloudlets/v3/policies/670790/versions?page=0&size=10", 180 Rel: "first", 181 }, 182 { 183 Href: "/cloudlets/v3/policies/670790/versions?page=3&size=10", 184 Rel: "prev", 185 }, 186 { 187 Href: "/cloudlets/v3/policies/670790/versions?page=4&size=10", 188 Rel: "self", 189 }, 190 { 191 Href: "/cloudlets/v3/policies/670790/versions?page=0&size=10", 192 Rel: "last", 193 }, 194 }, 195 Page: Page{ 196 Number: 4, 197 Size: 10, 198 TotalElements: 3, 199 TotalPages: 1, 200 }, 201 }, 202 }, 203 "500 internal server error": { 204 request: ListPolicyVersionsRequest{ 205 PolicyID: 284823, 206 }, 207 responseStatus: http.StatusInternalServerError, 208 responseBody: ` 209 { 210 "type": "internal_error", 211 "title": "Internal Server Error", 212 "status": 500 213 }`, 214 expectedPath: "/cloudlets/v3/policies/284823/versions?page=0", 215 withError: func(t *testing.T, err error) { 216 want := &Error{ 217 Type: "internal_error", 218 Title: "Internal Server Error", 219 Status: http.StatusInternalServerError, 220 } 221 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 222 }, 223 }, 224 } 225 226 for name, test := range tests { 227 name, test := name, test 228 t.Run(name, func(t *testing.T) { 229 t.Parallel() 230 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 231 assert.Equal(t, test.expectedPath, r.URL.String()) 232 assert.Equal(t, http.MethodGet, r.Method) 233 w.WriteHeader(test.responseStatus) 234 _, err := w.Write([]byte(test.responseBody)) 235 assert.NoError(t, err) 236 })) 237 client := mockAPIClient(t, mockServer) 238 result, err := client.ListPolicyVersions(context.Background(), test.request) 239 if test.withError != nil { 240 test.withError(t, err) 241 return 242 } 243 require.NoError(t, err) 244 assert.Equal(t, test.expectedResponse, result) 245 }) 246 } 247 } 248 249 func TestGetPolicyVersion(t *testing.T) { 250 t.Parallel() 251 tests := map[string]struct { 252 request GetPolicyVersionRequest 253 responseStatus int 254 responseBody string 255 expectedPath string 256 expectedResponse *PolicyVersion 257 withError func(*testing.T, error) 258 }{ 259 "200 OK": { 260 request: GetPolicyVersionRequest{ 261 PolicyID: 670798, 262 PolicyVersion: 2, 263 }, 264 responseStatus: http.StatusOK, 265 responseBody: ` 266 { 267 "createdBy": "jsmith", 268 "createdDate": "2023-10-19T09:46:57.395Z", 269 "description": "test description", 270 "id": 6551191, 271 "immutable": false, 272 "matchRules": [], 273 "matchRulesWarnings": [], 274 "modifiedBy": "jsmith", 275 "modifiedDate": "2023-10-19T09:46:57.395Z", 276 "policyId": 670798, 277 "version": 2 278 }`, 279 expectedPath: "/cloudlets/v3/policies/670798/versions/2", 280 expectedResponse: &PolicyVersion{ 281 CreatedBy: "jsmith", 282 CreatedDate: *newTimeFromString(t, "2023-10-19T09:46:57.395Z"), 283 Description: tools.StringPtr("test description"), 284 ID: 6551191, 285 MatchRules: nil, 286 MatchRulesWarnings: []MatchRulesWarning{}, 287 ModifiedBy: "jsmith", 288 ModifiedDate: newTimeFromString(t, "2023-10-19T09:46:57.395Z"), 289 PolicyID: 670798, 290 PolicyVersion: 2, 291 }, 292 }, 293 "200 OK, ER with disabled rule": { 294 request: GetPolicyVersionRequest{ 295 PolicyID: 276858, 296 PolicyVersion: 1, 297 }, 298 responseStatus: http.StatusOK, 299 responseBody: `{ 300 "createdBy": "jsmith", 301 "createdDate": "2023-10-19T10:45:30.619Z", 302 "description": null, 303 "id": 6551242, 304 "immutable": false, 305 "matchRules": [ 306 { 307 "type": "erMatchRule", 308 "id": 0, 309 "name": "er_rule", 310 "start": 0, 311 "end": 0, 312 "matchURL": null, 313 "disabled": true, 314 "matches": [], 315 "akaRuleId": "6d3bbc891fc0d8ce", 316 "statusCode": 301, 317 "redirectURL": "/path", 318 "useIncomingQueryString": false 319 } 320 ], 321 "matchRulesWarnings": [], 322 "modifiedBy": "jsmith", 323 "modifiedDate": "2023-10-19T10:45:30.619Z", 324 "policyId": 276858, 325 "version": 1 326 }`, 327 expectedPath: "/cloudlets/v3/policies/276858/versions/1", 328 expectedResponse: &PolicyVersion{ 329 CreatedDate: *newTimeFromString(t, "2023-10-19T10:45:30.619Z"), 330 CreatedBy: "jsmith", 331 Description: nil, 332 PolicyID: 276858, 333 PolicyVersion: 1, 334 ID: 6551242, 335 MatchRules: MatchRules{ 336 &MatchRuleER{ 337 Type: "erMatchRule", 338 End: 0, 339 ID: 0, 340 MatchURL: "", 341 Name: "er_rule", 342 Matches: []MatchCriteriaER{}, 343 RedirectURL: "/path", 344 Start: 0, 345 StatusCode: 301, 346 UseIncomingQueryString: false, 347 Disabled: true, 348 }, 349 }, 350 MatchRulesWarnings: []MatchRulesWarning{}, 351 ModifiedBy: "jsmith", 352 ModifiedDate: newTimeFromString(t, "2023-10-19T10:45:30.619Z"), 353 }, 354 }, 355 "200 OK, AS rule with disabled=false": { 356 request: GetPolicyVersionRequest{ 357 PolicyID: 355557, 358 PolicyVersion: 2, 359 }, 360 responseStatus: http.StatusOK, 361 responseBody: `{ 362 "createdDate": "2023-10-19T09:46:57.395Z", 363 "createdBy": "jsmith", 364 "description": "Initial version", 365 "modifiedBy": "jsmith", 366 "modifiedDate": "2023-10-19T10:45:30.619Z", 367 "matchRules": [ 368 { 369 "type": "asMatchRule", 370 "akaRuleId": "f58014ee0cc17ce", 371 "end": 0, 372 "forwardSettings": { 373 "originId": "originremote2", 374 "pathAndQS": "/sales/Q1/", 375 "useIncomingQueryString": true 376 }, 377 "id": 0, 378 "matches": [ 379 { 380 "caseSensitive": false, 381 "matchOperator": "equals", 382 "matchType": "range", 383 "negate": false, 384 "objectMatchValue": { 385 "type": "range", 386 "value": [ 387 1, 388 25 389 ] 390 } 391 } 392 ], 393 "name": "Q1Sales", 394 "start": 0 395 } 396 ], 397 "policyId": 355557, 398 "version": 2 399 }`, 400 expectedPath: "/cloudlets/v3/policies/355557/versions/2", 401 expectedResponse: &PolicyVersion{ 402 CreatedBy: "jsmith", 403 CreatedDate: *newTimeFromString(t, "2023-10-19T09:46:57.395Z"), 404 Description: tools.StringPtr("Initial version"), 405 MatchRules: MatchRules{ 406 &MatchRuleAS{ 407 Type: "asMatchRule", 408 End: 0, 409 ForwardSettings: ForwardSettingsAS{ 410 OriginID: "originremote2", 411 PathAndQS: "/sales/Q1/", 412 UseIncomingQueryString: true, 413 }, 414 ID: 0, 415 Matches: []MatchCriteriaAS{ 416 { 417 CaseSensitive: false, 418 MatchOperator: "equals", 419 MatchType: "range", 420 Negate: false, 421 ObjectMatchValue: &ObjectMatchValueRange{ 422 Type: "range", 423 Value: []int64{ 424 1, 25}, 425 }, 426 }, 427 }, 428 Name: "Q1Sales", 429 Start: 0, 430 }, 431 }, 432 ModifiedBy: "jsmith", 433 ModifiedDate: newTimeFromString(t, "2023-10-19T10:45:30.619Z"), 434 PolicyID: 355557, 435 PolicyVersion: 2, 436 }, 437 }, 438 "200 OK, PR rule": { 439 request: GetPolicyVersionRequest{ 440 PolicyID: 276858, 441 PolicyVersion: 6, 442 }, 443 responseStatus: http.StatusOK, 444 responseBody: `{ 445 "createdDate": "2023-10-19T09:46:57.395Z", 446 "createdBy": "jsmith", 447 "description": null, 448 "modifiedBy": "jsmith", 449 "modifiedDate": "2023-10-19T09:46:57.395Z", 450 "matchRules": [ 451 { 452 "type": "cdMatchRule", 453 "akaRuleId": "b151ca68e51f5a61", 454 "end": 0, 455 "forwardSettings": { 456 "originId": "fr_test_krk_dc2", 457 "percent": 11 458 }, 459 "id": 0, 460 "matches": [ 461 { 462 "caseSensitive": false, 463 "matchOperator": "equals", 464 "matchType": "method", 465 "negate": false, 466 "objectMatchValue": { 467 "type": "simple", 468 "value": [ 469 "GET" 470 ] 471 } 472 } 473 ], 474 "name": "rule 1", 475 "start": 0 476 } 477 ], 478 "policyId": 325401, 479 "version": 3 480 }`, 481 expectedPath: "/cloudlets/v3/policies/276858/versions/6", 482 expectedResponse: &PolicyVersion{ 483 CreatedBy: "jsmith", 484 CreatedDate: *newTimeFromString(t, "2023-10-19T09:46:57.395Z"), 485 Description: nil, 486 ModifiedBy: "jsmith", 487 ModifiedDate: newTimeFromString(t, "2023-10-19T09:46:57.395Z"), 488 MatchRules: MatchRules{ 489 &MatchRulePR{ 490 Type: "cdMatchRule", 491 End: 0, 492 ForwardSettings: ForwardSettingsPR{ 493 OriginID: "fr_test_krk_dc2", 494 Percent: 11, 495 }, 496 ID: 0, 497 Matches: []MatchCriteriaPR{ 498 { 499 CaseSensitive: false, 500 MatchOperator: "equals", 501 MatchType: "method", 502 Negate: false, 503 ObjectMatchValue: &ObjectMatchValueSimple{ 504 Type: "simple", 505 Value: []string{ 506 "GET"}, 507 }, 508 }, 509 }, 510 Name: "rule 1", 511 Start: 0, 512 }, 513 }, 514 PolicyID: 325401, 515 PolicyVersion: 3, 516 }, 517 }, 518 "200 OK, ER rule with disabled=false": { 519 request: GetPolicyVersionRequest{ 520 PolicyID: 276858, 521 PolicyVersion: 6, 522 }, 523 responseStatus: http.StatusOK, 524 responseBody: `{ 525 "createdDate": "2023-10-19T09:46:57.395Z", 526 "createdBy": "jsmith", 527 "description": null, 528 "modifiedBy": "jsmith", 529 "modifiedDate": "2023-10-19T09:46:57.395Z", 530 "matchRules": [ 531 { 532 "type": "erMatchRule", 533 "end": 0, 534 "id": 0, 535 "matchURL": null, 536 "name": "rul3", 537 "redirectURL": "/abc/sss", 538 "start": 0, 539 "statusCode": 307, 540 "useIncomingQueryString": false, 541 "useIncomingSchemeAndHost": true, 542 "useRelativeUrl": "copy_scheme_hostname" 543 } 544 ], 545 "policyId": 276858, 546 "version": 6 547 }`, 548 expectedPath: "/cloudlets/v3/policies/276858/versions/6", 549 expectedResponse: &PolicyVersion{ 550 CreatedDate: *newTimeFromString(t, "2023-10-19T09:46:57.395Z"), 551 CreatedBy: "jsmith", 552 Description: nil, 553 ModifiedBy: "jsmith", 554 ModifiedDate: newTimeFromString(t, "2023-10-19T09:46:57.395Z"), 555 PolicyID: 276858, 556 PolicyVersion: 6, 557 MatchRules: MatchRules{ 558 &MatchRuleER{ 559 Type: "erMatchRule", 560 End: 0, 561 ID: 0, 562 MatchURL: "", 563 Name: "rul3", 564 RedirectURL: "/abc/sss", 565 Start: 0, 566 StatusCode: 307, 567 UseIncomingQueryString: false, 568 UseIncomingSchemeAndHost: true, 569 UseRelativeURL: "copy_scheme_hostname", 570 Disabled: false, 571 }, 572 }, 573 }, 574 }, 575 "200 OK, FR with disabled rule": { 576 request: GetPolicyVersionRequest{ 577 PolicyID: 276858, 578 PolicyVersion: 6, 579 }, 580 responseStatus: http.StatusOK, 581 responseBody: `{ 582 "createdDate": "2023-10-19T08:50:47.350Z", 583 "createdBy": "jsmith", 584 "description": null, 585 "modifiedBy": "jsmith", 586 "modifiedDate": "2023-10-19T08:50:47.350Z", 587 "matchRules": [{ 588 "type": "frMatchRule", 589 "disabled": true, 590 "end": 0, 591 "id": 0, 592 "matchURL": null, 593 "forwardSettings": { 594 "pathAndQS": "/test_images/simpleimg.jpg", 595 "useIncomingQueryString": true, 596 "originId": "1234" 597 }, 598 "name": "rule 1", 599 "start": 0 600 }], 601 "policyId": 276858, 602 "version": 6 603 }`, 604 expectedPath: "/cloudlets/v3/policies/276858/versions/6", 605 expectedResponse: &PolicyVersion{ 606 CreatedBy: "jsmith", 607 CreatedDate: *newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 608 Description: nil, 609 PolicyID: 276858, 610 PolicyVersion: 6, 611 ModifiedBy: "jsmith", 612 ModifiedDate: newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 613 MatchRules: MatchRules{ 614 &MatchRuleFR{ 615 Name: "rule 1", 616 Type: "frMatchRule", 617 Start: 0, 618 End: 0, 619 ID: 0, 620 MatchURL: "", 621 ForwardSettings: ForwardSettingsFR{ 622 PathAndQS: "/test_images/simpleimg.jpg", 623 UseIncomingQueryString: true, 624 OriginID: "1234", 625 }, 626 Disabled: true, 627 }, 628 }, 629 }, 630 }, 631 "500 internal server error": { 632 request: GetPolicyVersionRequest{ 633 PolicyID: 1, 634 }, 635 responseStatus: http.StatusInternalServerError, 636 responseBody: ` 637 { 638 "type": "internal_error", 639 "title": "Internal Server Error", 640 "status": 500 641 }`, 642 expectedPath: "/cloudlets/v3/policies/1/versions/0", 643 withError: func(t *testing.T, err error) { 644 want := &Error{ 645 Type: "internal_error", 646 Title: "Internal Server Error", 647 Status: http.StatusInternalServerError, 648 } 649 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 650 }, 651 }, 652 } 653 654 for name, test := range tests { 655 name, test := name, test 656 t.Run(name, func(t *testing.T) { 657 t.Parallel() 658 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 659 assert.Equal(t, test.expectedPath, r.URL.String()) 660 assert.Equal(t, http.MethodGet, r.Method) 661 w.WriteHeader(test.responseStatus) 662 _, err := w.Write([]byte(test.responseBody)) 663 assert.NoError(t, err) 664 })) 665 client := mockAPIClient(t, mockServer) 666 result, err := client.GetPolicyVersion(context.Background(), test.request) 667 if test.withError != nil { 668 test.withError(t, err) 669 return 670 } 671 require.NoError(t, err) 672 assert.Equal(t, test.expectedResponse, result) 673 }) 674 } 675 } 676 677 func TestCreatePolicyVersion(t *testing.T) { 678 t.Parallel() 679 tests := map[string]struct { 680 request CreatePolicyVersionRequest 681 requestBody string 682 responseStatus int 683 responseBody string 684 expectedPath string 685 expectedResponse *PolicyVersion 686 withError error 687 }{ 688 "201 created, simple ER": { 689 request: CreatePolicyVersionRequest{ 690 CreatePolicyVersion: CreatePolicyVersion{ 691 Description: tools.StringPtr("Description for the policy"), 692 }, 693 PolicyID: 276858, 694 }, 695 responseStatus: http.StatusCreated, 696 responseBody: ` 697 { 698 "createdDate": "2023-10-19T08:50:47.350Z", 699 "createdBy": "jsmith", 700 "description": "Description for the policy", 701 "modifiedBy": "jsmith", 702 "modifiedDate": "2023-10-19T08:50:47.350Z", 703 "matchRules": null, 704 "policyId": 276858, 705 "version": 2 706 }`, 707 expectedPath: "/cloudlets/v3/policies/276858/versions", 708 expectedResponse: &PolicyVersion{ 709 CreatedDate: *newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 710 CreatedBy: "jsmith", 711 Description: tools.StringPtr("Description for the policy"), 712 ModifiedBy: "jsmith", 713 ModifiedDate: newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 714 MatchRules: nil, 715 PolicyID: 276858, 716 PolicyVersion: 2, 717 }, 718 }, 719 "201 created, complex AS": { 720 request: CreatePolicyVersionRequest{ 721 CreatePolicyVersion: CreatePolicyVersion{ 722 MatchRules: MatchRules{ 723 &MatchRuleAS{ 724 Start: 0, 725 End: 0, 726 Type: "asMatchRule", 727 Name: "Q1Sales", 728 ID: 0, 729 ForwardSettings: ForwardSettingsAS{ 730 OriginID: "originremote2", 731 PathAndQS: "/sales/Q1/", 732 UseIncomingQueryString: true, 733 }, 734 Matches: []MatchCriteriaAS{ 735 { 736 CaseSensitive: false, 737 MatchOperator: "equals", 738 MatchType: "range", 739 Negate: false, 740 ObjectMatchValue: &ObjectMatchValueRange{ 741 Type: "range", 742 Value: []int64{1, 25}, 743 }, 744 }, 745 { 746 CaseSensitive: false, 747 MatchOperator: "equals", 748 MatchType: "method", 749 Negate: false, 750 ObjectMatchValue: &ObjectMatchValueSimple{ 751 Type: "simple", 752 Value: []string{"GET"}, 753 }, 754 }, 755 { 756 MatchOperator: "equals", 757 MatchType: "header", 758 Negate: false, 759 ObjectMatchValue: &ObjectMatchValueObject{ 760 Type: "object", 761 Name: "AS", 762 Options: &Options{ 763 Value: []string{ 764 "text/html*", 765 "text/css*", 766 "application/x-javascript*", 767 }, 768 ValueHasWildcard: true, 769 }, 770 }, 771 }, 772 }, 773 }, 774 }, 775 }, 776 PolicyID: 355557, 777 }, 778 responseStatus: http.StatusCreated, 779 responseBody: `{ 780 "createdDate": "2023-10-19T08:50:47.350Z", 781 "createdBy": "jsmith", 782 "description": "Initial version", 783 "modifiedBy": "jsmith", 784 "modifiedDate": "2023-10-19T08:50:47.350Z", 785 "matchRules": [ 786 { 787 "type": "asMatchRule", 788 "akaRuleId": "f58014ee0cc17ce", 789 "end": 0, 790 "forwardSettings": { 791 "originId": "originremote2", 792 "pathAndQS": "/sales/Q1/", 793 "useIncomingQueryString": true 794 }, 795 "id": 0, 796 "matches": [ 797 { 798 "caseSensitive": false, 799 "matchOperator": "equals", 800 "matchType": "range", 801 "negate": false, 802 "objectMatchValue": { 803 "type": "range", 804 "value": [ 805 1, 806 25 807 ] 808 } 809 }, 810 { 811 "caseSensitive": false, 812 "matchOperator": "equals", 813 "matchType": "method", 814 "negate": false, 815 "objectMatchValue": { 816 "type": "simple", 817 "value": [ 818 "GET" 819 ] 820 } 821 }, 822 { 823 "matchOperator": "equals", 824 "matchType": "header", 825 "negate": false, 826 "objectMatchValue": { 827 "type": "object", 828 "name": "AS", 829 "options": { 830 "value": [ 831 "text/html*", 832 "text/css*", 833 "application/x-javascript*" 834 ], 835 "valueHasWildcard": true 836 } 837 } 838 } 839 ], 840 "name": "Q1Sales", 841 "start": 0 842 } 843 ], 844 "policyId": 355557, 845 "version": 2 846 }`, 847 expectedPath: "/cloudlets/v3/policies/355557/versions", 848 expectedResponse: &PolicyVersion{ 849 CreatedDate: *newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 850 CreatedBy: "jsmith", 851 Description: tools.StringPtr("Initial version"), 852 ModifiedBy: "jsmith", 853 ModifiedDate: newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 854 MatchRules: MatchRules{ 855 &MatchRuleAS{ 856 Type: "asMatchRule", 857 End: 0, 858 ForwardSettings: ForwardSettingsAS{ 859 OriginID: "originremote2", 860 PathAndQS: "/sales/Q1/", 861 UseIncomingQueryString: true, 862 }, 863 ID: 0, 864 Matches: []MatchCriteriaAS{ 865 { 866 CaseSensitive: false, 867 MatchOperator: "equals", 868 MatchType: "range", 869 Negate: false, 870 ObjectMatchValue: &ObjectMatchValueRange{ 871 Type: "range", 872 Value: []int64{ 873 1, 25}, 874 }, 875 }, 876 { 877 CaseSensitive: false, 878 MatchOperator: "equals", 879 MatchType: "method", 880 Negate: false, 881 ObjectMatchValue: &ObjectMatchValueSimple{ 882 Type: "simple", 883 Value: []string{"GET"}, 884 }, 885 }, 886 { 887 MatchOperator: "equals", 888 MatchType: "header", 889 Negate: false, 890 ObjectMatchValue: &ObjectMatchValueObject{ 891 Type: "object", 892 Name: "AS", 893 Options: &Options{ 894 Value: []string{ 895 "text/html*", 896 "text/css*", 897 "application/x-javascript*", 898 }, 899 ValueHasWildcard: true, 900 }, 901 }, 902 }, 903 }, 904 Name: "Q1Sales", 905 Start: 0, 906 }, 907 }, 908 PolicyID: 355557, 909 PolicyVersion: 2, 910 }, 911 }, 912 "201 created, complex PR": { 913 request: CreatePolicyVersionRequest{ 914 CreatePolicyVersion: CreatePolicyVersion{ 915 MatchRules: MatchRules{ 916 &MatchRulePR{ 917 Start: 0, 918 End: 0, 919 Type: "cdMatchRule", 920 Name: "rul3", 921 ID: 0, 922 ForwardSettings: ForwardSettingsPR{ 923 OriginID: "some_origin", 924 Percent: 10, 925 }, 926 Matches: []MatchCriteriaPR{ 927 { 928 MatchType: "hostname", 929 MatchValue: "3333.dom", 930 MatchOperator: "equals", 931 CaseSensitive: true, 932 Negate: false, 933 }, 934 { 935 MatchType: "cookie", 936 MatchValue: "cookie=cookievalue", 937 MatchOperator: "equals", 938 Negate: false, 939 CaseSensitive: false, 940 }, 941 { 942 MatchType: "extension", 943 MatchValue: "txt", 944 MatchOperator: "equals", 945 Negate: false, 946 CaseSensitive: false, 947 }, 948 }, 949 }, 950 &MatchRulePR{ 951 Start: 0, 952 End: 0, 953 Type: "cdMatchRule", 954 Name: "rule 2", 955 MatchURL: "ddd.aaa", 956 ID: 0, 957 ForwardSettings: ForwardSettingsPR{ 958 OriginID: "some_origin", 959 Percent: 10, 960 }, 961 }, 962 &MatchRulePR{ 963 Type: "cdMatchRule", 964 ID: 0, 965 Name: "r1", 966 Start: 0, 967 End: 0, 968 MatchURL: "abc.com", 969 ForwardSettings: ForwardSettingsPR{ 970 OriginID: "some_origin", 971 Percent: 10, 972 }, 973 }, 974 }, 975 }, 976 PolicyID: 276858, 977 }, 978 responseStatus: http.StatusCreated, 979 responseBody: `{ 980 "createdDate": "2023-10-19T08:50:47.350Z", 981 "createdBy": "jsmith", 982 "description": null, 983 "modifiedBy": "jsmith", 984 "modifiedDate": "2023-10-19T08:50:47.350Z", 985 "matchRules": [ 986 { 987 "type": "cdMatchRule", 988 "end": 0, 989 "id": 0, 990 "matchURL": null, 991 "matches": [ 992 { 993 "caseSensitive": true, 994 "matchOperator": "equals", 995 "matchType": "hostname", 996 "matchValue": "3333.dom", 997 "negate": false 998 }, 999 { 1000 "caseSensitive": false, 1001 "matchOperator": "equals", 1002 "matchType": "cookie", 1003 "matchValue": "cookie=cookievalue", 1004 "negate": false 1005 }, 1006 { 1007 "caseSensitive": false, 1008 "matchOperator": "equals", 1009 "matchType": "extension", 1010 "matchValue": "txt", 1011 "negate": false 1012 } 1013 ], 1014 "name": "rul3", 1015 "redirectURL": "/abc/sss", 1016 "start": 0, 1017 "forwardSettings": { 1018 "originId": "some_origin", 1019 "percent": 10 1020 } 1021 }, 1022 { 1023 "type": "cdMatchRule", 1024 "end": 0, 1025 "id": 0, 1026 "matchURL": "ddd.aaa", 1027 "name": "rule 2", 1028 "redirectURL": "sss.com", 1029 "start": 0, 1030 "statusCode": 301, 1031 "useIncomingQueryString": true, 1032 "useRelativeUrl": "none" 1033 }, 1034 { 1035 "type": "cdMatchRule", 1036 "end": 0, 1037 "id": 0, 1038 "matchURL": "abc.com", 1039 "name": "r1", 1040 "redirectURL": "/ddd", 1041 "start": 0, 1042 "statusCode": 301, 1043 "useIncomingQueryString": false, 1044 "useIncomingSchemeAndHost": true, 1045 "useRelativeUrl": "copy_scheme_hostname" 1046 } 1047 ], 1048 "policyId": 276858, 1049 "version": 6 1050 }`, 1051 expectedPath: "/cloudlets/v3/policies/276858/versions", 1052 expectedResponse: &PolicyVersion{ 1053 CreatedDate: *newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 1054 CreatedBy: "jsmith", 1055 Description: nil, 1056 ModifiedBy: "jsmith", 1057 ModifiedDate: newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 1058 PolicyID: 276858, 1059 PolicyVersion: 6, 1060 MatchRules: MatchRules{ 1061 &MatchRulePR{ 1062 Type: "cdMatchRule", 1063 End: 0, 1064 ID: 0, 1065 MatchURL: "", 1066 Name: "rul3", 1067 Start: 0, 1068 ForwardSettings: ForwardSettingsPR{ 1069 OriginID: "some_origin", 1070 Percent: 10, 1071 }, 1072 Matches: []MatchCriteriaPR{ 1073 { 1074 MatchType: "hostname", 1075 MatchValue: "3333.dom", 1076 MatchOperator: "equals", 1077 CaseSensitive: true, 1078 Negate: false, 1079 }, 1080 { 1081 MatchType: "cookie", 1082 MatchValue: "cookie=cookievalue", 1083 MatchOperator: "equals", 1084 Negate: false, 1085 CaseSensitive: false, 1086 }, 1087 { 1088 MatchType: "extension", 1089 MatchValue: "txt", 1090 MatchOperator: "equals", 1091 Negate: false, 1092 CaseSensitive: false, 1093 }, 1094 }, 1095 }, 1096 &MatchRulePR{ 1097 Type: "cdMatchRule", 1098 End: 0, 1099 ID: 0, 1100 MatchURL: "ddd.aaa", 1101 Name: "rule 2", 1102 Start: 0, 1103 }, 1104 &MatchRulePR{ 1105 Type: "cdMatchRule", 1106 End: 0, 1107 ID: 0, 1108 MatchURL: "abc.com", 1109 Name: "r1", 1110 Start: 0, 1111 }, 1112 }, 1113 }, 1114 }, 1115 "201 created, complex PR with objectMatchValue - simple": { 1116 request: CreatePolicyVersionRequest{ 1117 CreatePolicyVersion: CreatePolicyVersion{ 1118 MatchRules: MatchRules{ 1119 &MatchRulePR{ 1120 Start: 0, 1121 End: 0, 1122 Type: "cdMatchRule", 1123 Name: "rul3", 1124 ID: 0, 1125 ForwardSettings: ForwardSettingsPR{ 1126 OriginID: "some_origin", 1127 Percent: 10, 1128 }, 1129 Matches: []MatchCriteriaPR{ 1130 { 1131 CaseSensitive: true, 1132 MatchOperator: "equals", 1133 MatchType: "method", 1134 Negate: false, 1135 ObjectMatchValue: &ObjectMatchValueSimple{ 1136 Type: "simple", 1137 Value: []string{"GET"}, 1138 }, 1139 }, 1140 }, 1141 }, 1142 }, 1143 }, 1144 PolicyID: 276858, 1145 }, 1146 requestBody: `{"matchRules":[{"name":"rul3","type":"cdMatchRule","matches":[{"matchType":"method","matchOperator":"equals","caseSensitive":true,"negate":false,"objectMatchValue":{"type":"simple","value":["GET"]}}],"forwardSettings":{"originId":"some_origin","percent":10}}]}`, 1147 responseStatus: http.StatusCreated, 1148 responseBody: `{ 1149 "createdDate": "2023-10-19T08:50:47.350Z", 1150 "createdBy": "jsmith", 1151 "description": null, 1152 "modifiedBy": "jsmith", 1153 "modifiedDate": "2023-10-19T08:50:47.350Z", 1154 "matchRules": [ 1155 { 1156 "type": "cdMatchRule", 1157 "end": 0, 1158 "id": 0, 1159 "matchURL": null, 1160 "matches": [ 1161 { 1162 "caseSensitive": true, 1163 "matchOperator": "equals", 1164 "matchType": "method", 1165 "negate": false, 1166 "objectMatchValue": { 1167 "type": "simple", 1168 "value": [ 1169 "GET" 1170 ] 1171 } 1172 } 1173 ], 1174 "name": "rul3", 1175 "redirectURL": "/abc/sss", 1176 "start": 0, 1177 "forwardSettings": { 1178 "originId": "some_origin", 1179 "percent": 10 1180 } 1181 } 1182 ], 1183 "policyId": 276858, 1184 "version": 6 1185 }`, 1186 expectedPath: "/cloudlets/v3/policies/276858/versions", 1187 expectedResponse: &PolicyVersion{ 1188 CreatedDate: *newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 1189 CreatedBy: "jsmith", 1190 Description: nil, 1191 ModifiedBy: "jsmith", 1192 ModifiedDate: newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 1193 PolicyID: 276858, 1194 PolicyVersion: 6, 1195 MatchRules: MatchRules{ 1196 &MatchRulePR{ 1197 Type: "cdMatchRule", 1198 End: 0, 1199 ID: 0, 1200 MatchURL: "", 1201 Name: "rul3", 1202 Start: 0, 1203 ForwardSettings: ForwardSettingsPR{ 1204 OriginID: "some_origin", 1205 Percent: 10, 1206 }, 1207 Matches: []MatchCriteriaPR{ 1208 { 1209 CaseSensitive: true, 1210 MatchOperator: "equals", 1211 MatchType: "method", 1212 Negate: false, 1213 ObjectMatchValue: &ObjectMatchValueSimple{ 1214 Type: "simple", 1215 Value: []string{"GET"}, 1216 }, 1217 }, 1218 }, 1219 }, 1220 }, 1221 }, 1222 }, 1223 "201 created, complex PR with objectMatchValue - object": { 1224 request: CreatePolicyVersionRequest{ 1225 CreatePolicyVersion: CreatePolicyVersion{ 1226 MatchRules: MatchRules{ 1227 &MatchRulePR{ 1228 Start: 0, 1229 End: 0, 1230 Type: "cdMatchRule", 1231 Name: "rul3", 1232 ID: 0, 1233 ForwardSettings: ForwardSettingsPR{ 1234 OriginID: "some_origin", 1235 Percent: 10, 1236 }, 1237 Matches: []MatchCriteriaPR{ 1238 { 1239 MatchOperator: "equals", 1240 MatchType: "header", 1241 Negate: false, 1242 ObjectMatchValue: &ObjectMatchValueObject{ 1243 Type: "object", 1244 Name: "PR", 1245 Options: &Options{ 1246 Value: []string{ 1247 "text/html*", 1248 "text/css*", 1249 "application/x-javascript*", 1250 }, 1251 ValueHasWildcard: true, 1252 }, 1253 }, 1254 }, 1255 }, 1256 }, 1257 }, 1258 }, 1259 PolicyID: 276858, 1260 }, 1261 responseStatus: http.StatusCreated, 1262 responseBody: `{ 1263 "createdDate": "2023-10-19T08:50:47.350Z", 1264 "createdBy": "jsmith", 1265 "description": null, 1266 "modifiedBy": "jsmith", 1267 "modifiedDate": "2023-10-19T08:50:47.350Z", 1268 "matchRules": [ 1269 { 1270 "type": "cdMatchRule", 1271 "end": 0, 1272 "id": 0, 1273 "matchURL": null, 1274 "matches": [ 1275 { 1276 "matchOperator": "equals", 1277 "matchType": "hostname", 1278 "negate": false, 1279 "objectMatchValue": { 1280 "type": "object", 1281 "name": "PR", 1282 "options": { 1283 "value": [ 1284 "text/html*", 1285 "text/css*", 1286 "application/x-javascript*" 1287 ], 1288 "valueHasWildcard": true 1289 } 1290 } 1291 } 1292 ], 1293 "name": "rul3", 1294 "redirectURL": "/abc/sss", 1295 "start": 0, 1296 "forwardSettings": { 1297 "originId": "some_origin", 1298 "percent": 10 1299 } 1300 } 1301 ], 1302 "policyId": 276858, 1303 "version": 6 1304 }`, 1305 expectedPath: "/cloudlets/v3/policies/276858/versions", 1306 expectedResponse: &PolicyVersion{ 1307 CreatedDate: *newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 1308 CreatedBy: "jsmith", 1309 Description: nil, 1310 ModifiedBy: "jsmith", 1311 ModifiedDate: newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 1312 PolicyID: 276858, 1313 PolicyVersion: 6, 1314 MatchRules: MatchRules{ 1315 &MatchRulePR{ 1316 Type: "cdMatchRule", 1317 End: 0, 1318 ID: 0, 1319 MatchURL: "", 1320 Name: "rul3", 1321 Start: 0, 1322 ForwardSettings: ForwardSettingsPR{ 1323 OriginID: "some_origin", 1324 Percent: 10, 1325 }, 1326 Matches: []MatchCriteriaPR{ 1327 { 1328 MatchOperator: "equals", 1329 MatchType: "hostname", 1330 Negate: false, 1331 ObjectMatchValue: &ObjectMatchValueObject{ 1332 Type: "object", 1333 Name: "PR", 1334 Options: &Options{ 1335 Value: []string{ 1336 "text/html*", 1337 "text/css*", 1338 "application/x-javascript*", 1339 }, 1340 ValueHasWildcard: true, 1341 }, 1342 }, 1343 }, 1344 }, 1345 }, 1346 }, 1347 }, 1348 }, 1349 "validation error, complex PR with unavailable objectMatchValue type - range": { 1350 request: CreatePolicyVersionRequest{ 1351 CreatePolicyVersion: CreatePolicyVersion{ 1352 MatchRules: MatchRules{ 1353 &MatchRulePR{ 1354 Start: 0, 1355 End: 0, 1356 Type: "cdMatchRule", 1357 Name: "rul3", 1358 ID: 0, 1359 ForwardSettings: ForwardSettingsPR{ 1360 OriginID: "some_origin", 1361 Percent: 10, 1362 }, 1363 Matches: []MatchCriteriaPR{ 1364 { 1365 MatchOperator: "equals", 1366 MatchType: "header", 1367 Negate: false, 1368 ObjectMatchValue: &ObjectMatchValueRange{ 1369 Type: "range", 1370 Value: []int64{1, 50}, 1371 }, 1372 }, 1373 }, 1374 }, 1375 }, 1376 }, 1377 PolicyID: 276858, 1378 }, 1379 withError: ErrStructValidation, 1380 }, 1381 "validation error, complex PR missing forwardSettings": { 1382 request: CreatePolicyVersionRequest{ 1383 CreatePolicyVersion: CreatePolicyVersion{ 1384 MatchRules: MatchRules{ 1385 &MatchRulePR{ 1386 Start: 0, 1387 End: 0, 1388 Type: "cdMatchRule", 1389 Name: "rul3", 1390 ID: 0, 1391 ForwardSettings: ForwardSettingsPR{ 1392 OriginID: "some_origin", 1393 Percent: 10, 1394 }, 1395 Matches: []MatchCriteriaPR{ 1396 { 1397 MatchType: "hostname", 1398 MatchValue: "3333.dom", 1399 MatchOperator: "equals", 1400 CaseSensitive: true, 1401 Negate: false, 1402 }, 1403 { 1404 MatchType: "cookie", 1405 MatchValue: "cookie=cookievalue", 1406 MatchOperator: "equals", 1407 Negate: false, 1408 CaseSensitive: false, 1409 }, 1410 { 1411 MatchType: "extension", 1412 MatchValue: "txt", 1413 MatchOperator: "equals", 1414 Negate: false, 1415 CaseSensitive: false, 1416 }, 1417 }, 1418 }, 1419 &MatchRulePR{ 1420 Start: 0, 1421 End: 0, 1422 Type: "cdMatchRule", 1423 Name: "rule 2", 1424 MatchURL: "ddd.aaa", 1425 ID: 0, 1426 }, 1427 &MatchRulePR{ 1428 Type: "cdMatchRule", 1429 ID: 0, 1430 Name: "r1", 1431 Start: 0, 1432 End: 0, 1433 MatchURL: "abc.com", 1434 ForwardSettings: ForwardSettingsPR{ 1435 OriginID: "some_origin", 1436 Percent: 10, 1437 }, 1438 }, 1439 }, 1440 }, 1441 PolicyID: 276858, 1442 }, 1443 withError: ErrStructValidation, 1444 }, 1445 1446 "201 created, complex ER": { 1447 request: CreatePolicyVersionRequest{ 1448 CreatePolicyVersion: CreatePolicyVersion{ 1449 MatchRules: MatchRules{ 1450 &MatchRuleER{ 1451 Start: 0, 1452 End: 0, 1453 Type: "erMatchRule", 1454 UseRelativeURL: "copy_scheme_hostname", 1455 Name: "rul3", 1456 StatusCode: 307, 1457 RedirectURL: "/abc/sss", 1458 ID: 0, 1459 Matches: []MatchCriteriaER{ 1460 { 1461 MatchType: "hostname", 1462 MatchValue: "3333.dom", 1463 MatchOperator: "equals", 1464 CaseSensitive: true, 1465 Negate: false, 1466 }, 1467 { 1468 MatchType: "cookie", 1469 MatchValue: "cookie=cookievalue", 1470 MatchOperator: "equals", 1471 Negate: false, 1472 CaseSensitive: false, 1473 }, 1474 { 1475 MatchType: "extension", 1476 MatchValue: "txt", 1477 MatchOperator: "equals", 1478 Negate: false, 1479 CaseSensitive: false, 1480 }, 1481 }, 1482 }, 1483 &MatchRuleER{ 1484 Start: 0, 1485 End: 0, 1486 Type: "erMatchRule", 1487 UseRelativeURL: "none", 1488 Name: "rule 2", 1489 MatchURL: "ddd.aaa", 1490 RedirectURL: "sss.com", 1491 StatusCode: 301, 1492 UseIncomingQueryString: true, 1493 ID: 0, 1494 }, 1495 &MatchRuleER{ 1496 Type: "erMatchRule", 1497 ID: 0, 1498 Name: "r1", 1499 Start: 0, 1500 End: 0, 1501 MatchURL: "abc.com", 1502 StatusCode: 301, 1503 RedirectURL: "/ddd", 1504 UseIncomingQueryString: false, 1505 UseIncomingSchemeAndHost: true, 1506 UseRelativeURL: "copy_scheme_hostname", 1507 }, 1508 }, 1509 }, 1510 PolicyID: 276858, 1511 }, 1512 responseStatus: http.StatusCreated, 1513 responseBody: `{ 1514 "createdDate": "2023-10-19T08:50:47.350Z", 1515 "createdBy": "jsmith", 1516 "description": null, 1517 "modifiedBy": "jsmith", 1518 "modifiedDate": "2023-10-19T08:50:47.350Z", 1519 "matchRules": [ 1520 { 1521 "type": "erMatchRule", 1522 "end": 0, 1523 "id": 0, 1524 "matchURL": null, 1525 "matches": [ 1526 { 1527 "caseSensitive": true, 1528 "matchOperator": "equals", 1529 "matchType": "hostname", 1530 "matchValue": "3333.dom", 1531 "negate": false 1532 }, 1533 { 1534 "caseSensitive": false, 1535 "matchOperator": "equals", 1536 "matchType": "cookie", 1537 "matchValue": "cookie=cookievalue", 1538 "negate": false 1539 }, 1540 { 1541 "caseSensitive": false, 1542 "matchOperator": "equals", 1543 "matchType": "extension", 1544 "matchValue": "txt", 1545 "negate": false 1546 } 1547 ], 1548 "name": "rul3", 1549 "redirectURL": "/abc/sss", 1550 "start": 0, 1551 "statusCode": 307, 1552 "useIncomingQueryString": false, 1553 "useIncomingSchemeAndHost": true, 1554 "useRelativeUrl": "copy_scheme_hostname" 1555 }, 1556 { 1557 "type": "erMatchRule", 1558 "end": 0, 1559 "id": 0, 1560 "matchURL": "ddd.aaa", 1561 "name": "rule 2", 1562 "redirectURL": "sss.com", 1563 "start": 0, 1564 "statusCode": 301, 1565 "useIncomingQueryString": true, 1566 "useRelativeUrl": "none" 1567 }, 1568 { 1569 "type": "erMatchRule", 1570 "end": 0, 1571 "id": 0, 1572 "matchURL": "abc.com", 1573 "name": "r1", 1574 "redirectURL": "/ddd", 1575 "start": 0, 1576 "statusCode": 301, 1577 "useIncomingQueryString": false, 1578 "useIncomingSchemeAndHost": true, 1579 "useRelativeUrl": "copy_scheme_hostname" 1580 } 1581 ], 1582 "policyId": 276858, 1583 "version": 6 1584 }`, 1585 expectedPath: "/cloudlets/v3/policies/276858/versions", 1586 expectedResponse: &PolicyVersion{ 1587 CreatedDate: *newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 1588 CreatedBy: "jsmith", 1589 Description: nil, 1590 ModifiedBy: "jsmith", 1591 ModifiedDate: newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 1592 PolicyID: 276858, 1593 PolicyVersion: 6, 1594 MatchRules: MatchRules{ 1595 &MatchRuleER{ 1596 Type: "erMatchRule", 1597 End: 0, 1598 ID: 0, 1599 MatchURL: "", 1600 Name: "rul3", 1601 RedirectURL: "/abc/sss", 1602 Start: 0, 1603 StatusCode: 307, 1604 UseIncomingQueryString: false, 1605 UseIncomingSchemeAndHost: true, 1606 UseRelativeURL: "copy_scheme_hostname", 1607 Matches: []MatchCriteriaER{ 1608 { 1609 MatchType: "hostname", 1610 MatchValue: "3333.dom", 1611 MatchOperator: "equals", 1612 CaseSensitive: true, 1613 Negate: false, 1614 }, 1615 { 1616 MatchType: "cookie", 1617 MatchValue: "cookie=cookievalue", 1618 MatchOperator: "equals", 1619 Negate: false, 1620 CaseSensitive: false, 1621 }, 1622 { 1623 MatchType: "extension", 1624 MatchValue: "txt", 1625 MatchOperator: "equals", 1626 Negate: false, 1627 CaseSensitive: false, 1628 }, 1629 }, 1630 }, 1631 &MatchRuleER{ 1632 Type: "erMatchRule", 1633 End: 0, 1634 ID: 0, 1635 MatchURL: "ddd.aaa", 1636 Name: "rule 2", 1637 RedirectURL: "sss.com", 1638 Start: 0, 1639 StatusCode: 301, 1640 UseIncomingQueryString: true, 1641 UseRelativeURL: "none", 1642 }, 1643 &MatchRuleER{ 1644 Type: "erMatchRule", 1645 End: 0, 1646 ID: 0, 1647 MatchURL: "abc.com", 1648 Name: "r1", 1649 RedirectURL: "/ddd", 1650 Start: 0, 1651 StatusCode: 301, 1652 UseIncomingQueryString: false, 1653 UseIncomingSchemeAndHost: true, 1654 UseRelativeURL: "copy_scheme_hostname", 1655 }, 1656 }, 1657 }, 1658 }, 1659 "201 created, complex ER with objectMatchValue - simple": { 1660 request: CreatePolicyVersionRequest{ 1661 CreatePolicyVersion: CreatePolicyVersion{ 1662 MatchRules: MatchRules{ 1663 &MatchRuleER{ 1664 Start: 0, 1665 End: 0, 1666 Type: "erMatchRule", 1667 UseRelativeURL: "copy_scheme_hostname", 1668 Name: "rul3", 1669 StatusCode: 307, 1670 RedirectURL: "/abc/sss", 1671 ID: 0, 1672 Matches: []MatchCriteriaER{ 1673 { 1674 CaseSensitive: true, 1675 MatchOperator: "equals", 1676 MatchType: "method", 1677 Negate: false, 1678 ObjectMatchValue: &ObjectMatchValueSimple{ 1679 Type: "simple", 1680 Value: []string{"GET"}, 1681 }, 1682 }, 1683 }, 1684 }, 1685 }, 1686 }, 1687 PolicyID: 276858, 1688 }, 1689 responseStatus: http.StatusCreated, 1690 responseBody: `{ 1691 "createdDate": "2023-10-19T08:50:47.350Z", 1692 "createdBy": "jsmith", 1693 "description": null, 1694 "modifiedBy": "jsmith", 1695 "modifiedDate": "2023-10-19T08:50:47.350Z", 1696 "matchRules": [ 1697 { 1698 "type": "erMatchRule", 1699 "end": 0, 1700 "id": 0, 1701 "matchURL": null, 1702 "matches": [ 1703 { 1704 "caseSensitive": true, 1705 "matchOperator": "equals", 1706 "matchType": "method", 1707 "negate": false, 1708 "objectMatchValue": { 1709 "type": "simple", 1710 "value": [ 1711 "GET" 1712 ] 1713 } 1714 } 1715 ], 1716 "name": "rul3", 1717 "redirectURL": "/abc/sss", 1718 "start": 0, 1719 "statusCode": 307, 1720 "useIncomingQueryString": false, 1721 "useIncomingSchemeAndHost": true, 1722 "useRelativeUrl": "copy_scheme_hostname" 1723 } 1724 ], 1725 "policyId": 276858, 1726 "version": 6 1727 }`, 1728 expectedPath: "/cloudlets/v3/policies/276858/versions", 1729 expectedResponse: &PolicyVersion{ 1730 CreatedDate: *newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 1731 CreatedBy: "jsmith", 1732 Description: nil, 1733 ModifiedBy: "jsmith", 1734 ModifiedDate: newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 1735 PolicyID: 276858, 1736 PolicyVersion: 6, 1737 MatchRules: MatchRules{ 1738 &MatchRuleER{ 1739 Type: "erMatchRule", 1740 End: 0, 1741 ID: 0, 1742 MatchURL: "", 1743 Name: "rul3", 1744 RedirectURL: "/abc/sss", 1745 Start: 0, 1746 StatusCode: 307, 1747 UseIncomingQueryString: false, 1748 UseIncomingSchemeAndHost: true, 1749 UseRelativeURL: "copy_scheme_hostname", 1750 Matches: []MatchCriteriaER{ 1751 { 1752 CaseSensitive: true, 1753 MatchOperator: "equals", 1754 MatchType: "method", 1755 Negate: false, 1756 ObjectMatchValue: &ObjectMatchValueSimple{ 1757 Type: "simple", 1758 Value: []string{"GET"}, 1759 }, 1760 }, 1761 }, 1762 }, 1763 }, 1764 }, 1765 }, 1766 "201 created, complex ER with objectMatchValue - object": { 1767 request: CreatePolicyVersionRequest{ 1768 CreatePolicyVersion: CreatePolicyVersion{ 1769 MatchRules: MatchRules{ 1770 &MatchRuleER{ 1771 Start: 0, 1772 End: 0, 1773 Type: "erMatchRule", 1774 UseRelativeURL: "copy_scheme_hostname", 1775 Name: "rul3", 1776 StatusCode: 307, 1777 RedirectURL: "/abc/sss", 1778 ID: 0, 1779 Matches: []MatchCriteriaER{ 1780 { 1781 MatchOperator: "equals", 1782 MatchType: "header", 1783 Negate: false, 1784 ObjectMatchValue: &ObjectMatchValueObject{ 1785 Type: "object", 1786 Name: "ER", 1787 Options: &Options{ 1788 Value: []string{ 1789 "text/html*", 1790 "text/css*", 1791 "application/x-javascript*", 1792 }, 1793 ValueHasWildcard: true, 1794 }, 1795 }, 1796 }, 1797 }, 1798 }, 1799 }, 1800 }, 1801 PolicyID: 276858, 1802 }, 1803 responseStatus: http.StatusCreated, 1804 responseBody: `{ 1805 "createdDate": "2023-10-19T08:50:47.350Z", 1806 "createdBy": "jsmith", 1807 "description": null, 1808 "modifiedBy": "jsmith", 1809 "modifiedDate": "2023-10-19T08:50:47.350Z", 1810 "matchRules": [ 1811 { 1812 "type": "erMatchRule", 1813 "end": 0, 1814 "id": 0, 1815 "matchURL": null, 1816 "matches": [ 1817 { 1818 "matchOperator": "equals", 1819 "matchType": "hostname", 1820 "negate": false, 1821 "objectMatchValue": { 1822 "type": "object", 1823 "name": "ER", 1824 "options": { 1825 "value": [ 1826 "text/html*", 1827 "text/css*", 1828 "application/x-javascript*" 1829 ], 1830 "valueHasWildcard": true 1831 } 1832 } 1833 } 1834 ], 1835 "name": "rul3", 1836 "redirectURL": "/abc/sss", 1837 "start": 0, 1838 "statusCode": 307, 1839 "useIncomingQueryString": false, 1840 "useIncomingSchemeAndHost": true, 1841 "useRelativeUrl": "copy_scheme_hostname" 1842 } 1843 ], 1844 "policyId": 276858, 1845 "version": 6 1846 }`, 1847 expectedPath: "/cloudlets/v3/policies/276858/versions", 1848 expectedResponse: &PolicyVersion{ 1849 CreatedDate: *newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 1850 CreatedBy: "jsmith", 1851 Description: nil, 1852 ModifiedBy: "jsmith", 1853 ModifiedDate: newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 1854 PolicyID: 276858, 1855 PolicyVersion: 6, 1856 MatchRules: MatchRules{ 1857 &MatchRuleER{ 1858 Type: "erMatchRule", 1859 End: 0, 1860 ID: 0, 1861 MatchURL: "", 1862 Name: "rul3", 1863 RedirectURL: "/abc/sss", 1864 Start: 0, 1865 StatusCode: 307, 1866 UseIncomingQueryString: false, 1867 UseIncomingSchemeAndHost: true, 1868 UseRelativeURL: "copy_scheme_hostname", 1869 Matches: []MatchCriteriaER{ 1870 { 1871 MatchOperator: "equals", 1872 MatchType: "hostname", 1873 Negate: false, 1874 ObjectMatchValue: &ObjectMatchValueObject{ 1875 Type: "object", 1876 Name: "ER", 1877 Options: &Options{ 1878 Value: []string{ 1879 "text/html*", 1880 "text/css*", 1881 "application/x-javascript*", 1882 }, 1883 ValueHasWildcard: true, 1884 }, 1885 }, 1886 }, 1887 }, 1888 }, 1889 }, 1890 }, 1891 }, 1892 "201 created, ER with empty/no useRelativeURL": { 1893 request: CreatePolicyVersionRequest{ 1894 CreatePolicyVersion: CreatePolicyVersion{ 1895 MatchRules: MatchRules{ 1896 &MatchRuleER{ 1897 Start: 0, 1898 End: 0, 1899 Type: "erMatchRule", 1900 Name: "rule 2", 1901 MatchURL: "ddd.aaa", 1902 RedirectURL: "sss.com", 1903 StatusCode: 301, 1904 UseIncomingQueryString: true, 1905 ID: 0, 1906 }, 1907 &MatchRuleER{ 1908 Type: "erMatchRule", 1909 ID: 0, 1910 Name: "r1", 1911 Start: 0, 1912 End: 0, 1913 MatchURL: "abc.com", 1914 StatusCode: 301, 1915 RedirectURL: "/ddd", 1916 UseIncomingQueryString: false, 1917 UseIncomingSchemeAndHost: true, 1918 UseRelativeURL: "", 1919 }, 1920 &MatchRuleER{ 1921 Start: 0, 1922 End: 0, 1923 Type: "erMatchRule", 1924 Name: "rul3", 1925 StatusCode: 307, 1926 RedirectURL: "/abc/sss", 1927 ID: 0, 1928 }, 1929 }, 1930 }, 1931 PolicyID: 276858, 1932 }, 1933 responseStatus: http.StatusCreated, 1934 responseBody: `{ 1935 "createdDate": "2023-10-19T08:50:47.350Z", 1936 "createdBy": "jsmith", 1937 "description": null, 1938 "modifiedBy": "jsmith", 1939 "modifiedDate": "2023-10-19T08:50:47.350Z", 1940 "matchRules": [ 1941 { 1942 "type": "erMatchRule", 1943 "end": 0, 1944 "id": 0, 1945 "matchURL": "ddd.aaa", 1946 "name": "rule 2", 1947 "redirectURL": "sss.com", 1948 "start": 0, 1949 "statusCode": 301, 1950 "useIncomingQueryString": true 1951 }, 1952 { 1953 "type": "erMatchRule", 1954 "end": 0, 1955 "id": 0, 1956 "matchURL": "abc.com", 1957 "name": "r1", 1958 "redirectURL": "/ddd", 1959 "start": 0, 1960 "statusCode": 301, 1961 "useIncomingQueryString": false, 1962 "useIncomingSchemeAndHost": true, 1963 "useRelativeUrl": "copy_scheme_hostname" 1964 }, 1965 { 1966 "type": "erMatchRule", 1967 "end": 0, 1968 "id": 0, 1969 "name": "rul3", 1970 "redirectURL": "/abc/sss", 1971 "start": 0, 1972 "statusCode": 307 1973 } 1974 ], 1975 "policyId": 276858, 1976 "version": 6 1977 }`, 1978 expectedPath: "/cloudlets/v3/policies/276858/versions", 1979 expectedResponse: &PolicyVersion{ 1980 CreatedDate: *newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 1981 CreatedBy: "jsmith", 1982 Description: nil, 1983 ModifiedBy: "jsmith", 1984 ModifiedDate: newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 1985 PolicyID: 276858, 1986 PolicyVersion: 6, 1987 MatchRules: MatchRules{ 1988 &MatchRuleER{ 1989 Type: "erMatchRule", 1990 End: 0, 1991 ID: 0, 1992 MatchURL: "ddd.aaa", 1993 Name: "rule 2", 1994 RedirectURL: "sss.com", 1995 Start: 0, 1996 StatusCode: 301, 1997 UseIncomingQueryString: true, 1998 }, 1999 &MatchRuleER{ 2000 Type: "erMatchRule", 2001 End: 0, 2002 ID: 0, 2003 MatchURL: "abc.com", 2004 Name: "r1", 2005 RedirectURL: "/ddd", 2006 Start: 0, 2007 StatusCode: 301, 2008 UseIncomingQueryString: false, 2009 UseIncomingSchemeAndHost: true, 2010 UseRelativeURL: "copy_scheme_hostname", 2011 }, 2012 &MatchRuleER{ 2013 Start: 0, 2014 End: 0, 2015 Type: "erMatchRule", 2016 Name: "rul3", 2017 StatusCode: 307, 2018 RedirectURL: "/abc/sss", 2019 ID: 0, 2020 }, 2021 }, 2022 }, 2023 }, 2024 "validation error, complex ER with unavailable objectMatchValue type - range": { 2025 request: CreatePolicyVersionRequest{ 2026 CreatePolicyVersion: CreatePolicyVersion{ 2027 MatchRules: MatchRules{ 2028 &MatchRuleER{ 2029 Start: 0, 2030 End: 0, 2031 Type: "erMatchRule", 2032 UseRelativeURL: "copy_scheme_hostname", 2033 Name: "rul3", 2034 StatusCode: 307, 2035 RedirectURL: "/abc/sss", 2036 ID: 0, 2037 Matches: []MatchCriteriaER{ 2038 { 2039 MatchOperator: "equals", 2040 MatchType: "header", 2041 Negate: false, 2042 ObjectMatchValue: &ObjectMatchValueRange{ 2043 Type: "range", 2044 Value: []int64{1, 50}, 2045 }, 2046 }, 2047 }, 2048 }, 2049 }, 2050 }, 2051 PolicyID: 276858, 2052 }, 2053 withError: ErrStructValidation, 2054 }, 2055 2056 "201 created, complex FR": { 2057 request: CreatePolicyVersionRequest{ 2058 CreatePolicyVersion: CreatePolicyVersion{ 2059 MatchRules: MatchRules{ 2060 &MatchRuleFR{ 2061 Start: 0, 2062 End: 0, 2063 Type: "frMatchRule", 2064 Name: "rul3", 2065 ID: 0, 2066 Matches: []MatchCriteriaFR{ 2067 { 2068 MatchType: "hostname", 2069 MatchValue: "3333.dom", 2070 MatchOperator: "equals", 2071 CaseSensitive: true, 2072 Negate: false, 2073 }, 2074 { 2075 MatchType: "cookie", 2076 MatchValue: "cookie=cookievalue", 2077 MatchOperator: "equals", 2078 Negate: false, 2079 CaseSensitive: false, 2080 }, 2081 { 2082 MatchType: "extension", 2083 MatchValue: "txt", 2084 MatchOperator: "equals", 2085 Negate: false, 2086 CaseSensitive: false, 2087 }, 2088 }, 2089 ForwardSettings: ForwardSettingsFR{ 2090 PathAndQS: "/test_images/simpleimg.jpg", 2091 UseIncomingQueryString: true, 2092 OriginID: "1234", 2093 }, 2094 }, 2095 &MatchRuleFR{ 2096 Name: "rule 1", 2097 Type: "frMatchRule", 2098 Start: 0, 2099 End: 0, 2100 ID: 0, 2101 MatchURL: "ddd.aaa", 2102 ForwardSettings: ForwardSettingsFR{ 2103 PathAndQS: "/test_images/simpleimg.jpg", 2104 UseIncomingQueryString: true, 2105 OriginID: "1234", 2106 }, 2107 }, 2108 &MatchRuleFR{ 2109 Name: "rule 2", 2110 Type: "frMatchRule", 2111 Start: 0, 2112 End: 0, 2113 ID: 0, 2114 MatchURL: "abc.com", 2115 ForwardSettings: ForwardSettingsFR{ 2116 PathAndQS: "/test_images/otherimage.jpg", 2117 UseIncomingQueryString: true, 2118 OriginID: "1234", 2119 }, 2120 }, 2121 }, 2122 }, 2123 PolicyID: 276858, 2124 }, 2125 responseStatus: http.StatusCreated, 2126 responseBody: `{ 2127 "createdDate": "2023-10-19T08:50:47.350Z", 2128 "createdBy": "jsmith", 2129 "description": null, 2130 "modifiedBy": "jsmith", 2131 "modifiedDate": "2023-10-19T08:50:47.350Z", 2132 "matchRules": [ 2133 { 2134 "type": "frMatchRule", 2135 "akaRuleId": "893947a3d5a85c1b", 2136 "end": 0, 2137 "forwardSettings": { 2138 "pathAndQS": "/test_images/otherimage.jpg", 2139 "useIncomingQueryString": true, 2140 "originId": "1234" 2141 }, 2142 "id": 0, 2143 "matchURL": null, 2144 "matches": [ 2145 { 2146 "caseSensitive": true, 2147 "matchOperator": "equals", 2148 "matchType": "hostname", 2149 "matchValue": "3333.dom", 2150 "negate": false 2151 }, 2152 { 2153 "caseSensitive": false, 2154 "matchOperator": "equals", 2155 "matchType": "cookie", 2156 "matchValue": "cookie=cookievalue", 2157 "negate": false 2158 }, 2159 { 2160 "caseSensitive": false, 2161 "matchOperator": "equals", 2162 "matchType": "extension", 2163 "matchValue": "txt", 2164 "negate": false 2165 } 2166 ], 2167 "name": "rul3", 2168 "start": 0 2169 }, 2170 { 2171 "type": "frMatchRule", 2172 "akaRuleId": "aa379d230efcded0", 2173 "end": 0, 2174 "forwardSettings": { 2175 "pathAndQS": "/test_images/simpleimg.jpg", 2176 "useIncomingQueryString": true, 2177 "originId": "1234" 2178 }, 2179 "id": 0, 2180 "matchURL": "ddd.aaa", 2181 "name": "rule 1", 2182 "start": 0 2183 }, 2184 { 2185 "type": "frMatchRule", 2186 "akaRuleId": "1afe03d843996766", 2187 "end": 0, 2188 "forwardSettings": { 2189 "pathAndQS": "/test_images/otherimage.jpg", 2190 "useIncomingQueryString": true, 2191 "originId": "1234" 2192 }, 2193 "id": 0, 2194 "matchURL": "abc.com", 2195 "name": "rule 2", 2196 "start": 0 2197 } 2198 ], 2199 "policyId": 276858, 2200 "version": 6 2201 }`, 2202 expectedPath: "/cloudlets/v3/policies/276858/versions", 2203 expectedResponse: &PolicyVersion{ 2204 CreatedDate: *newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 2205 CreatedBy: "jsmith", 2206 Description: nil, 2207 ModifiedBy: "jsmith", 2208 ModifiedDate: newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 2209 PolicyID: 276858, 2210 PolicyVersion: 6, 2211 MatchRules: MatchRules{ 2212 &MatchRuleFR{ 2213 Type: "frMatchRule", 2214 End: 0, 2215 ID: 0, 2216 MatchURL: "", 2217 Name: "rul3", 2218 Start: 0, 2219 Matches: []MatchCriteriaFR{ 2220 { 2221 MatchType: "hostname", 2222 MatchValue: "3333.dom", 2223 MatchOperator: "equals", 2224 CaseSensitive: true, 2225 Negate: false, 2226 }, 2227 { 2228 MatchType: "cookie", 2229 MatchValue: "cookie=cookievalue", 2230 MatchOperator: "equals", 2231 Negate: false, 2232 CaseSensitive: false, 2233 }, 2234 { 2235 MatchType: "extension", 2236 MatchValue: "txt", 2237 MatchOperator: "equals", 2238 Negate: false, 2239 CaseSensitive: false, 2240 }, 2241 }, 2242 ForwardSettings: ForwardSettingsFR{ 2243 PathAndQS: "/test_images/otherimage.jpg", 2244 UseIncomingQueryString: true, 2245 OriginID: "1234", 2246 }, 2247 }, 2248 &MatchRuleFR{ 2249 Name: "rule 1", 2250 Type: "frMatchRule", 2251 Start: 0, 2252 End: 0, 2253 ID: 0, 2254 MatchURL: "ddd.aaa", 2255 ForwardSettings: ForwardSettingsFR{ 2256 PathAndQS: "/test_images/simpleimg.jpg", 2257 UseIncomingQueryString: true, 2258 OriginID: "1234", 2259 }, 2260 }, 2261 &MatchRuleFR{ 2262 Name: "rule 2", 2263 Type: "frMatchRule", 2264 Start: 0, 2265 End: 0, 2266 ID: 0, 2267 MatchURL: "abc.com", 2268 ForwardSettings: ForwardSettingsFR{ 2269 PathAndQS: "/test_images/otherimage.jpg", 2270 UseIncomingQueryString: true, 2271 OriginID: "1234", 2272 }, 2273 }, 2274 }, 2275 }, 2276 }, 2277 "201 created, complex FR with objectMatchValue - object": { 2278 request: CreatePolicyVersionRequest{ 2279 CreatePolicyVersion: CreatePolicyVersion{ 2280 Description: tools.StringPtr("New version 1630480693371"), 2281 MatchRules: MatchRules{ 2282 &MatchRuleFR{ 2283 ForwardSettings: ForwardSettingsFR{}, 2284 Matches: []MatchCriteriaFR{ 2285 { 2286 CaseSensitive: false, 2287 MatchOperator: "equals", 2288 MatchType: "header", 2289 Negate: false, 2290 ObjectMatchValue: &ObjectMatchValueObject{ 2291 Type: "object", 2292 Name: "Accept", 2293 NameCaseSensitive: false, 2294 NameHasWildcard: false, 2295 Options: &Options{ 2296 Value: []string{"asd", "qwe"}, 2297 ValueHasWildcard: false, 2298 ValueCaseSensitive: true, 2299 ValueEscaped: false, 2300 }, 2301 }, 2302 }, 2303 }, 2304 Start: 0, 2305 End: 0, 2306 Type: "frMatchRule", 2307 Name: "rul3", 2308 ID: 0, 2309 }, 2310 }, 2311 }, 2312 PolicyID: 139743, 2313 }, 2314 responseStatus: http.StatusCreated, 2315 responseBody: ` 2316 { 2317 "createdDate": "2023-10-19T08:50:47.350Z", 2318 "createdBy": "jsmith", 2319 "description": "New version 1630480693371", 2320 "modifiedBy": "jsmith", 2321 "modifiedDate": "2023-10-19T08:50:47.350Z", 2322 "matchRules": [ 2323 { 2324 "type": "frMatchRule", 2325 "akaRuleId": "f2168e71692e6d9f", 2326 "end": 0, 2327 "forwardSettings": {}, 2328 "id": 0, 2329 "matchURL": null, 2330 "matches": [ 2331 { 2332 "caseSensitive": false, 2333 "matchOperator": "equals", 2334 "matchType": "header", 2335 "negate": false, 2336 "objectMatchValue": { 2337 "type": "object", 2338 "name": "Accept", 2339 "options": { 2340 "value": [ 2341 "asd", 2342 "qwe" 2343 ], 2344 "valueCaseSensitive": true 2345 } 2346 } 2347 } 2348 ], 2349 "name": "rul3", 2350 "start": 0 2351 } 2352 ], 2353 "policyId": 139743, 2354 "version": 798 2355 }`, 2356 expectedPath: "/cloudlets/v3/policies/139743/versions", 2357 expectedResponse: &PolicyVersion{ 2358 CreatedDate: *newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 2359 CreatedBy: "jsmith", 2360 Description: tools.StringPtr("New version 1630480693371"), 2361 ModifiedBy: "jsmith", 2362 ModifiedDate: newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 2363 MatchRules: MatchRules{ 2364 &MatchRuleFR{ 2365 ForwardSettings: ForwardSettingsFR{}, 2366 Matches: []MatchCriteriaFR{ 2367 { 2368 CaseSensitive: false, 2369 MatchOperator: "equals", 2370 MatchType: "header", 2371 Negate: false, 2372 ObjectMatchValue: &ObjectMatchValueObject{ 2373 Name: "Accept", 2374 Type: "object", 2375 NameCaseSensitive: false, 2376 NameHasWildcard: false, 2377 Options: &Options{ 2378 Value: []string{"asd", "qwe"}, 2379 ValueHasWildcard: false, 2380 ValueCaseSensitive: true, 2381 ValueEscaped: false, 2382 }, 2383 }, 2384 }, 2385 }, 2386 Start: 0, 2387 End: 0, 2388 Type: "frMatchRule", 2389 Name: "rul3", 2390 ID: 0, 2391 }, 2392 }, 2393 PolicyID: 139743, 2394 PolicyVersion: 798, 2395 }, 2396 }, 2397 "201 created, complex FR with objectMatchValue - simple": { 2398 request: CreatePolicyVersionRequest{ 2399 CreatePolicyVersion: CreatePolicyVersion{ 2400 Description: tools.StringPtr("New version 1630480693371"), 2401 MatchRules: MatchRules{ 2402 &MatchRuleFR{ 2403 ForwardSettings: ForwardSettingsFR{ 2404 PathAndQS: "/test_images/otherimage.jpg", 2405 UseIncomingQueryString: true, 2406 }, 2407 Matches: []MatchCriteriaFR{ 2408 { 2409 CaseSensitive: false, 2410 MatchOperator: "equals", 2411 MatchType: "method", 2412 Negate: false, 2413 ObjectMatchValue: &ObjectMatchValueSimple{ 2414 Type: "simple", 2415 Value: []string{"GET"}, 2416 }, 2417 }, 2418 }, 2419 Start: 0, 2420 End: 0, 2421 Type: "frMatchRule", 2422 Name: "rul3", 2423 ID: 0, 2424 }, 2425 }, 2426 }, 2427 PolicyID: 139743, 2428 }, 2429 responseStatus: http.StatusCreated, 2430 responseBody: ` 2431 { 2432 "createdDate": "2023-10-19T08:50:47.350Z", 2433 "createdBy": "jsmith", 2434 "description": "New version 1630480693371", 2435 "modifiedBy": "jsmith", 2436 "modifiedDate": "2023-10-19T08:50:47.350Z", 2437 "matchRules": [ 2438 { 2439 "type": "frMatchRule", 2440 "akaRuleId": "f2168e71692e6d9f", 2441 "end": 0, 2442 "forwardSettings": { 2443 "pathAndQS": "/test_images/otherimage.jpg", 2444 "useIncomingQueryString": true 2445 }, 2446 "id": 0, 2447 "matchURL": null, 2448 "matches": [ 2449 { 2450 "caseSensitive": false, 2451 "matchOperator": "equals", 2452 "matchType": "method", 2453 "negate": false, 2454 "objectMatchValue": { 2455 "type": "simple", 2456 "value": [ 2457 "GET" 2458 ] 2459 } 2460 } 2461 ], 2462 "name": "rul3", 2463 "start": 0 2464 } 2465 ], 2466 "policyId": 139743, 2467 "version": 798 2468 }`, 2469 expectedPath: "/cloudlets/v3/policies/139743/versions", 2470 expectedResponse: &PolicyVersion{ 2471 CreatedDate: *newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 2472 CreatedBy: "jsmith", 2473 Description: tools.StringPtr("New version 1630480693371"), 2474 ModifiedBy: "jsmith", 2475 ModifiedDate: newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 2476 MatchRules: MatchRules{ 2477 &MatchRuleFR{ 2478 ForwardSettings: ForwardSettingsFR{ 2479 PathAndQS: "/test_images/otherimage.jpg", 2480 UseIncomingQueryString: true, 2481 }, 2482 Matches: []MatchCriteriaFR{ 2483 { 2484 CaseSensitive: false, 2485 MatchOperator: "equals", 2486 MatchType: "method", 2487 Negate: false, 2488 ObjectMatchValue: &ObjectMatchValueSimple{ 2489 Type: "simple", 2490 Value: []string{"GET"}, 2491 }, 2492 }, 2493 }, 2494 Start: 0, 2495 End: 0, 2496 Type: "frMatchRule", 2497 Name: "rul3", 2498 ID: 0, 2499 }, 2500 }, 2501 PolicyID: 139743, 2502 PolicyVersion: 798, 2503 }, 2504 }, 2505 "201 created, complex AP with objectMatchValue - simple": { 2506 request: CreatePolicyVersionRequest{ 2507 CreatePolicyVersion: CreatePolicyVersion{ 2508 MatchRules: MatchRules{ 2509 &MatchRuleAP{ 2510 Start: 0, 2511 End: 0, 2512 Type: "apMatchRule", 2513 Name: "rul3", 2514 PassThroughPercent: tools.Float64Ptr(0), 2515 ID: 0, 2516 Matches: []MatchCriteriaAP{ 2517 { 2518 CaseSensitive: true, 2519 MatchOperator: "equals", 2520 MatchType: "method", 2521 Negate: false, 2522 ObjectMatchValue: &ObjectMatchValueSimple{ 2523 Type: "simple", 2524 Value: []string{"GET"}, 2525 }, 2526 }, 2527 }, 2528 }, 2529 }, 2530 }, 2531 PolicyID: 276858, 2532 }, 2533 responseStatus: http.StatusCreated, 2534 responseBody: `{ 2535 "createdDate": "2023-10-19T08:50:47.350Z", 2536 "createdBy": "jsmith", 2537 "description": null, 2538 "modifiedBy": "jsmith", 2539 "modifiedDate": "2023-10-19T08:50:47.350Z", 2540 "matchRules": [ 2541 { 2542 "type": "apMatchRule", 2543 "end": 0, 2544 "id": 0, 2545 "matchURL": null, 2546 "matches": [ 2547 { 2548 "caseSensitive": true, 2549 "matchOperator": "equals", 2550 "matchType": "method", 2551 "negate": false, 2552 "objectMatchValue": { 2553 "type": "simple", 2554 "value": [ 2555 "GET" 2556 ] 2557 } 2558 } 2559 ], 2560 "name": "rul3", 2561 "start": 0, 2562 "useIncomingQueryString": false, 2563 "passThroughPercent": -1 2564 } 2565 ], 2566 "policyId": 276858, 2567 "version": 6 2568 }`, 2569 expectedPath: "/cloudlets/v3/policies/276858/versions", 2570 expectedResponse: &PolicyVersion{ 2571 CreatedDate: *newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 2572 CreatedBy: "jsmith", 2573 Description: nil, 2574 ModifiedBy: "jsmith", 2575 ModifiedDate: newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 2576 PolicyID: 276858, 2577 PolicyVersion: 6, 2578 MatchRules: MatchRules{ 2579 &MatchRuleAP{ 2580 Type: "apMatchRule", 2581 End: 0, 2582 ID: 0, 2583 MatchURL: "", 2584 Name: "rul3", 2585 PassThroughPercent: tools.Float64Ptr(-1), 2586 Start: 0, 2587 Matches: []MatchCriteriaAP{ 2588 { 2589 CaseSensitive: true, 2590 MatchOperator: "equals", 2591 MatchType: "method", 2592 Negate: false, 2593 ObjectMatchValue: &ObjectMatchValueSimple{ 2594 Type: "simple", 2595 Value: []string{"GET"}, 2596 }, 2597 }, 2598 }, 2599 }, 2600 }, 2601 }, 2602 }, 2603 "201 created, complex AP with objectMatchValue - object": { 2604 request: CreatePolicyVersionRequest{ 2605 CreatePolicyVersion: CreatePolicyVersion{ 2606 MatchRules: MatchRules{ 2607 &MatchRuleAP{ 2608 Start: 0, 2609 End: 0, 2610 Type: "apMatchRule", 2611 Name: "rul3", 2612 PassThroughPercent: tools.Float64Ptr(-1), 2613 ID: 0, 2614 Matches: []MatchCriteriaAP{ 2615 { 2616 CaseSensitive: false, 2617 MatchOperator: "equals", 2618 MatchType: "header", 2619 Negate: false, 2620 ObjectMatchValue: &ObjectMatchValueObject{ 2621 Type: "object", 2622 Name: "AP", 2623 Options: &Options{ 2624 Value: []string{"y"}, 2625 ValueHasWildcard: true, 2626 }, 2627 }, 2628 }, 2629 }, 2630 }, 2631 }, 2632 }, 2633 PolicyID: 276858, 2634 }, 2635 responseStatus: http.StatusCreated, 2636 responseBody: `{ 2637 "createdDate": "2023-10-19T08:50:47.350Z", 2638 "createdBy": "jsmith", 2639 "description": null, 2640 "modifiedBy": "jsmith", 2641 "modifiedDate": null, 2642 "matchRules": [ 2643 { 2644 "type": "apMatchRule", 2645 "end": 0, 2646 "id": 0, 2647 "matchURL": null, 2648 "matches": [ 2649 { 2650 "caseSensitive": false, 2651 "matchOperator": "equals", 2652 "matchType": "header", 2653 "negate": false, 2654 "objectMatchValue": { 2655 "type": "object", 2656 "name": "AP", 2657 "options": { 2658 "value": [ 2659 "y" 2660 ], 2661 "valueHasWildcard": true 2662 } 2663 } 2664 } 2665 ], 2666 "name": "rul3", 2667 "start": 0, 2668 "passThroughPercent": -1 2669 } 2670 ], 2671 "policyId": 276858, 2672 "version": 6 2673 }`, 2674 expectedPath: "/cloudlets/v3/policies/276858/versions", 2675 expectedResponse: &PolicyVersion{ 2676 CreatedDate: *newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 2677 CreatedBy: "jsmith", 2678 Description: nil, 2679 ModifiedBy: "jsmith", 2680 ModifiedDate: nil, 2681 PolicyID: 276858, 2682 PolicyVersion: 6, 2683 MatchRules: MatchRules{ 2684 &MatchRuleAP{ 2685 Type: "apMatchRule", 2686 End: 0, 2687 ID: 0, 2688 MatchURL: "", 2689 Name: "rul3", 2690 PassThroughPercent: tools.Float64Ptr(-1), 2691 Start: 0, 2692 Matches: []MatchCriteriaAP{ 2693 { 2694 CaseSensitive: false, 2695 MatchOperator: "equals", 2696 MatchType: "header", 2697 Negate: false, 2698 ObjectMatchValue: &ObjectMatchValueObject{ 2699 Type: "object", 2700 Name: "AP", 2701 Options: &Options{ 2702 Value: []string{"y"}, 2703 ValueHasWildcard: true, 2704 }, 2705 }, 2706 }, 2707 }, 2708 }, 2709 }, 2710 }, 2711 }, 2712 "201 created, complex RC": { 2713 request: CreatePolicyVersionRequest{ 2714 CreatePolicyVersion: CreatePolicyVersion{ 2715 MatchRules: MatchRules{ 2716 &MatchRuleRC{ 2717 Start: 0, 2718 End: 0, 2719 Type: "igMatchRule", 2720 Name: "rul3", 2721 AllowDeny: DenyBranded, 2722 ID: 0, 2723 Matches: []MatchCriteriaRC{ 2724 { 2725 CaseSensitive: false, 2726 MatchOperator: "equals", 2727 MatchType: "protocol", 2728 MatchValue: "https", 2729 Negate: false, 2730 }, 2731 { 2732 CaseSensitive: true, 2733 MatchOperator: "equals", 2734 MatchType: "method", 2735 Negate: false, 2736 ObjectMatchValue: &ObjectMatchValueSimple{ 2737 Type: "simple", 2738 Value: []string{"GET"}, 2739 }, 2740 }, 2741 { 2742 MatchOperator: "equals", 2743 MatchType: "header", 2744 Negate: false, 2745 ObjectMatchValue: &ObjectMatchValueObject{ 2746 Type: "object", 2747 Name: "RC", 2748 Options: &Options{ 2749 Value: []string{ 2750 "text/html*", 2751 "text/css*", 2752 "application/x-javascript*", 2753 }, 2754 ValueHasWildcard: true, 2755 }, 2756 }, 2757 }, 2758 }, 2759 }, 2760 }, 2761 }, 2762 PolicyID: 276858, 2763 }, 2764 responseStatus: http.StatusCreated, 2765 responseBody: `{ 2766 "createdDate": "2023-10-19T08:50:47.350Z", 2767 "createdBy": "jsmith", 2768 "description": null, 2769 "modifiedBy": "jsmith", 2770 "modifiedDate": "2023-10-19T08:50:47.350Z", 2771 "matchRules": [ 2772 { 2773 "type": "igMatchRule", 2774 "end": 0, 2775 "id": 0, 2776 "matchesAlways": false, 2777 "matches": [ 2778 { 2779 "caseSensitive": false, 2780 "matchOperator": "equals", 2781 "matchType": "protocol", 2782 "negate": false, 2783 "matchValue": "https" 2784 }, 2785 { 2786 "caseSensitive": true, 2787 "matchOperator": "equals", 2788 "matchType": "method", 2789 "negate": false, 2790 "objectMatchValue": { 2791 "type": "simple", 2792 "value": [ 2793 "GET" 2794 ] 2795 } 2796 }, 2797 { 2798 "matchOperator": "equals", 2799 "matchType": "header", 2800 "negate": false, 2801 "objectMatchValue": { 2802 "type": "object", 2803 "name": "RC", 2804 "options": { 2805 "value": [ 2806 "text/html*", 2807 "text/css*", 2808 "application/x-javascript*" 2809 ], 2810 "valueHasWildcard": true 2811 } 2812 } 2813 } 2814 ], 2815 "name": "rul3", 2816 "start": 0, 2817 "allowDeny": "denybranded" 2818 } 2819 ], 2820 "policyId": 276858, 2821 "version": 6 2822 }`, 2823 expectedPath: "/cloudlets/v3/policies/276858/versions", 2824 expectedResponse: &PolicyVersion{ 2825 CreatedDate: *newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 2826 CreatedBy: "jsmith", 2827 Description: nil, 2828 ModifiedBy: "jsmith", 2829 ModifiedDate: newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 2830 PolicyID: 276858, 2831 PolicyVersion: 6, 2832 MatchRules: MatchRules{ 2833 &MatchRuleRC{ 2834 Type: "igMatchRule", 2835 End: 0, 2836 ID: 0, 2837 MatchesAlways: false, 2838 Name: "rul3", 2839 AllowDeny: DenyBranded, 2840 Start: 0, 2841 Matches: []MatchCriteriaRC{ 2842 { 2843 CaseSensitive: false, 2844 MatchOperator: "equals", 2845 MatchType: "protocol", 2846 MatchValue: "https", 2847 Negate: false, 2848 }, 2849 { 2850 CaseSensitive: true, 2851 MatchOperator: "equals", 2852 MatchType: "method", 2853 Negate: false, 2854 ObjectMatchValue: &ObjectMatchValueSimple{ 2855 Type: "simple", 2856 Value: []string{"GET"}, 2857 }, 2858 }, 2859 { 2860 MatchOperator: "equals", 2861 MatchType: "header", 2862 Negate: false, 2863 ObjectMatchValue: &ObjectMatchValueObject{ 2864 Type: "object", 2865 Name: "RC", 2866 Options: &Options{ 2867 Value: []string{ 2868 "text/html*", 2869 "text/css*", 2870 "application/x-javascript*", 2871 }, 2872 ValueHasWildcard: true, 2873 }, 2874 }, 2875 }, 2876 }, 2877 }, 2878 }, 2879 }, 2880 }, 2881 "validation error, complex RC with unavailable objectMatchValue type - range": { 2882 request: CreatePolicyVersionRequest{ 2883 CreatePolicyVersion: CreatePolicyVersion{ 2884 MatchRules: MatchRules{ 2885 &MatchRuleRC{ 2886 Start: 0, 2887 End: 0, 2888 Type: "igMatchRule", 2889 AllowDeny: Allow, 2890 Name: "rul3", 2891 ID: 0, 2892 Matches: []MatchCriteriaRC{ 2893 { 2894 MatchOperator: "equals", 2895 MatchType: "header", 2896 Negate: false, 2897 ObjectMatchValue: &ObjectMatchValueRange{ 2898 Type: "range", 2899 Value: []int64{1, 50}, 2900 }, 2901 }, 2902 }, 2903 }, 2904 }, 2905 }, 2906 PolicyID: 276858, 2907 }, 2908 withError: ErrStructValidation, 2909 }, 2910 "validation error, complex AP with unavailable objectMatchValue type - range": { 2911 request: CreatePolicyVersionRequest{ 2912 CreatePolicyVersion: CreatePolicyVersion{ 2913 MatchRules: MatchRules{ 2914 &MatchRuleAP{ 2915 Start: 0, 2916 End: 0, 2917 Type: "apMatchRule", 2918 PassThroughPercent: tools.Float64Ptr(50.50), 2919 Name: "rul3", 2920 ID: 0, 2921 Matches: []MatchCriteriaAP{ 2922 { 2923 MatchOperator: "equals", 2924 MatchType: "header", 2925 Negate: false, 2926 ObjectMatchValue: &ObjectMatchValueRange{ 2927 Type: "range", 2928 Value: []int64{1, 50}, 2929 }, 2930 }, 2931 }, 2932 }, 2933 }, 2934 }, 2935 PolicyID: 276858, 2936 }, 2937 withError: ErrStructValidation, 2938 }, 2939 2940 "validation error, simple RC missing allowDeny": { 2941 request: CreatePolicyVersionRequest{ 2942 CreatePolicyVersion: CreatePolicyVersion{ 2943 MatchRules: MatchRules{ 2944 &MatchRuleRC{ 2945 Start: 0, 2946 End: 0, 2947 Type: "igMatchRule", 2948 Name: "rul3", 2949 ID: 0, 2950 }, 2951 }, 2952 }, 2953 PolicyID: 276858, 2954 }, 2955 withError: ErrStructValidation, 2956 }, 2957 2958 "validation error, simple AP missing passThrughPercent": { 2959 request: CreatePolicyVersionRequest{ 2960 CreatePolicyVersion: CreatePolicyVersion{ 2961 MatchRules: MatchRules{ 2962 &MatchRuleAP{ 2963 Start: 0, 2964 End: 0, 2965 Type: "apMatchRule", 2966 Name: "rul3", 2967 ID: 0, 2968 }, 2969 }, 2970 }, 2971 PolicyID: 276858, 2972 }, 2973 withError: ErrStructValidation, 2974 }, 2975 2976 "validation error, simple AP passThroughPercent out of range": { 2977 request: CreatePolicyVersionRequest{ 2978 CreatePolicyVersion: CreatePolicyVersion{ 2979 MatchRules: MatchRules{ 2980 &MatchRuleAP{ 2981 Start: 0, 2982 End: 0, 2983 Type: "apMatchRule", 2984 PassThroughPercent: tools.Float64Ptr(101), 2985 Name: "rul3", 2986 ID: 0, 2987 }, 2988 }, 2989 }, 2990 PolicyID: 276858, 2991 }, 2992 withError: ErrStructValidation, 2993 }, 2994 2995 "500 internal server error": { 2996 request: CreatePolicyVersionRequest{ 2997 PolicyID: 1, 2998 }, 2999 responseStatus: http.StatusInternalServerError, 3000 responseBody: ` 3001 { 3002 "type": "internal_error", 3003 "title": "Internal Server Error", 3004 "status": 500 3005 }`, 3006 expectedPath: "/cloudlets/v3/policies/1/versions", 3007 withError: &Error{ 3008 Type: "internal_error", 3009 Title: "Internal Server Error", 3010 Status: http.StatusInternalServerError, 3011 }, 3012 }, 3013 } 3014 3015 for name, test := range tests { 3016 name, test := name, test 3017 t.Run(name, func(t *testing.T) { 3018 t.Parallel() 3019 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 3020 assert.Equal(t, test.expectedPath, r.URL.String()) 3021 assert.Equal(t, http.MethodPost, r.Method) 3022 if test.requestBody != "" { 3023 buf := new(bytes.Buffer) 3024 _, err := buf.ReadFrom(r.Body) 3025 assert.NoError(t, err) 3026 req := buf.String() 3027 assert.Equal(t, test.requestBody, req) 3028 } 3029 w.WriteHeader(test.responseStatus) 3030 _, err := w.Write([]byte(test.responseBody)) 3031 assert.NoError(t, err) 3032 })) 3033 client := mockAPIClient(t, mockServer) 3034 result, err := client.CreatePolicyVersion(context.Background(), test.request) 3035 if test.withError != nil { 3036 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 3037 return 3038 } 3039 require.NoError(t, err) 3040 assert.Equal(t, test.expectedResponse, result) 3041 }) 3042 } 3043 } 3044 3045 func TestDeletePolicyVersion(t *testing.T) { 3046 t.Parallel() 3047 tests := map[string]struct { 3048 request DeletePolicyVersionRequest 3049 responseStatus int 3050 responseBody string 3051 expectedPath string 3052 withError error 3053 }{ 3054 "204 no content": { 3055 request: DeletePolicyVersionRequest{ 3056 PolicyID: 276858, 3057 PolicyVersion: 5, 3058 }, 3059 responseStatus: http.StatusNoContent, 3060 responseBody: "", 3061 expectedPath: "/cloudlets/v3/policies/276858/versions/5", 3062 }, 3063 3064 "missing required fields": { 3065 request: DeletePolicyVersionRequest{}, 3066 withError: ErrStructValidation, 3067 }, 3068 3069 "500 internal server error": { 3070 request: DeletePolicyVersionRequest{ 3071 PolicyID: 1, 3072 PolicyVersion: 2, 3073 }, 3074 responseStatus: http.StatusInternalServerError, 3075 responseBody: ` 3076 { 3077 "type": "internal_error", 3078 "title": "Internal Server Error", 3079 "status": 500 3080 }`, 3081 expectedPath: "/cloudlets/v3/policies/1/versions/2", 3082 withError: &Error{ 3083 Type: "internal_error", 3084 Title: "Internal Server Error", 3085 Status: http.StatusInternalServerError, 3086 }, 3087 }, 3088 } 3089 3090 for name, test := range tests { 3091 name, test := name, test 3092 t.Run(name, func(t *testing.T) { 3093 t.Parallel() 3094 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 3095 assert.Equal(t, test.expectedPath, r.URL.String()) 3096 assert.Equal(t, http.MethodDelete, r.Method) 3097 w.WriteHeader(test.responseStatus) 3098 _, err := w.Write([]byte(test.responseBody)) 3099 assert.NoError(t, err) 3100 })) 3101 client := mockAPIClient(t, mockServer) 3102 err := client.DeletePolicyVersion(context.Background(), test.request) 3103 if test.withError != nil { 3104 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 3105 return 3106 } 3107 require.NoError(t, err) 3108 }) 3109 } 3110 } 3111 3112 func TestUpdatePolicyVersion(t *testing.T) { 3113 t.Parallel() 3114 tests := map[string]struct { 3115 request UpdatePolicyVersionRequest 3116 requestBody string 3117 responseStatus int 3118 responseBody string 3119 expectedPath string 3120 expectedResponse *PolicyVersion 3121 withError error 3122 }{ 3123 "201 updated simple ER": { 3124 request: UpdatePolicyVersionRequest{ 3125 UpdatePolicyVersion: UpdatePolicyVersion{ 3126 Description: tools.StringPtr("Updated description"), 3127 }, 3128 PolicyID: 276858, 3129 PolicyVersion: 5, 3130 }, 3131 responseStatus: http.StatusOK, 3132 responseBody: ` 3133 { 3134 "createdDate": "2023-10-19T08:50:47.350Z", 3135 "createdBy": "jsmith", 3136 "description": "Updated description", 3137 "modifiedBy": "jsmith", 3138 "modifiedDate": "2023-10-19T08:50:47.350Z", 3139 "matchRules": null, 3140 "policyId": 276858, 3141 "version": 5 3142 }`, 3143 expectedPath: "/cloudlets/v3/policies/276858/versions/5", 3144 expectedResponse: &PolicyVersion{ 3145 CreatedDate: *newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 3146 CreatedBy: "jsmith", 3147 Description: tools.StringPtr("Updated description"), 3148 ModifiedBy: "jsmith", 3149 ModifiedDate: newTimeFromString(t, "2023-10-19T08:50:47.350Z"), 3150 MatchRules: nil, 3151 PolicyID: 276858, 3152 PolicyVersion: 5, 3153 }, 3154 }, 3155 "201 updated simple ER with warnings": { 3156 request: UpdatePolicyVersionRequest{ 3157 UpdatePolicyVersion: UpdatePolicyVersion{ 3158 Description: tools.StringPtr("Updated description"), 3159 MatchRules: MatchRules{ 3160 &MatchRuleER{ 3161 Name: "er_rule", 3162 Type: "erMatchRule", 3163 Matches: []MatchCriteriaER{}, 3164 MatchesAlways: false, 3165 StatusCode: 301, 3166 RedirectURL: "/path", 3167 }, 3168 }, 3169 }, 3170 PolicyID: 276858, 3171 PolicyVersion: 5, 3172 }, 3173 requestBody: ` 3174 { 3175 "description": "Updated description", 3176 "id": 276858, 3177 "matchRules": [ 3178 { 3179 "type": "erMatchRule", 3180 "name": "er_rule", 3181 "matchURL": null, 3182 "statusCode": 301, 3183 "redirectURL": "/path", 3184 "useIncomingQueryString": false 3185 } 3186 ] 3187 }`, 3188 responseStatus: http.StatusOK, 3189 responseBody: ` 3190 { 3191 "createdBy": "jsmith", 3192 "createdDate": "2023-10-20T09:21:04.180Z", 3193 "description": "Updated description", 3194 "id": 6552305, 3195 "immutable": false, 3196 "matchRules": [ 3197 { 3198 "type": "erMatchRule", 3199 "id": 0, 3200 "name": "er_rule", 3201 "start": 0, 3202 "end": 0, 3203 "matchURL": null, 3204 "statusCode": 301, 3205 "redirectURL": "/path", 3206 "useIncomingQueryString": false 3207 } 3208 ], 3209 "matchRulesWarnings": [ 3210 { 3211 "detail": "No match match conditions.", 3212 "title": "Missing Match Criteria", 3213 "type": "/cloudlets/error-types/missing-match-criteria", 3214 "jsonPointer": "/matchRules/0" 3215 } 3216 ], 3217 "modifiedBy": "jsmith", 3218 "modifiedDate": "2023-10-20T10:32:56.316Z", 3219 "policyId": 670831, 3220 "version": 3 3221 }`, 3222 expectedPath: "/cloudlets/v3/policies/276858/versions/5", 3223 expectedResponse: &PolicyVersion{ 3224 CreatedDate: *newTimeFromString(t, "2023-10-20T09:21:04.180Z"), 3225 CreatedBy: "jsmith", 3226 Description: tools.StringPtr("Updated description"), 3227 ModifiedBy: "jsmith", 3228 ModifiedDate: newTimeFromString(t, "2023-10-20T10:32:56.316Z"), 3229 ID: 6552305, 3230 MatchRules: MatchRules{ 3231 &MatchRuleER{ 3232 Name: "er_rule", 3233 Type: "erMatchRule", 3234 MatchesAlways: false, 3235 StatusCode: 301, 3236 RedirectURL: "/path", 3237 }, 3238 }, 3239 PolicyID: 670831, 3240 PolicyVersion: 3, 3241 MatchRulesWarnings: []MatchRulesWarning{ 3242 { 3243 Detail: "No match match conditions.", 3244 Title: "Missing Match Criteria", 3245 Type: "/cloudlets/error-types/missing-match-criteria", 3246 JSONPointer: "/matchRules/0", 3247 }, 3248 }, 3249 }, 3250 }, 3251 "500 internal server error": { 3252 request: UpdatePolicyVersionRequest{ 3253 PolicyID: 276858, 3254 PolicyVersion: 3, 3255 }, 3256 responseStatus: http.StatusInternalServerError, 3257 responseBody: ` 3258 { 3259 "type": "internal_error", 3260 "title": "Internal Server Error", 3261 "status": 500 3262 }`, 3263 expectedPath: "/cloudlets/v3/policies/276858/versions/3", 3264 withError: &Error{ 3265 Type: "internal_error", 3266 Title: "Internal Server Error", 3267 Status: http.StatusInternalServerError, 3268 }, 3269 }, 3270 "validation error": { 3271 expectedPath: "/cloudlets/v3/policies/0", 3272 request: UpdatePolicyVersionRequest{ 3273 UpdatePolicyVersion: UpdatePolicyVersion{ 3274 Description: tools.StringPtr(strings.Repeat("A", 256)), 3275 }, 3276 }, 3277 withError: ErrStructValidation, 3278 }, 3279 } 3280 3281 for name, test := range tests { 3282 name, test := name, test 3283 t.Run(name, func(t *testing.T) { 3284 t.Parallel() 3285 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 3286 assert.Equal(t, test.expectedPath, r.URL.String()) 3287 assert.Equal(t, http.MethodPut, r.Method) 3288 w.WriteHeader(test.responseStatus) 3289 _, err := w.Write([]byte(test.responseBody)) 3290 assert.NoError(t, err) 3291 })) 3292 client := mockAPIClient(t, mockServer) 3293 result, err := client.UpdatePolicyVersion(context.Background(), test.request) 3294 if test.withError != nil { 3295 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 3296 return 3297 } 3298 require.NoError(t, err) 3299 assert.Equal(t, test.expectedResponse, result) 3300 }) 3301 } 3302 }