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  }