github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/cloudlets/match_rule_test.go (about) 1 package cloudlets 2 3 import ( 4 "encoding/json" 5 "errors" 6 "strings" 7 "testing" 8 9 "github.com/stretchr/testify/require" 10 "github.com/tj/assert" 11 12 "github.com/akamai/AkamaiOPEN-edgegrid-golang/v8/pkg/tools" 13 ) 14 15 func TestUnmarshalJSONMatchRules(t *testing.T) { 16 tests := map[string]struct { 17 withError error 18 responseBody string 19 expectedObject MatchRules 20 }{ 21 "valid MatchRuleALB": { 22 responseBody: ` 23 [ 24 { 25 "type": "albMatchRule", 26 "end": 0, 27 "forwardSettings": { 28 "originId": "alb_test_krk_dc1_only" 29 }, 30 "id": 0, 31 "matchURL": null, 32 "matches": [ 33 { 34 "caseSensitive": false, 35 "matchOperator": "equals", 36 "matchType": "protocol", 37 "matchValue": "https", 38 "negate": false 39 }, 40 { 41 "caseSensitive": false, 42 "matchOperator": "equals", 43 "matchType": "range", 44 "negate": false, 45 "objectMatchValue": { 46 "type": "range", 47 "value": [ 48 1, 49 50 50 ] 51 } 52 }, 53 { 54 "caseSensitive": false, 55 "matchOperator": "equals", 56 "matchType": "method", 57 "negate": false, 58 "objectMatchValue": { 59 "type": "simple", 60 "value": [ 61 "GET" 62 ] 63 } 64 } 65 ], 66 "name": "Rule3", 67 "start": 0 68 } 69 ] 70 `, 71 expectedObject: MatchRules{ 72 &MatchRuleALB{ 73 Type: "albMatchRule", 74 End: 0, 75 ForwardSettings: ForwardSettingsALB{ 76 OriginID: "alb_test_krk_dc1_only", 77 }, 78 ID: 0, 79 MatchURL: "", 80 Matches: []MatchCriteriaALB{ 81 { 82 CaseSensitive: false, 83 MatchOperator: "equals", 84 MatchType: "protocol", 85 MatchValue: "https", 86 Negate: false, 87 }, 88 { 89 CaseSensitive: false, 90 MatchOperator: "equals", 91 MatchType: "range", 92 Negate: false, 93 ObjectMatchValue: &ObjectMatchValueRange{ 94 Type: "range", 95 Value: []int64{1, 50}, 96 }, 97 }, 98 { 99 CaseSensitive: false, 100 MatchOperator: "equals", 101 MatchType: "method", 102 Negate: false, 103 ObjectMatchValue: &ObjectMatchValueSimple{ 104 Type: "simple", 105 Value: []string{"GET"}, 106 }, 107 }, 108 }, 109 Name: "Rule3", 110 Start: 0, 111 }, 112 }, 113 }, 114 115 "invalid objectMatchValue type for ALB - foo": { 116 withError: errors.New("unmarshalling MatchRules: unmarshalling MatchCriteriaALB: objectMatchValue has unexpected type: 'foo'"), 117 responseBody: ` 118 [ 119 { 120 "type": "albMatchRule", 121 "matches": [ 122 { 123 "caseSensitive": false, 124 "matchOperator": "equals", 125 "matchType": "method", 126 "negate": false, 127 "objectMatchValue": { 128 "type": "foo", 129 "value": [ 130 "GET" 131 ] 132 } 133 } 134 ], 135 "name": "Rule3", 136 "start": 0 137 } 138 ] 139 `, 140 }, 141 142 "wrong type for object value type": { 143 withError: errors.New("unmarshalling MatchRules: unmarshalling MatchCriteriaALB: 'type' should be a string"), 144 responseBody: ` 145 [ 146 { 147 "type": "albMatchRule", 148 "matches": [ 149 { 150 "caseSensitive": false, 151 "matchOperator": "equals", 152 "matchType": "method", 153 "negate": false, 154 "objectMatchValue": { 155 "type": 1, 156 "value": [ 157 "GET" 158 ] 159 } 160 } 161 ], 162 "name": "Rule3", 163 "start": 0 164 } 165 ] 166 `, 167 }, 168 169 "missing object value type": { 170 withError: errors.New("unmarshalling MatchRules: unmarshalling MatchCriteriaALB: objectMatchValue should contain 'type' field"), 171 responseBody: ` 172 [ 173 { 174 "type": "albMatchRule", 175 "matches": [ 176 { 177 "caseSensitive": false, 178 "matchOperator": "equals", 179 "matchType": "method", 180 "negate": false, 181 "objectMatchValue": { 182 "value": [ 183 "GET" 184 ] 185 } 186 } 187 ], 188 "name": "Rule3", 189 "start": 0 190 } 191 ] 192 `, 193 }, 194 195 "invalid object value": { 196 withError: errors.New("unmarshalling MatchRules: unmarshalling MatchCriteriaALB: structure of objectMatchValue should be 'map', but was 'string'"), 197 responseBody: ` 198 [ 199 { 200 "type": "albMatchRule", 201 "matches": [ 202 { 203 "caseSensitive": false, 204 "matchOperator": "equals", 205 "matchType": "method", 206 "negate": false, 207 "objectMatchValue": "" 208 } 209 ], 210 "name": "Rule3", 211 "start": 0 212 } 213 ] 214 `, 215 }, 216 217 "invalid MatchRuleXX": { 218 responseBody: ` 219 [ 220 { 221 "type": "xxMatchRule" 222 } 223 ] 224 `, 225 withError: errors.New("unmarshalling MatchRules: unsupported match rule type: xxMatchRule"), 226 }, 227 228 "invalid type": { 229 withError: errors.New("unmarshalling MatchRules: 'type' field on match rule entry should be a string"), 230 responseBody: ` 231 [ 232 { 233 "type": 1 234 } 235 ] 236 `, 237 }, 238 239 "invalid JSON": { 240 withError: errors.New("unexpected end of JSON input"), 241 responseBody: ` 242 [ 243 { 244 "type": "albMatchRule" 245 } 246 247 `, 248 }, 249 250 "missing type": { 251 withError: errors.New("unmarshalling MatchRules: match rule entry should contain 'type' field"), 252 responseBody: ` 253 [ 254 { 255 } 256 ] 257 `, 258 }, 259 260 "invalid objectMatchValue type for PR - range": { 261 withError: errors.New("unmarshalling MatchRules: unmarshalling MatchCriteriaPR: objectMatchValue has unexpected type: 'range'"), 262 responseBody: ` 263 [ 264 { 265 "type": "cdMatchRule", 266 "matches": [ 267 { 268 "caseSensitive": false, 269 "matchOperator": "equals", 270 "matchType": "method", 271 "negate": false, 272 "objectMatchValue": { 273 "type": "range", 274 "value": [ 275 1, 276 50 277 ] 278 } 279 } 280 ], 281 "name": "Rule3", 282 "start": 0 283 } 284 ] 285 `, 286 }, 287 288 "invalid objectMatchValue type for ER - range": { 289 withError: errors.New("unmarshalling MatchRules: unmarshalling MatchCriteriaER: objectMatchValue has unexpected type: 'range'"), 290 responseBody: ` 291 [ 292 { 293 "type": "erMatchRule", 294 "matches": [ 295 { 296 "caseSensitive": false, 297 "matchOperator": "equals", 298 "matchType": "method", 299 "negate": false, 300 "objectMatchValue": { 301 "type": "range", 302 "value": [ 303 1, 304 50 305 ] 306 } 307 } 308 ], 309 "name": "Rule3", 310 "start": 0 311 } 312 ] 313 `, 314 }, 315 316 "invalid objectMatchValue type for FR - range": { 317 withError: errors.New("unmarshalling MatchRules: unmarshalling MatchCriteriaFR: objectMatchValue has unexpected type: 'range'"), 318 responseBody: ` 319 [ 320 { 321 "type": "frMatchRule", 322 "matches": [ 323 { 324 "caseSensitive": false, 325 "matchOperator": "equals", 326 "matchType": "method", 327 "negate": false, 328 "objectMatchValue": { 329 "type": "range", 330 "value": [ 331 1, 332 50 333 ] 334 } 335 } 336 ], 337 "name": "Rule3", 338 "start": 0 339 } 340 ] 341 `, 342 }, 343 344 "valid MatchRulePR": { 345 responseBody: ` 346 [ 347 { 348 "type": "cdMatchRule", 349 "end": 0, 350 "id": 0, 351 "matchURL": null, 352 "forwardSettings": { 353 "originId": "fr_test_krk_dc2", 354 "percent": 62 355 }, 356 "matches": [ 357 { 358 "caseSensitive": false, 359 "matchOperator": "equals", 360 "matchType": "protocol", 361 "matchValue": "https", 362 "negate": false 363 }, 364 { 365 "caseSensitive": false, 366 "matchOperator": "equals", 367 "matchType": "method", 368 "negate": false, 369 "objectMatchValue": { 370 "type": "simple", 371 "value": [ 372 "GET" 373 ] 374 } 375 } 376 ], 377 "name": "Rule3", 378 "start": 0 379 } 380 ] 381 `, 382 expectedObject: MatchRules{ 383 &MatchRulePR{ 384 Type: "cdMatchRule", 385 End: 0, 386 ID: 0, 387 MatchURL: "", 388 Matches: []MatchCriteriaPR{ 389 { 390 CaseSensitive: false, 391 MatchOperator: "equals", 392 MatchType: "protocol", 393 MatchValue: "https", 394 Negate: false, 395 }, 396 { 397 CaseSensitive: false, 398 MatchOperator: "equals", 399 MatchType: "method", 400 Negate: false, 401 ObjectMatchValue: &ObjectMatchValueSimple{ 402 Type: "simple", 403 Value: []string{"GET"}, 404 }, 405 }, 406 }, 407 Name: "Rule3", 408 Start: 0, 409 ForwardSettings: ForwardSettingsPR{ 410 OriginID: "fr_test_krk_dc2", 411 Percent: 62, 412 }, 413 }, 414 }, 415 }, 416 417 "valid MatchRuleFR": { 418 responseBody: ` 419 [ 420 { 421 "type": "frMatchRule", 422 "end": 0, 423 "id": 0, 424 "matchURL": null, 425 "forwardSettings": {}, 426 "matches": [ 427 { 428 "caseSensitive": false, 429 "matchOperator": "equals", 430 "matchType": "protocol", 431 "matchValue": "https", 432 "negate": false 433 }, 434 { 435 "caseSensitive": false, 436 "matchOperator": "equals", 437 "matchType": "method", 438 "negate": false, 439 "objectMatchValue": { 440 "type": "simple", 441 "value": [ 442 "GET" 443 ] 444 } 445 } 446 ], 447 "name": "Rule3", 448 "start": 0 449 } 450 ] 451 `, 452 expectedObject: MatchRules{ 453 &MatchRuleFR{ 454 Type: "frMatchRule", 455 End: 0, 456 ID: 0, 457 MatchURL: "", 458 Matches: []MatchCriteriaFR{ 459 { 460 CaseSensitive: false, 461 MatchOperator: "equals", 462 MatchType: "protocol", 463 MatchValue: "https", 464 Negate: false, 465 }, 466 { 467 CaseSensitive: false, 468 MatchOperator: "equals", 469 MatchType: "method", 470 Negate: false, 471 ObjectMatchValue: &ObjectMatchValueSimple{ 472 Type: "simple", 473 Value: []string{"GET"}, 474 }, 475 }, 476 }, 477 Name: "Rule3", 478 Start: 0, 479 }, 480 }, 481 }, 482 483 "invalid objectMatchValue type for VP - range": { 484 withError: errors.New("unmarshalling MatchRules: unmarshalling MatchCriteriaVP: objectMatchValue has unexpected type: 'range'"), 485 responseBody: ` 486 [ 487 { 488 "type": "vpMatchRule", 489 "matches": [ 490 { 491 "caseSensitive": false, 492 "matchOperator": "equals", 493 "matchType": "method", 494 "negate": false, 495 "objectMatchValue": { 496 "type": "range", 497 "value": [ 498 1, 499 50 500 ] 501 } 502 } 503 ], 504 "name": "Rule3", 505 "start": 0 506 } 507 ] 508 `, 509 }, 510 "invalid objectMatchValue type for AP - range": { 511 withError: errors.New("unmarshalling MatchRules: unmarshalling MatchCriteriaAP: objectMatchValue has unexpected type: 'range'"), 512 responseBody: ` 513 [ 514 { 515 "type": "apMatchRule", 516 "matches": [ 517 { 518 "caseSensitive": false, 519 "matchOperator": "equals", 520 "matchType": "method", 521 "negate": false, 522 "objectMatchValue": { 523 "type": "range", 524 "value": [ 525 1, 526 50 527 ] 528 } 529 } 530 ], 531 "name": "Rule3", 532 "start": 0 533 } 534 ] 535 `, 536 }, 537 538 "valid MatchRuleVP": { 539 responseBody: ` 540 [ 541 { 542 "type": "vpMatchRule", 543 "end": 0, 544 "passThroughPercent": 50.50, 545 "id": 0, 546 "matchURL": null, 547 "matches": [ 548 { 549 "caseSensitive": false, 550 "matchOperator": "equals", 551 "matchType": "protocol", 552 "matchValue": "https", 553 "negate": false 554 }, 555 { 556 "caseSensitive": false, 557 "matchOperator": "equals", 558 "matchType": "method", 559 "negate": false, 560 "objectMatchValue": { 561 "type": "simple", 562 "value": [ 563 "GET" 564 ] 565 } 566 } 567 ], 568 "name": "Rule3", 569 "start": 0 570 } 571 ] 572 `, 573 expectedObject: MatchRules{ 574 &MatchRuleVP{ 575 Type: "vpMatchRule", 576 End: 0, 577 PassThroughPercent: tools.Float64Ptr(50.50), 578 ID: 0, 579 MatchURL: "", 580 Matches: []MatchCriteriaVP{ 581 { 582 CaseSensitive: false, 583 MatchOperator: "equals", 584 MatchType: "protocol", 585 MatchValue: "https", 586 Negate: false, 587 }, 588 { 589 CaseSensitive: false, 590 MatchOperator: "equals", 591 MatchType: "method", 592 Negate: false, 593 ObjectMatchValue: &ObjectMatchValueSimple{ 594 Type: "simple", 595 Value: []string{"GET"}, 596 }, 597 }, 598 }, 599 Name: "Rule3", 600 Start: 0, 601 }, 602 }, 603 }, 604 "valid MatchRuleAP": { 605 responseBody: ` 606 [ 607 { 608 "type": "apMatchRule", 609 "end": 0, 610 "passThroughPercent": 50.50, 611 "id": 0, 612 "matchURL": null, 613 "matches": [ 614 { 615 "caseSensitive": false, 616 "matchOperator": "equals", 617 "matchType": "protocol", 618 "matchValue": "https", 619 "negate": false 620 }, 621 { 622 "caseSensitive": false, 623 "matchOperator": "equals", 624 "matchType": "method", 625 "negate": false, 626 "objectMatchValue": { 627 "type": "simple", 628 "value": [ 629 "GET" 630 ] 631 } 632 } 633 ], 634 "name": "Rule3", 635 "start": 0 636 } 637 ] 638 `, 639 expectedObject: MatchRules{ 640 &MatchRuleAP{ 641 Type: "apMatchRule", 642 End: 0, 643 PassThroughPercent: tools.Float64Ptr(50.50), 644 ID: 0, 645 MatchURL: "", 646 Matches: []MatchCriteriaAP{ 647 { 648 CaseSensitive: false, 649 MatchOperator: "equals", 650 MatchType: "protocol", 651 MatchValue: "https", 652 Negate: false, 653 }, 654 { 655 CaseSensitive: false, 656 MatchOperator: "equals", 657 MatchType: "method", 658 Negate: false, 659 ObjectMatchValue: &ObjectMatchValueSimple{ 660 Type: "simple", 661 Value: []string{"GET"}, 662 }, 663 }, 664 }, 665 Name: "Rule3", 666 Start: 0, 667 }, 668 }, 669 }, 670 "valid MatchRuleAS": { 671 responseBody: ` 672 [ 673 { 674 "name": "rule 10", 675 "type": "asMatchRule", 676 "matchURL": "http://source.com/test1", 677 678 "forwardSettings": { 679 "originId": "origin_remote_1", 680 "pathAndQS": "/cpaths/test1.html" 681 }, 682 683 "matches": [ 684 { 685 "matchType": "range", 686 "objectMatchValue": { 687 "type": "range", 688 "value": [ 1, 100 ] 689 }, 690 "matchOperator": "equals", 691 "negate": false, 692 "caseSensitive": false 693 }, 694 { 695 "matchType": "header", 696 "objectMatchValue": { 697 "options": { 698 "value": [ "en" ] 699 }, 700 "type": "object", 701 "name": "Accept-Charset" 702 }, 703 "matchOperator": "equals", 704 "negate": false, 705 "caseSensitive": false 706 } 707 ] 708 } 709 ]`, 710 expectedObject: MatchRules{ 711 &MatchRuleAS{ 712 Name: "rule 10", 713 Type: "asMatchRule", 714 MatchURL: "http://source.com/test1", 715 ForwardSettings: ForwardSettingsAS{ 716 OriginID: "origin_remote_1", 717 PathAndQS: "/cpaths/test1.html", 718 }, 719 Matches: []MatchCriteriaAS{ 720 { 721 MatchType: "range", 722 ObjectMatchValue: &ObjectMatchValueRange{ 723 Type: "range", 724 Value: []int64{1, 100}, 725 }, 726 MatchOperator: "equals", 727 CaseSensitive: false, 728 Negate: false, 729 }, 730 { 731 MatchType: "header", 732 ObjectMatchValue: &ObjectMatchValueObject{ 733 Name: "Accept-Charset", 734 Type: "object", 735 Options: &Options{ 736 Value: []string{"en"}, 737 }, 738 }, 739 MatchOperator: "equals", 740 Negate: false, 741 CaseSensitive: false, 742 }, 743 }, 744 }, 745 }, 746 }, 747 748 "valid MatchRuleRC": { 749 responseBody: ` 750 [ 751 { 752 "type": "igMatchRule", 753 "end": 0, 754 "allowDeny": "allow", 755 "id": 0, 756 "matchURL": null, 757 "matches": [ 758 { 759 "caseSensitive": false, 760 "matchOperator": "equals", 761 "matchType": "protocol", 762 "matchValue": "https", 763 "negate": false 764 }, 765 { 766 "caseSensitive": false, 767 "matchOperator": "equals", 768 "matchType": "method", 769 "negate": false, 770 "objectMatchValue": { 771 "type": "simple", 772 "value": [ 773 "GET" 774 ] 775 } 776 } 777 ], 778 "name": "Rule3", 779 "start": 0 780 } 781 ]`, 782 expectedObject: MatchRules{ 783 &MatchRuleRC{ 784 Name: "Rule3", 785 Type: "igMatchRule", 786 AllowDeny: Allow, 787 Matches: []MatchCriteriaRC{ 788 { 789 CaseSensitive: false, 790 MatchOperator: "equals", 791 MatchType: "protocol", 792 MatchValue: "https", 793 Negate: false, 794 }, 795 { 796 CaseSensitive: false, 797 MatchOperator: "equals", 798 MatchType: "method", 799 Negate: false, 800 ObjectMatchValue: &ObjectMatchValueSimple{ 801 Type: "simple", 802 Value: []string{"GET"}, 803 }, 804 }, 805 }, 806 }, 807 }, 808 }, 809 810 "invalid objectMatchValue type for RC - range": { 811 withError: errors.New("unmarshalling MatchRules: unmarshalling MatchCriteriaRC: objectMatchValue has unexpected type: 'range'"), 812 responseBody: ` 813 [ 814 { 815 "type": "igMatchRule", 816 "allowDeny": "allow", 817 "matches": [ 818 { 819 "caseSensitive": false, 820 "matchOperator": "equals", 821 "matchType": "method", 822 "negate": false, 823 "objectMatchValue": { 824 "type": "range", 825 "value": [ 826 1, 827 50 828 ] 829 } 830 } 831 ], 832 "name": "Rule3", 833 "start": 0 834 } 835 ] 836 `, 837 }, 838 } 839 840 for name, test := range tests { 841 t.Run(name, func(t *testing.T) { 842 var matchRules MatchRules 843 err := json.Unmarshal([]byte(test.responseBody), &matchRules) 844 845 if test.withError != nil { 846 assert.Equal(t, test.withError.Error(), err.Error()) 847 return 848 } 849 require.NoError(t, err) 850 assert.Equal(t, test.expectedObject, matchRules) 851 }) 852 } 853 } 854 855 func TestGetObjectMatchValueType(t *testing.T) { 856 tests := map[string]struct { 857 withError error 858 input interface{} 859 expected string 860 }{ 861 "success getting objectMatchValue type": { 862 input: map[string]interface{}{ 863 "type": "range", 864 "value": []int{1, 50}, 865 }, 866 expected: "range", 867 }, 868 "error getting objectMatchValue type - invalid type": { 869 withError: errors.New("structure of objectMatchValue should be 'map', but was 'string'"), 870 input: "stringType", 871 }, 872 "error getting objectMatchValue type - missing type": { 873 withError: errors.New("objectMatchValue should contain 'type' field"), 874 input: map[string]interface{}{ 875 "value": []int{1, 50}, 876 }, 877 }, 878 "error getting objectMatchValue type - type not string": { 879 withError: errors.New("'type' should be a string"), 880 input: map[string]interface{}{ 881 "type": 50, 882 "value": []int{1, 50}, 883 }, 884 }, 885 } 886 887 for name, test := range tests { 888 t.Run(name, func(t *testing.T) { 889 objectMatchValueType, err := getObjectMatchValueType(test.input) 890 891 if test.withError != nil { 892 assert.Equal(t, test.withError.Error(), err.Error()) 893 return 894 } 895 require.NoError(t, err) 896 assert.Equal(t, test.expected, objectMatchValueType) 897 }) 898 } 899 } 900 901 func TestConvertObjectMatchValue(t *testing.T) { 902 tests := map[string]struct { 903 withError bool 904 input map[string]interface{} 905 output interface{} 906 expected interface{} 907 }{ 908 "success converting objectMatchValueRange": { 909 input: map[string]interface{}{ 910 "type": "range", 911 "value": []int{1, 50}, 912 }, 913 output: &ObjectMatchValueRange{}, 914 expected: &ObjectMatchValueRange{ 915 Type: "range", 916 Value: []int64{1, 50}, 917 }, 918 }, 919 "success converting objectMatchValueSimple": { 920 input: map[string]interface{}{ 921 "type": "simple", 922 "value": []string{"GET"}, 923 }, 924 output: &ObjectMatchValueSimple{}, 925 expected: &ObjectMatchValueSimple{ 926 Type: "simple", 927 Value: []string{"GET"}, 928 }, 929 }, 930 "success converting objectMatchValueObject": { 931 input: map[string]interface{}{ 932 "type": "object", 933 "name": "ER", 934 "options": map[string]interface{}{ 935 "value": []string{ 936 "text/html*", 937 "text/css*", 938 "application/x-javascript*", 939 }, 940 "valueHasWildcard": true, 941 }, 942 }, 943 output: &ObjectMatchValueObject{}, 944 expected: &ObjectMatchValueObject{ 945 Type: "object", 946 Name: "ER", 947 Options: &Options{ 948 Value: []string{ 949 "text/html*", 950 "text/css*", 951 "application/x-javascript*", 952 }, 953 ValueHasWildcard: true, 954 }, 955 }, 956 }, 957 "error converting objectMatchValue": { 958 withError: true, 959 input: map[string]interface{}{ 960 "type": "range", 961 "value": []int{1, 50}, 962 }, 963 output: &ObjectMatchValueSimple{}, 964 }, 965 } 966 967 for name, test := range tests { 968 t.Run(name, func(t *testing.T) { 969 convertedObjectMatchValue, err := convertObjectMatchValue(test.input, test.output) 970 971 if test.withError == true { 972 require.Error(t, err) 973 return 974 } 975 require.NoError(t, err) 976 assert.Equal(t, test.expected, convertedObjectMatchValue) 977 }) 978 } 979 } 980 981 func TestValidateMatchRules(t *testing.T) { 982 tests := map[string]struct { 983 input MatchRules 984 withError string 985 }{ 986 "valid match rules ALB": { 987 input: MatchRules{ 988 MatchRuleALB{ 989 Type: "albMatchRule", 990 ForwardSettings: ForwardSettingsALB{ 991 OriginID: "testOriginID", 992 }, 993 }, 994 MatchRuleALB{ 995 Type: "albMatchRule", 996 Start: 1, 997 End: 2, 998 ForwardSettings: ForwardSettingsALB{ 999 OriginID: "testOriginID", 1000 }, 1001 }, 1002 }, 1003 }, 1004 "invalid match rules ALB": { 1005 input: MatchRules{ 1006 MatchRuleALB{ 1007 Type: "matchRule", 1008 }, 1009 MatchRuleALB{ 1010 Type: "albMatchRule", 1011 Start: -1, 1012 End: -1, 1013 ForwardSettings: ForwardSettingsALB{ 1014 OriginID: "testOriginID", 1015 }, 1016 }, 1017 }, 1018 withError: ` 1019 MatchRules[0]: { 1020 ForwardSettings.OriginID: cannot be blank 1021 Type: value 'matchRule' is invalid. Must be: 'albMatchRule' 1022 } 1023 MatchRules[1]: { 1024 End: must be no less than 0 1025 Start: must be no less than 0 1026 }`, 1027 }, 1028 "valid match rules AP": { 1029 input: MatchRules{ 1030 MatchRuleAP{ 1031 Type: "apMatchRule", 1032 PassThroughPercent: tools.Float64Ptr(-1), 1033 }, 1034 MatchRuleAP{ 1035 Type: "apMatchRule", 1036 PassThroughPercent: tools.Float64Ptr(50.5), 1037 }, 1038 MatchRuleAP{ 1039 Type: "apMatchRule", 1040 PassThroughPercent: tools.Float64Ptr(0), 1041 }, 1042 MatchRuleAP{ 1043 Type: "apMatchRule", 1044 PassThroughPercent: tools.Float64Ptr(100), 1045 }, 1046 }, 1047 }, 1048 "invalid match rules AP": { 1049 input: MatchRules{ 1050 MatchRuleAP{ 1051 Type: "matchRule", 1052 }, 1053 MatchRuleAP{ 1054 Type: "apMatchRule", 1055 PassThroughPercent: tools.Float64Ptr(100.1), 1056 }, 1057 MatchRuleAP{ 1058 Type: "apMatchRule", 1059 PassThroughPercent: tools.Float64Ptr(-1.1), 1060 }, 1061 }, 1062 withError: ` 1063 MatchRules[0]: { 1064 PassThroughPercent: cannot be blank 1065 Type: value 'matchRule' is invalid. Must be: 'apMatchRule' 1066 } 1067 MatchRules[1]: { 1068 PassThroughPercent: must be no greater than 100 1069 } 1070 MatchRules[2]: { 1071 PassThroughPercent: must be no less than -1 1072 }`, 1073 }, 1074 "valid match rules AS": { 1075 input: MatchRules{ 1076 MatchRuleAS{ 1077 Type: "asMatchRule", 1078 Start: 0, 1079 End: 1, 1080 }, 1081 MatchRuleAS{ 1082 Type: "asMatchRule", 1083 ForwardSettings: ForwardSettingsAS{ 1084 PathAndQS: "something", 1085 OriginID: "something_else", 1086 }, 1087 }, 1088 }, 1089 }, 1090 "invalid match rules AS": { 1091 input: MatchRules{ 1092 MatchRuleAS{ 1093 Type: "matchRule", 1094 }, 1095 MatchRuleAS{ 1096 Type: "asMatchRule", 1097 Start: -2, 1098 End: -1, 1099 ForwardSettings: ForwardSettingsAS{ 1100 OriginID: "some_id", 1101 }, 1102 }, 1103 }, 1104 1105 withError: ` 1106 MatchRules[0]: { 1107 Type: value 'matchRule' is invalid. Must be: 'asMatchRule' 1108 } 1109 MatchRules[1]: { 1110 End: must be no less than 0 1111 Start: must be no less than 0 1112 }`, 1113 }, 1114 "valid match rules CD": { 1115 input: MatchRules{ 1116 MatchRulePR{ 1117 Type: "cdMatchRule", 1118 ForwardSettings: ForwardSettingsPR{ 1119 OriginID: "testOriginID", 1120 Percent: 100, 1121 }, 1122 }, 1123 MatchRulePR{ 1124 Type: "cdMatchRule", 1125 ForwardSettings: ForwardSettingsPR{ 1126 OriginID: "testOriginID", 1127 Percent: 1, 1128 }, 1129 }, 1130 }, 1131 }, 1132 "invalid match rules CD": { 1133 input: MatchRules{ 1134 MatchRulePR{ 1135 Type: "matchRule", 1136 }, 1137 MatchRulePR{ 1138 Type: "cdMatchRule", 1139 ForwardSettings: ForwardSettingsPR{}, 1140 }, 1141 MatchRulePR{ 1142 Type: "cdMatchRule", 1143 ForwardSettings: ForwardSettingsPR{ 1144 OriginID: "testOriginID", 1145 Percent: 101, 1146 }, 1147 }, 1148 MatchRulePR{ 1149 Type: "cdMatchRule", 1150 ForwardSettings: ForwardSettingsPR{ 1151 OriginID: "testOriginID", 1152 Percent: -1, 1153 }, 1154 }, 1155 MatchRulePR{ 1156 Type: "cdMatchRule", 1157 ForwardSettings: ForwardSettingsPR{ 1158 OriginID: "testOriginID", 1159 Percent: 0, 1160 }, 1161 }, 1162 }, 1163 withError: ` 1164 MatchRules[0]: { 1165 ForwardSettings.OriginID: cannot be blank 1166 ForwardSettings.Percent: cannot be blank 1167 Type: value 'matchRule' is invalid. Must be: 'cdMatchRule' 1168 } 1169 MatchRules[1]: { 1170 ForwardSettings.OriginID: cannot be blank 1171 ForwardSettings.Percent: cannot be blank 1172 } 1173 MatchRules[2]: { 1174 ForwardSettings.Percent: must be no greater than 100 1175 } 1176 MatchRules[3]: { 1177 ForwardSettings.Percent: must be no less than 1 1178 } 1179 MatchRules[4]: { 1180 ForwardSettings.Percent: cannot be blank 1181 }`, 1182 }, 1183 "valid match rules ER": { 1184 input: MatchRules{ 1185 MatchRuleER{ 1186 Type: "erMatchRule", 1187 RedirectURL: "abc.com", 1188 UseRelativeURL: "none", 1189 StatusCode: 301, 1190 }, 1191 MatchRuleER{ 1192 Type: "erMatchRule", 1193 RedirectURL: "abc.com", 1194 StatusCode: 301, 1195 }, 1196 MatchRuleER{ 1197 Type: "erMatchRule", 1198 RedirectURL: "abc.com", 1199 MatchesAlways: true, 1200 StatusCode: 301, 1201 }, 1202 MatchRuleER{ 1203 Type: "erMatchRule", 1204 RedirectURL: "abc.com", 1205 Matches: []MatchCriteriaER{ 1206 { 1207 MatchValue: "asd", 1208 }, 1209 }, 1210 StatusCode: 301, 1211 }, 1212 }, 1213 }, 1214 "invalid match rules ER": { 1215 input: MatchRules{ 1216 MatchRuleER{ 1217 Type: "matchRule", 1218 }, 1219 MatchRuleER{ 1220 Type: "erMatchRule", 1221 RedirectURL: "abc.com", 1222 UseRelativeURL: "test", 1223 StatusCode: 404, 1224 }, 1225 MatchRuleER{ 1226 Type: "erMatchRule", 1227 RedirectURL: "abc.com", 1228 UseRelativeURL: "none", 1229 StatusCode: 301, 1230 MatchesAlways: true, 1231 Matches: []MatchCriteriaER{ 1232 { 1233 MatchValue: "asd", 1234 }, 1235 }, 1236 }, 1237 }, 1238 withError: ` 1239 MatchRules[0]: { 1240 RedirectURL: cannot be blank 1241 StatusCode: cannot be blank 1242 Type: value 'matchRule' is invalid. Must be: 'erMatchRule' 1243 } 1244 MatchRules[1]: { 1245 StatusCode: value '404' is invalid. Must be one of: 301, 302, 303, 307 or 308 1246 UseRelativeURL: value 'test' is invalid. Must be one of: 'none', 'copy_scheme_hostname', 'relative_url' or '' (empty) 1247 } 1248 MatchRules[2]: { 1249 Matches/MatchesAlways: only one of [ "Matches", "MatchesAlways" ] can be specified 1250 }`, 1251 }, 1252 "valid match rules FR": { 1253 input: MatchRules{ 1254 MatchRuleFR{ 1255 Type: "frMatchRule", 1256 ForwardSettings: ForwardSettingsFR{ 1257 PathAndQS: "test", 1258 OriginID: "testOriginID", 1259 }, 1260 }, 1261 MatchRuleFR{ 1262 Type: "frMatchRule", 1263 ForwardSettings: ForwardSettingsFR{ 1264 PathAndQS: "test", 1265 OriginID: "testOriginID", 1266 }, 1267 }, 1268 }, 1269 }, 1270 "invalid match rules FR": { 1271 input: MatchRules{ 1272 MatchRuleFR{ 1273 Type: "matchRule", 1274 }, 1275 MatchRuleFR{ 1276 Type: "frMatchRule", 1277 ForwardSettings: ForwardSettingsFR{ 1278 OriginID: "testOriginID", 1279 PathAndQS: "", 1280 }, 1281 }, 1282 }, 1283 withError: ` 1284 MatchRules[0]: { 1285 Type: value 'matchRule' is invalid. Must be: 'frMatchRule' 1286 }`, 1287 }, 1288 "valid match rules RC": { 1289 input: MatchRules{ 1290 MatchRuleRC{ 1291 Type: "igMatchRule", 1292 AllowDeny: Allow, 1293 }, 1294 MatchRuleRC{ 1295 Type: "igMatchRule", 1296 AllowDeny: Deny, 1297 }, 1298 MatchRuleRC{ 1299 Type: "igMatchRule", 1300 AllowDeny: DenyBranded, 1301 }, 1302 }, 1303 }, 1304 "invalid match rules RC": { 1305 input: MatchRules{ 1306 MatchRuleRC{ 1307 Type: "invalidMatchRule", 1308 }, 1309 MatchRuleRC{ 1310 Type: "igMatchRule", 1311 AllowDeny: "allowBranded", 1312 }, 1313 MatchRuleRC{ 1314 Type: "igMatchRule", 1315 AllowDeny: Allow, 1316 MatchesAlways: true, 1317 Matches: []MatchCriteriaRC{ 1318 { 1319 CaseSensitive: false, 1320 CheckIPs: "CONNECTING_IP", 1321 MatchOperator: "equals", 1322 MatchType: "clientip", 1323 MatchValue: "1.2.3.4", 1324 Negate: false, 1325 }, 1326 }, 1327 }, 1328 }, 1329 withError: ` 1330 MatchRules[0]: { 1331 AllowDeny: cannot be blank 1332 Type: value 'invalidMatchRule' is invalid. Must be: 'igMatchRule' 1333 } 1334 MatchRules[1]: { 1335 AllowDeny: value 'allowBranded' is invalid. Must be one of: 'allow', 'deny' or 'denybranded' 1336 } 1337 MatchRules[2]: { 1338 Matches/MatchesAlways: only one of [ "Matches", "MatchesAlways" ] can be specified 1339 }`, 1340 }, 1341 "valid match rules VP": { 1342 input: MatchRules{ 1343 MatchRuleVP{ 1344 Type: "vpMatchRule", 1345 PassThroughPercent: tools.Float64Ptr(-1), 1346 }, 1347 MatchRuleVP{ 1348 Type: "vpMatchRule", 1349 PassThroughPercent: tools.Float64Ptr(50.5), 1350 }, 1351 MatchRuleVP{ 1352 Type: "vpMatchRule", 1353 PassThroughPercent: tools.Float64Ptr(0), 1354 }, 1355 MatchRuleVP{ 1356 Type: "vpMatchRule", 1357 PassThroughPercent: tools.Float64Ptr(100), 1358 }, 1359 }, 1360 }, 1361 "invalid match rules VP": { 1362 input: MatchRules{ 1363 MatchRuleVP{ 1364 Type: "matchRule", 1365 }, 1366 MatchRuleVP{ 1367 Type: "vpMatchRule", 1368 PassThroughPercent: tools.Float64Ptr(100.1), 1369 }, 1370 MatchRuleVP{ 1371 Type: "vpMatchRule", 1372 PassThroughPercent: tools.Float64Ptr(-1.1), 1373 }, 1374 }, 1375 withError: ` 1376 MatchRules[0]: { 1377 PassThroughPercent: cannot be blank 1378 Type: value 'matchRule' is invalid. Must be: 'vpMatchRule' 1379 } 1380 MatchRules[1]: { 1381 PassThroughPercent: must be no greater than 100 1382 } 1383 MatchRules[2]: { 1384 PassThroughPercent: must be no less than -1 1385 }`, 1386 }, 1387 "valid match criteria - matchValue": { 1388 input: MatchRules{ 1389 MatchRuleER{ 1390 Type: "erMatchRule", 1391 RedirectURL: "abc.com", 1392 StatusCode: 301, 1393 Matches: []MatchCriteriaER{ 1394 { 1395 MatchType: "method", 1396 MatchOperator: "equals", 1397 CheckIPs: "CONNECTING_IP", 1398 MatchValue: "https", 1399 }, 1400 }, 1401 }, 1402 }, 1403 }, 1404 "valid match criteria - object match value": { 1405 input: MatchRules{ 1406 MatchRuleER{ 1407 Type: "erMatchRule", 1408 RedirectURL: "abc.com", 1409 StatusCode: 301, 1410 Matches: []MatchCriteriaER{ 1411 { 1412 MatchType: "header", 1413 MatchOperator: "equals", 1414 CheckIPs: "CONNECTING_IP", 1415 ObjectMatchValue: &ObjectMatchValueSimple{ 1416 Type: "simple", 1417 Value: []string{ 1418 "GET", 1419 }, 1420 }, 1421 }, 1422 }, 1423 }, 1424 }, 1425 }, 1426 "invalid match criteria - matchValue and omv combinations": { 1427 input: MatchRules{ 1428 MatchRuleER{ 1429 Type: "erMatchRule", 1430 RedirectURL: "abc.com", 1431 StatusCode: 301, 1432 Matches: []MatchCriteriaER{ 1433 { 1434 MatchType: "header", 1435 MatchOperator: "equals", 1436 CheckIPs: "CONNECTING_IP", 1437 ObjectMatchValue: &ObjectMatchValueSimple{ 1438 Type: "simple", 1439 Value: []string{ 1440 "GET", 1441 }, 1442 }, 1443 MatchValue: "GET", 1444 }, 1445 { 1446 MatchType: "header", 1447 MatchOperator: "equals", 1448 CheckIPs: "CONNECTING_IP", 1449 }, 1450 }, 1451 }, 1452 }, 1453 withError: ` 1454 MatchRules[0]: { 1455 Matches[0]: { 1456 MatchValue: must be blank when ObjectMatchValue is set 1457 ObjectMatchValue: must be blank when MatchValue is set 1458 } 1459 Matches[1]: { 1460 MatchValue: cannot be blank when ObjectMatchValue is blank 1461 ObjectMatchValue: cannot be blank when MatchValue is blank 1462 } 1463 }`, 1464 }, 1465 } 1466 1467 for name, test := range tests { 1468 t.Run(name, func(t *testing.T) { 1469 err := test.input.Validate() 1470 if test.withError != "" { 1471 require.Error(t, err) 1472 assert.Equal(t, strings.TrimPrefix(test.withError, "\n"), err.Error()) 1473 return 1474 } 1475 require.NoError(t, err) 1476 }) 1477 } 1478 }