github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/cloudlets/policy_version_test.go (about)

     1  package cloudlets
     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  
    14  	"github.com/stretchr/testify/require"
    15  	"github.com/tj/assert"
    16  )
    17  
    18  func TestListPolicyVersions(t *testing.T) {
    19  	tests := map[string]struct {
    20  		request          ListPolicyVersionsRequest
    21  		responseStatus   int
    22  		responseBody     string
    23  		expectedPath     string
    24  		expectedResponse []PolicyVersion
    25  		withError        func(*testing.T, error)
    26  	}{
    27  		"200 OK": {
    28  			request: ListPolicyVersionsRequest{
    29  				PolicyID: 284823,
    30  			},
    31  			responseStatus: http.StatusOK,
    32  			responseBody: `
    33  [
    34      {
    35          "activations": [],
    36          "createDate": 1631191583350,
    37          "createdBy": "jsmith",
    38          "deleted": false,
    39          "description": "some string",
    40          "lastModifiedBy": "jsmith",
    41          "lastModifiedDate": 1631191583350,
    42          "location": "/cloudlets/api/v2/policies/284823/versions/2",
    43          "matchRuleFormat": "1.0",
    44          "matchRules": null,
    45          "policyId": 284823,
    46          "revisionId": 4824132,
    47          "rulesLocked": false,
    48          "version": 2
    49      },
    50      {
    51          "activations": [],
    52          "createDate": 1631190136935,
    53          "createdBy": "jsmith",
    54          "deleted": false,
    55          "description": null,
    56          "lastModifiedBy": "jsmith",
    57          "lastModifiedDate": 1631190136935,
    58          "location": "/cloudlets/api/v2/policies/284823/versions/1",
    59          "matchRuleFormat": "1.0",
    60          "matchRules": null,
    61          "policyId": 284823,
    62          "revisionId": 4824129,
    63          "rulesLocked": false,
    64          "version": 1
    65      }
    66  ]`,
    67  			expectedPath: "/cloudlets/api/v2/policies/284823/versions?includeActivations=false&includeDeleted=false&includeRules=false&offset=0",
    68  			expectedResponse: []PolicyVersion{
    69  				{
    70  					Activations:      []PolicyActivation{},
    71  					CreateDate:       1631191583350,
    72  					CreatedBy:        "jsmith",
    73  					Deleted:          false,
    74  					Description:      "some string",
    75  					LastModifiedBy:   "jsmith",
    76  					LastModifiedDate: 1631191583350,
    77  					Location:         "/cloudlets/api/v2/policies/284823/versions/2",
    78  					MatchRuleFormat:  "1.0",
    79  					MatchRules:       nil,
    80  					PolicyID:         284823,
    81  					RevisionID:       4824132,
    82  					RulesLocked:      false,
    83  					Version:          2,
    84  				},
    85  				{
    86  					Activations:      []PolicyActivation{},
    87  					CreateDate:       1631190136935,
    88  					CreatedBy:        "jsmith",
    89  					Deleted:          false,
    90  					Description:      "",
    91  					LastModifiedBy:   "jsmith",
    92  					LastModifiedDate: 1631190136935,
    93  					Location:         "/cloudlets/api/v2/policies/284823/versions/1",
    94  					MatchRuleFormat:  "1.0",
    95  					MatchRules:       nil,
    96  					PolicyID:         284823,
    97  					RevisionID:       4824129,
    98  					RulesLocked:      false,
    99  					Version:          1,
   100  				},
   101  			},
   102  		},
   103  
   104  		"200 OK with params": {
   105  			request: ListPolicyVersionsRequest{
   106  				PolicyID:           284823,
   107  				IncludeRules:       true,
   108  				IncludeDeleted:     true,
   109  				IncludeActivations: true,
   110  				Offset:             2,
   111  				PageSize:           tools.IntPtr(3),
   112  			},
   113  			responseStatus: http.StatusOK,
   114  			responseBody: `
   115  []`,
   116  			expectedPath:     "/cloudlets/api/v2/policies/284823/versions?includeActivations=true&includeDeleted=true&includeRules=true&offset=2&pageSize=3",
   117  			expectedResponse: []PolicyVersion{},
   118  		},
   119  		"500 internal server error": {
   120  			request: ListPolicyVersionsRequest{
   121  				PolicyID: 284823,
   122  			},
   123  			responseStatus: http.StatusInternalServerError,
   124  			responseBody: `
   125  {
   126  	"type": "internal_error",
   127     "title": "Internal Server Error",
   128     "detail": "Error making request",
   129     "status": 500
   130  }`,
   131  			expectedPath: "/cloudlets/api/v2/policies/284823/versions?includeActivations=false&includeDeleted=false&includeRules=false&offset=0",
   132  			withError: func(t *testing.T, err error) {
   133  				want := &Error{
   134  					Type:       "internal_error",
   135  					Title:      "Internal Server Error",
   136  					Detail:     "Error making request",
   137  					StatusCode: http.StatusInternalServerError,
   138  				}
   139  				assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err)
   140  			},
   141  		},
   142  	}
   143  
   144  	for name, test := range tests {
   145  		t.Run(name, func(t *testing.T) {
   146  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   147  				assert.Equal(t, test.expectedPath, r.URL.String())
   148  				assert.Equal(t, http.MethodGet, r.Method)
   149  				w.WriteHeader(test.responseStatus)
   150  				_, err := w.Write([]byte(test.responseBody))
   151  				assert.NoError(t, err)
   152  			}))
   153  			client := mockAPIClient(t, mockServer)
   154  			result, err := client.ListPolicyVersions(context.Background(), test.request)
   155  			if test.withError != nil {
   156  				test.withError(t, err)
   157  				return
   158  			}
   159  			require.NoError(t, err)
   160  			assert.Equal(t, test.expectedResponse, result)
   161  		})
   162  	}
   163  }
   164  
   165  func TestGetPolicyVersion(t *testing.T) {
   166  	tests := map[string]struct {
   167  		request          GetPolicyVersionRequest
   168  		responseStatus   int
   169  		responseBody     string
   170  		expectedPath     string
   171  		expectedResponse *PolicyVersion
   172  		withError        func(*testing.T, error)
   173  	}{
   174  		"200 OK": {
   175  			request: GetPolicyVersionRequest{
   176  				PolicyID:  276858,
   177  				Version:   1,
   178  				OmitRules: true,
   179  			},
   180  			responseStatus: http.StatusOK,
   181  			responseBody: `
   182  {
   183      "activations": [],
   184      "createDate": 1629299944291,
   185      "createdBy": "jsmith",
   186      "deleted": false,
   187      "description": null,
   188      "lastModifiedBy": "jsmith",
   189      "lastModifiedDate": 1629299944291,
   190      "location": "/cloudlets/api/v2/policies/276858/versions/1",
   191      "matchRuleFormat": "1.0",
   192      "matchRules": null,
   193      "policyId": 276858,
   194      "revisionId": 4811534,
   195      "rulesLocked": false,
   196      "version": 1
   197  }`,
   198  			expectedPath: "/cloudlets/api/v2/policies/276858/versions/1?omitRules=true",
   199  			expectedResponse: &PolicyVersion{
   200  				Activations:      []PolicyActivation{},
   201  				CreateDate:       1629299944291,
   202  				CreatedBy:        "jsmith",
   203  				Deleted:          false,
   204  				Description:      "",
   205  				LastModifiedBy:   "jsmith",
   206  				LastModifiedDate: 1629299944291,
   207  				Location:         "/cloudlets/api/v2/policies/276858/versions/1",
   208  				MatchRuleFormat:  "1.0",
   209  				MatchRules:       nil,
   210  				PolicyID:         276858,
   211  				RevisionID:       4811534,
   212  				RulesLocked:      false,
   213  				Version:          1,
   214  			},
   215  		},
   216  		"200 OK, ER with disabled rule": {
   217  			request: GetPolicyVersionRequest{
   218  				PolicyID: 276858,
   219  				Version:  6,
   220  			},
   221  			responseStatus: http.StatusOK,
   222  			responseBody: `{
   223      "activations": [],
   224      "createDate": 1629981355165,
   225      "createdBy": "jsmith",
   226      "deleted": false,
   227      "description": null,
   228      "lastModifiedBy": "jsmith",
   229      "lastModifiedDate": 1629981355165,
   230      "location": "/cloudlets/api/v2/policies/276858/versions/6",
   231      "matchRuleFormat": "1.0",
   232      "matchRules": [
   233          {
   234              "type": "erMatchRule",
   235              "end": 0,
   236              "id": 0,
   237              "matchURL": null,
   238              "disabled": true,
   239              "name": "rul3",
   240              "redirectURL": "/abc/sss",
   241              "start": 0,
   242              "statusCode": 307,
   243              "useIncomingQueryString": false,
   244              "useIncomingSchemeAndHost": true,
   245              "useRelativeUrl": "copy_scheme_hostname"
   246          }
   247      ],
   248      "policyId": 276858,
   249      "revisionId": 4815968,
   250      "rulesLocked": false,
   251      "version": 6
   252  }`,
   253  			expectedPath: "/cloudlets/api/v2/policies/276858/versions/6?omitRules=false",
   254  			expectedResponse: &PolicyVersion{
   255  				Activations:      []PolicyActivation{},
   256  				CreateDate:       1629981355165,
   257  				CreatedBy:        "jsmith",
   258  				Deleted:          false,
   259  				Description:      "",
   260  				LastModifiedBy:   "jsmith",
   261  				LastModifiedDate: 1629981355165,
   262  				Location:         "/cloudlets/api/v2/policies/276858/versions/6",
   263  				MatchRuleFormat:  "1.0",
   264  				PolicyID:         276858,
   265  				RevisionID:       4815968,
   266  				RulesLocked:      false,
   267  				Version:          6,
   268  				MatchRules: MatchRules{
   269  					&MatchRuleER{
   270  						Type:                     "erMatchRule",
   271  						End:                      0,
   272  						ID:                       0,
   273  						MatchURL:                 "",
   274  						Name:                     "rul3",
   275  						RedirectURL:              "/abc/sss",
   276  						Start:                    0,
   277  						StatusCode:               307,
   278  						UseIncomingQueryString:   false,
   279  						UseIncomingSchemeAndHost: true,
   280  						UseRelativeURL:           "copy_scheme_hostname",
   281  						Disabled:                 true,
   282  					},
   283  				},
   284  			},
   285  		},
   286  
   287  		"200 OK, ALB with disabled rule": {
   288  			request: GetPolicyVersionRequest{
   289  				PolicyID: 276858,
   290  				Version:  6,
   291  			},
   292  			responseStatus: http.StatusOK,
   293  			responseBody: `{
   294      "activations": [],
   295      "createDate": 1629981355165,
   296      "createdBy": "jsmith",
   297      "deleted": false,
   298      "description": null,
   299      "lastModifiedBy": "jsmith",
   300      "lastModifiedDate": 1629981355165,
   301      "location": "/cloudlets/api/v2/policies/276858/versions/6",
   302      "matchRuleFormat": "1.0",
   303      "matchRules": [
   304          {
   305              "type": "albMatchRule",
   306              "end": 0,
   307              "id": 0,
   308              "matchURL": null,
   309              "disabled": true,
   310              "name": "rul3",
   311              "start": 0
   312          }
   313      ],
   314      "policyId": 276858,
   315      "revisionId": 4815968,
   316      "rulesLocked": false,
   317      "version": 6
   318  }`,
   319  			expectedPath: "/cloudlets/api/v2/policies/276858/versions/6?omitRules=false",
   320  			expectedResponse: &PolicyVersion{
   321  				Activations:      []PolicyActivation{},
   322  				CreateDate:       1629981355165,
   323  				CreatedBy:        "jsmith",
   324  				Deleted:          false,
   325  				Description:      "",
   326  				LastModifiedBy:   "jsmith",
   327  				LastModifiedDate: 1629981355165,
   328  				Location:         "/cloudlets/api/v2/policies/276858/versions/6",
   329  				MatchRuleFormat:  "1.0",
   330  				PolicyID:         276858,
   331  				RevisionID:       4815968,
   332  				RulesLocked:      false,
   333  				Version:          6,
   334  				MatchRules: MatchRules{
   335  					&MatchRuleALB{
   336  						Type:     "albMatchRule",
   337  						End:      0,
   338  						ID:       0,
   339  						MatchURL: "",
   340  						Name:     "rul3",
   341  						Start:    0,
   342  						Disabled: true,
   343  					},
   344  				},
   345  			},
   346  		},
   347  		"200 OK, AS rule with disabled=false": {
   348  			request: GetPolicyVersionRequest{
   349  				PolicyID: 355557,
   350  				Version:  2,
   351  			},
   352  			responseStatus: http.StatusOK,
   353  			responseBody: `{
   354      "activations": [],
   355      "createDate": 1643788763643,
   356      "createdBy": "jsmith",
   357      "deleted": false,
   358      "description": "Initial version",
   359      "lastModifiedBy": "jsmith",
   360      "lastModifiedDate": 1643789091393,
   361      "location": "/cloudlets/api/v2/policies/355557/versions/2",
   362      "matchRuleFormat": "1.0",
   363      "matchRules": [
   364          {
   365              "type": "asMatchRule",
   366              "akaRuleId": "f58014ee0cc17ce",
   367              "end": 0,
   368              "forwardSettings": {
   369                  "originId": "originremote2",
   370                  "pathAndQS": "/sales/Q1/",
   371                  "useIncomingQueryString": true
   372              },
   373              "id": 0,
   374              "location": "/cloudlets/api/v2/policies/355557/versions/2/rules/f58014ee0cc17ce",
   375              "matches": [
   376                  {
   377                      "caseSensitive": false,
   378                      "matchOperator": "equals",
   379                      "matchType": "range",
   380                      "negate": false,
   381                      "objectMatchValue": {
   382                          "type": "range",
   383                          "value": [
   384                              1,
   385                              25
   386                          ]
   387                      }
   388                  }
   389              ],
   390              "name": "Q1Sales",
   391              "start": 0
   392          }
   393      ],
   394      "policyId": 355557,
   395      "revisionId": 4934569,
   396      "rulesLocked": false,
   397      "version": 2
   398  }`,
   399  			expectedPath: "/cloudlets/api/v2/policies/355557/versions/2?omitRules=false",
   400  			expectedResponse: &PolicyVersion{
   401  				Activations:      []PolicyActivation{},
   402  				CreateDate:       1643788763643,
   403  				CreatedBy:        "jsmith",
   404  				Deleted:          false,
   405  				Description:      "Initial version",
   406  				LastModifiedBy:   "jsmith",
   407  				LastModifiedDate: 1643789091393,
   408  				Location:         "/cloudlets/api/v2/policies/355557/versions/2",
   409  				MatchRuleFormat:  "1.0",
   410  				MatchRules: MatchRules{
   411  					&MatchRuleAS{
   412  						Type: "asMatchRule",
   413  						End:  0,
   414  						ForwardSettings: ForwardSettingsAS{
   415  							OriginID:               "originremote2",
   416  							PathAndQS:              "/sales/Q1/",
   417  							UseIncomingQueryString: true,
   418  						},
   419  						ID: 0,
   420  						Matches: []MatchCriteriaAS{
   421  							{
   422  								CaseSensitive: false,
   423  								MatchOperator: "equals",
   424  								MatchType:     "range",
   425  								Negate:        false,
   426  								ObjectMatchValue: &ObjectMatchValueRange{
   427  									Type: "range",
   428  									Value: []int64{
   429  										1, 25},
   430  								},
   431  							},
   432  						},
   433  						Name:  "Q1Sales",
   434  						Start: 0,
   435  					},
   436  				},
   437  				PolicyID:    355557,
   438  				RevisionID:  4934569,
   439  				RulesLocked: false,
   440  				Version:     2,
   441  			},
   442  		},
   443  		"200 OK, PR rule": {
   444  			request: GetPolicyVersionRequest{
   445  				PolicyID: 276858,
   446  				Version:  6,
   447  			},
   448  			responseStatus: http.StatusOK,
   449  			responseBody: `{
   450      "activations": [],
   451      "createDate": 1638547203265,
   452      "createdBy": "jsmith",
   453      "deleted": false,
   454      "description": null,
   455      "lastModifiedBy": "jsmith",
   456      "lastModifiedDate": 1638547203265,
   457      "location": "/cloudlets/api/v2/policies/325401/versions/3",
   458      "matchRuleFormat": "1.0",
   459      "matchRules": [
   460          {
   461              "type": "cdMatchRule",
   462              "akaRuleId": "b151ca68e51f5a61",
   463              "end": 0,
   464              "forwardSettings": {
   465                  "originId": "fr_test_krk_dc2",
   466                  "percent": 11
   467              },
   468              "id": 0,
   469              "location": "/cloudlets/api/v2/policies/325401/versions/3/rules/b151ca68e51f5a61",
   470              "matches": [
   471                  {
   472                      "caseSensitive": false,
   473                      "matchOperator": "equals",
   474                      "matchType": "method",
   475                      "negate": false,
   476                      "objectMatchValue": {
   477                          "type": "simple",
   478                          "value": [
   479                              "GET"
   480                          ]
   481                      }
   482                  }
   483              ],
   484              "name": "rule 1",
   485              "start": 0
   486          }
   487      ],
   488      "policyId": 325401,
   489      "revisionId": 4888857,
   490      "rulesLocked": false,
   491      "version": 3
   492  }`,
   493  			expectedPath: "/cloudlets/api/v2/policies/276858/versions/6?omitRules=false",
   494  			expectedResponse: &PolicyVersion{
   495  				Activations:      []PolicyActivation{},
   496  				CreateDate:       1638547203265,
   497  				CreatedBy:        "jsmith",
   498  				Deleted:          false,
   499  				Description:      "",
   500  				LastModifiedBy:   "jsmith",
   501  				LastModifiedDate: 1638547203265,
   502  				Location:         "/cloudlets/api/v2/policies/325401/versions/3",
   503  				MatchRuleFormat:  "1.0",
   504  				MatchRules: MatchRules{
   505  					&MatchRulePR{
   506  						Type: "cdMatchRule",
   507  						End:  0,
   508  						ForwardSettings: ForwardSettingsPR{
   509  							OriginID: "fr_test_krk_dc2",
   510  							Percent:  11,
   511  						},
   512  						ID: 0,
   513  						Matches: []MatchCriteriaPR{
   514  							{
   515  								CaseSensitive: false,
   516  								MatchOperator: "equals",
   517  								MatchType:     "method",
   518  								Negate:        false,
   519  								ObjectMatchValue: &ObjectMatchValueSimple{
   520  									Type: "simple",
   521  									Value: []string{
   522  										"GET"},
   523  								},
   524  							},
   525  						},
   526  						Name:  "rule 1",
   527  						Start: 0,
   528  					},
   529  				},
   530  				PolicyID:    325401,
   531  				RevisionID:  4888857,
   532  				RulesLocked: false,
   533  				Version:     3,
   534  			},
   535  		},
   536  		"200 OK, ER rule with disabled=false": {
   537  			request: GetPolicyVersionRequest{
   538  				PolicyID: 276858,
   539  				Version:  6,
   540  			},
   541  			responseStatus: http.StatusOK,
   542  			responseBody: `{
   543      "activations": [],
   544      "createDate": 1629981355165,
   545      "createdBy": "jsmith",
   546      "deleted": false,
   547      "description": null,
   548      "lastModifiedBy": "jsmith",
   549      "lastModifiedDate": 1629981355165,
   550      "location": "/cloudlets/api/v2/policies/276858/versions/6",
   551      "matchRuleFormat": "1.0",
   552      "matchRules": [
   553          {
   554              "type": "erMatchRule",
   555              "end": 0,
   556              "id": 0,
   557              "matchURL": null,
   558              "name": "rul3",
   559              "redirectURL": "/abc/sss",
   560              "start": 0,
   561              "statusCode": 307,
   562              "useIncomingQueryString": false,
   563              "useIncomingSchemeAndHost": true,
   564              "useRelativeUrl": "copy_scheme_hostname"
   565          }
   566      ],
   567      "policyId": 276858,
   568      "revisionId": 4815968,
   569      "rulesLocked": false,
   570      "version": 6
   571  }`,
   572  			expectedPath: "/cloudlets/api/v2/policies/276858/versions/6?omitRules=false",
   573  			expectedResponse: &PolicyVersion{
   574  				Activations:      []PolicyActivation{},
   575  				CreateDate:       1629981355165,
   576  				CreatedBy:        "jsmith",
   577  				Deleted:          false,
   578  				Description:      "",
   579  				LastModifiedBy:   "jsmith",
   580  				LastModifiedDate: 1629981355165,
   581  				Location:         "/cloudlets/api/v2/policies/276858/versions/6",
   582  				MatchRuleFormat:  "1.0",
   583  				PolicyID:         276858,
   584  				RevisionID:       4815968,
   585  				RulesLocked:      false,
   586  				Version:          6,
   587  				MatchRules: MatchRules{
   588  					&MatchRuleER{
   589  						Type:                     "erMatchRule",
   590  						End:                      0,
   591  						ID:                       0,
   592  						MatchURL:                 "",
   593  						Name:                     "rul3",
   594  						RedirectURL:              "/abc/sss",
   595  						Start:                    0,
   596  						StatusCode:               307,
   597  						UseIncomingQueryString:   false,
   598  						UseIncomingSchemeAndHost: true,
   599  						UseRelativeURL:           "copy_scheme_hostname",
   600  						Disabled:                 false,
   601  					},
   602  				},
   603  			},
   604  		},
   605  		"200 OK, ALB rule with disabled=false": {
   606  			request: GetPolicyVersionRequest{
   607  				PolicyID: 276858,
   608  				Version:  6,
   609  			},
   610  			responseStatus: http.StatusOK,
   611  			responseBody: `{
   612      "activations": [],
   613      "createDate": 1629981355165,
   614      "createdBy": "jsmith",
   615      "deleted": false,
   616      "description": null,
   617      "lastModifiedBy": "jsmith",
   618      "lastModifiedDate": 1629981355165,
   619      "location": "/cloudlets/api/v2/policies/276858/versions/6",
   620      "matchRuleFormat": "1.0",
   621      "matchRules": [
   622          {
   623              "type": "albMatchRule",
   624              "end": 0,
   625              "id": 0,
   626              "matchURL": null,
   627              "name": "rul3",
   628              "start": 0
   629          }
   630      ],
   631      "policyId": 276858,
   632      "revisionId": 4815968,
   633      "rulesLocked": false,
   634      "version": 6
   635  }`,
   636  			expectedPath: "/cloudlets/api/v2/policies/276858/versions/6?omitRules=false",
   637  			expectedResponse: &PolicyVersion{
   638  				Activations:      []PolicyActivation{},
   639  				CreateDate:       1629981355165,
   640  				CreatedBy:        "jsmith",
   641  				Deleted:          false,
   642  				Description:      "",
   643  				LastModifiedBy:   "jsmith",
   644  				LastModifiedDate: 1629981355165,
   645  				Location:         "/cloudlets/api/v2/policies/276858/versions/6",
   646  				MatchRuleFormat:  "1.0",
   647  				PolicyID:         276858,
   648  				RevisionID:       4815968,
   649  				RulesLocked:      false,
   650  				Version:          6,
   651  				MatchRules: MatchRules{
   652  					&MatchRuleALB{
   653  						Type:     "albMatchRule",
   654  						End:      0,
   655  						ID:       0,
   656  						MatchURL: "",
   657  						Name:     "rul3",
   658  						Start:    0,
   659  						Disabled: false,
   660  					},
   661  				},
   662  			},
   663  		},
   664  		"200 OK, FR with disabled rule": {
   665  			request: GetPolicyVersionRequest{
   666  				PolicyID: 276858,
   667  				Version:  6,
   668  			},
   669  			responseStatus: http.StatusOK,
   670  			responseBody: `{
   671      "activations": [],
   672      "createDate": 1629981355165,
   673      "createdBy": "jsmith",
   674      "deleted": false,
   675      "description": null,
   676      "lastModifiedBy": "jsmith",
   677      "lastModifiedDate": 1629981355165,
   678      "location": "/cloudlets/api/v2/policies/276858/versions/6",
   679      "matchRuleFormat": "1.0",
   680      "matchRules": [{
   681          "type": "frMatchRule",
   682          "disabled": true,
   683          "end": 0,
   684          "id": 0,
   685          "matchURL": null,
   686          "forwardSettings": {
   687              "pathAndQS": "/test_images/simpleimg.jpg",
   688              "useIncomingQueryString": true,
   689  			"originId": "1234"
   690  		},
   691          "name": "rule 1",
   692          "start": 0
   693      }],
   694      "policyId": 276858,
   695      "revisionId": 4815968,
   696      "rulesLocked": false,
   697      "version": 6
   698  }`,
   699  			expectedPath: "/cloudlets/api/v2/policies/276858/versions/6?omitRules=false",
   700  			expectedResponse: &PolicyVersion{
   701  				Activations:      []PolicyActivation{},
   702  				CreateDate:       1629981355165,
   703  				CreatedBy:        "jsmith",
   704  				Deleted:          false,
   705  				Description:      "",
   706  				LastModifiedBy:   "jsmith",
   707  				LastModifiedDate: 1629981355165,
   708  				Location:         "/cloudlets/api/v2/policies/276858/versions/6",
   709  				MatchRuleFormat:  "1.0",
   710  				PolicyID:         276858,
   711  				RevisionID:       4815968,
   712  				RulesLocked:      false,
   713  				Version:          6,
   714  				MatchRules: MatchRules{
   715  					&MatchRuleFR{
   716  						Name:     "rule 1",
   717  						Type:     "frMatchRule",
   718  						Start:    0,
   719  						End:      0,
   720  						ID:       0,
   721  						MatchURL: "",
   722  						ForwardSettings: ForwardSettingsFR{
   723  							PathAndQS:              "/test_images/simpleimg.jpg",
   724  							UseIncomingQueryString: true,
   725  							OriginID:               "1234",
   726  						},
   727  						Disabled: true,
   728  					},
   729  				},
   730  			},
   731  		},
   732  		"500 internal server error": {
   733  			request: GetPolicyVersionRequest{
   734  				PolicyID: 1,
   735  			},
   736  			responseStatus: http.StatusInternalServerError,
   737  			responseBody: `
   738  {
   739  	"type": "internal_error",
   740     "title": "Internal Server Error",
   741     "detail": "Error making request",
   742     "status": 500
   743  }`,
   744  			expectedPath: "/cloudlets/api/v2/policies/1/versions/0?omitRules=false",
   745  			withError: func(t *testing.T, err error) {
   746  				want := &Error{
   747  					Type:       "internal_error",
   748  					Title:      "Internal Server Error",
   749  					Detail:     "Error making request",
   750  					StatusCode: http.StatusInternalServerError,
   751  				}
   752  				assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err)
   753  			},
   754  		},
   755  	}
   756  
   757  	for name, test := range tests {
   758  		t.Run(name, func(t *testing.T) {
   759  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   760  				assert.Equal(t, test.expectedPath, r.URL.String())
   761  				assert.Equal(t, http.MethodGet, r.Method)
   762  				w.WriteHeader(test.responseStatus)
   763  				_, err := w.Write([]byte(test.responseBody))
   764  				assert.NoError(t, err)
   765  			}))
   766  			client := mockAPIClient(t, mockServer)
   767  			result, err := client.GetPolicyVersion(context.Background(), test.request)
   768  			if test.withError != nil {
   769  				test.withError(t, err)
   770  				return
   771  			}
   772  			require.NoError(t, err)
   773  			assert.Equal(t, test.expectedResponse, result)
   774  		})
   775  	}
   776  }
   777  
   778  func TestCreatePolicyVersion(t *testing.T) {
   779  	tests := map[string]struct {
   780  		request          CreatePolicyVersionRequest
   781  		requestBody      string
   782  		responseStatus   int
   783  		responseBody     string
   784  		expectedPath     string
   785  		expectedResponse *PolicyVersion
   786  		withError        error
   787  	}{
   788  		"201 created, simple ER": {
   789  			request: CreatePolicyVersionRequest{
   790  				CreatePolicyVersion: CreatePolicyVersion{
   791  					Description: "Description for the policy",
   792  				},
   793  				PolicyID: 276858,
   794  			},
   795  			responseStatus: http.StatusCreated,
   796  			responseBody: `
   797  {
   798      "activations": [],
   799      "createDate": 1629812554924,
   800      "createdBy": "jsmith",
   801      "deleted": false,
   802      "description": "Description for the policy",
   803      "lastModifiedBy": "jsmith",
   804      "lastModifiedDate": 1629812554924,
   805      "location": "/cloudlets/api/v2/policies/276858/versions/2",
   806      "matchRuleFormat": "1.0",
   807      "matchRules": null,
   808      "policyId": 276858,
   809      "revisionId": 4814868,
   810      "rulesLocked": false,
   811      "version": 2
   812  }`,
   813  			expectedPath: "/cloudlets/api/v2/policies/276858/versions",
   814  			expectedResponse: &PolicyVersion{
   815  				Activations:      []PolicyActivation{},
   816  				CreateDate:       1629812554924,
   817  				CreatedBy:        "jsmith",
   818  				Deleted:          false,
   819  				Description:      "Description for the policy",
   820  				LastModifiedBy:   "jsmith",
   821  				LastModifiedDate: 1629812554924,
   822  				Location:         "/cloudlets/api/v2/policies/276858/versions/2",
   823  				MatchRuleFormat:  "1.0",
   824  				MatchRules:       nil,
   825  				PolicyID:         276858,
   826  				RevisionID:       4814868,
   827  				RulesLocked:      false,
   828  				Version:          2,
   829  			},
   830  		},
   831  
   832  		"201 created, complex ALB": {
   833  			request: CreatePolicyVersionRequest{
   834  				CreatePolicyVersion: CreatePolicyVersion{
   835  					MatchRules: MatchRules{
   836  						&MatchRuleALB{
   837  							Matches: []MatchCriteriaALB{
   838  								{
   839  									MatchType:     "protocol",
   840  									MatchValue:    "https",
   841  									MatchOperator: "equals",
   842  									Negate:        false,
   843  									CaseSensitive: false,
   844  								},
   845  								{
   846  									MatchType:     "path",
   847  									MatchValue:    "/nonalb",
   848  									MatchOperator: "equals",
   849  									Negate:        true,
   850  									CaseSensitive: false,
   851  								},
   852  							},
   853  							Start: 0,
   854  							End:   0,
   855  							Type:  "albMatchRule",
   856  							Name:  "Rule3",
   857  							ForwardSettings: ForwardSettingsALB{
   858  								OriginID: "alb_test_krk_dc1_only",
   859  							},
   860  							ID: 0,
   861  						},
   862  						&MatchRuleALB{
   863  							Matches: []MatchCriteriaALB{
   864  								{
   865  
   866  									MatchType:     "protocol",
   867  									MatchValue:    "http",
   868  									MatchOperator: "equals",
   869  									Negate:        false,
   870  									CaseSensitive: false,
   871  								},
   872  							},
   873  							Start: 0,
   874  							End:   0,
   875  							Type:  "albMatchRule",
   876  							Name:  "Rule1",
   877  							ForwardSettings: ForwardSettingsALB{
   878  								OriginID: "alb_test_krk_0_100",
   879  							},
   880  							ID: 0,
   881  						},
   882  					},
   883  				},
   884  				PolicyID: 276858,
   885  			},
   886  			responseStatus: http.StatusCreated,
   887  			responseBody: `
   888  {
   889      "activations": [],
   890      "createDate": 1629981546401,
   891      "createdBy": "jsmith",
   892      "deleted": false,
   893      "description": null,
   894      "lastModifiedBy": "jsmith",
   895      "lastModifiedDate": 1629981546401,
   896      "location": "/cloudlets/api/v2/policies/279628/versions/2",
   897      "matchRuleFormat": "1.0",
   898      "matchRules": [
   899          {
   900              "type": "albMatchRule",
   901              "end": 0,
   902              "forwardSettings": {
   903                  "originId": "alb_test_krk_dc1_only"
   904              },
   905              "id": 0,
   906              "matchURL": null,
   907              "matches": [
   908                  {
   909                      "caseSensitive": false,
   910                      "matchOperator": "equals",
   911                      "matchType": "protocol",
   912                      "matchValue": "https",
   913                      "negate": false
   914                  },
   915                  {
   916                      "caseSensitive": false,
   917                      "matchOperator": "equals",
   918                      "matchType": "path",
   919                      "matchValue": "/nonalb",
   920                      "negate": true
   921                  }
   922              ],
   923              "name": "Rule3",
   924              "start": 0
   925          },
   926          {
   927              "type": "albMatchRule",
   928              "end": 0,
   929              "forwardSettings": {
   930                  "originId": "alb_test_krk_0_100"
   931              },
   932              "id": 0,
   933              "matchURL": null,
   934              "matches": [
   935                  {
   936                      "caseSensitive": false,
   937                      "matchOperator": "equals",
   938                      "matchType": "protocol",
   939                      "matchValue": "http",
   940                      "negate": false
   941                  }
   942              ],
   943              "name": "Rule1",
   944              "start": 0
   945          }
   946      ],
   947      "policyId": 279628,
   948      "revisionId": 4815971,
   949      "rulesLocked": false,
   950      "version": 2
   951  }`,
   952  			expectedPath: "/cloudlets/api/v2/policies/276858/versions",
   953  			expectedResponse: &PolicyVersion{
   954  				Activations:      []PolicyActivation{},
   955  				CreateDate:       1629981546401,
   956  				CreatedBy:        "jsmith",
   957  				Deleted:          false,
   958  				Description:      "",
   959  				LastModifiedBy:   "jsmith",
   960  				LastModifiedDate: 1629981546401,
   961  				Location:         "/cloudlets/api/v2/policies/279628/versions/2",
   962  				MatchRuleFormat:  "1.0",
   963  				MatchRules: MatchRules{
   964  					&MatchRuleALB{
   965  						Type: "albMatchRule",
   966  						End:  0,
   967  						ForwardSettings: ForwardSettingsALB{
   968  							OriginID: "alb_test_krk_dc1_only",
   969  						},
   970  						ID:       0,
   971  						MatchURL: "",
   972  						Matches: []MatchCriteriaALB{
   973  							{
   974  
   975  								CaseSensitive: false,
   976  								MatchOperator: "equals",
   977  								MatchType:     "protocol",
   978  								MatchValue:    "https",
   979  								Negate:        false,
   980  							},
   981  							{
   982  								CaseSensitive: false,
   983  								MatchOperator: "equals",
   984  								MatchType:     "path",
   985  								MatchValue:    "/nonalb",
   986  								Negate:        true,
   987  							},
   988  						},
   989  						Name:  "Rule3",
   990  						Start: 0,
   991  					},
   992  					&MatchRuleALB{
   993  						Type: "albMatchRule",
   994  						End:  0,
   995  						ForwardSettings: ForwardSettingsALB{
   996  							OriginID: "alb_test_krk_0_100",
   997  						},
   998  						ID:       0,
   999  						MatchURL: "",
  1000  						Matches: []MatchCriteriaALB{
  1001  							{
  1002  								CaseSensitive: false,
  1003  								MatchOperator: "equals",
  1004  								MatchType:     "protocol",
  1005  								MatchValue:    "http",
  1006  								Negate:        false,
  1007  							},
  1008  						},
  1009  						Name:  "Rule1",
  1010  						Start: 0,
  1011  					},
  1012  				},
  1013  				PolicyID:    279628,
  1014  				RevisionID:  4815971,
  1015  				RulesLocked: false,
  1016  				Version:     2,
  1017  			},
  1018  		},
  1019  		"201 created, complex ALB with objectMatchValue - object": {
  1020  			request: CreatePolicyVersionRequest{
  1021  				CreatePolicyVersion: CreatePolicyVersion{
  1022  					Description:     "New version 1630480693371",
  1023  					MatchRuleFormat: "1.0",
  1024  					MatchRules: MatchRules{
  1025  						&MatchRuleALB{
  1026  							Matches: []MatchCriteriaALB{
  1027  								{
  1028  									MatchOperator: "equals",
  1029  									MatchType:     "header",
  1030  									ObjectMatchValue: &ObjectMatchValueObject{
  1031  										Type: "object",
  1032  										Name: "ALB",
  1033  										Options: &Options{
  1034  											Value:            []string{"y"},
  1035  											ValueHasWildcard: true,
  1036  										},
  1037  									},
  1038  									Negate: false,
  1039  								},
  1040  							},
  1041  							Start: 0,
  1042  							End:   0,
  1043  							Type:  "albMatchRule",
  1044  							Name:  "alb rule",
  1045  							ForwardSettings: ForwardSettingsALB{
  1046  								OriginID: "alb_test_krk_mutable",
  1047  							},
  1048  							ID:            0,
  1049  							MatchesAlways: true,
  1050  						},
  1051  					},
  1052  				},
  1053  				PolicyID: 139743,
  1054  			},
  1055  			responseStatus: http.StatusCreated,
  1056  			responseBody: `
  1057  		{
  1058  		    "activations": [],
  1059  		    "createDate": 1630489884742,
  1060  		    "createdBy": "jsmith",
  1061  		    "deleted": false,
  1062  		    "description": "New version 1630480693371",
  1063  		    "lastModifiedBy": "jsmith",
  1064  		    "lastModifiedDate": 1630489884742,
  1065  		    "location": "/cloudlets/api/v2/policies/139743/versions/796",
  1066  		    "matchRuleFormat": "1.0",
  1067  		    "matchRules": [
  1068  		        {
  1069  		            "type": "albMatchRule",
  1070  		            "end": 0,
  1071  		            "forwardSettings": {
  1072  		                "originId": "alb_test_krk_mutable"
  1073  		            },
  1074  		            "id": 0,
  1075  		            "matchURL": null,
  1076  		            "matches": [
  1077  		                {
  1078  		                    "caseSensitive": false,
  1079  		                    "matchOperator": "equals",
  1080  		                    "matchType": "header",
  1081  		                    "negate": false,
  1082  		                    "objectMatchValue": {
  1083  		                        "type": "object",
  1084  		                        "name": "ALB",
  1085  		                        "options": {
  1086  		                            "value": [
  1087  		                                "y"
  1088  		                            ],
  1089  		                            "valueHasWildcard": true
  1090  		                        }
  1091  		                    }
  1092  		                }
  1093  		            ],
  1094  		            "matchesAlways": true,
  1095  		            "name": "alb rule",
  1096  		            "start": 0
  1097  		        }
  1098  		    ],
  1099  		    "policyId": 139743,
  1100  		    "revisionId": 4819432,
  1101  		    "rulesLocked": false,
  1102  		    "version": 796
  1103  		}`,
  1104  			expectedPath: "/cloudlets/api/v2/policies/139743/versions",
  1105  			expectedResponse: &PolicyVersion{
  1106  				Activations:      []PolicyActivation{},
  1107  				CreateDate:       1630489884742,
  1108  				CreatedBy:        "jsmith",
  1109  				Deleted:          false,
  1110  				Description:      "New version 1630480693371",
  1111  				LastModifiedBy:   "jsmith",
  1112  				LastModifiedDate: 1630489884742,
  1113  				Location:         "/cloudlets/api/v2/policies/139743/versions/796",
  1114  				MatchRuleFormat:  "1.0",
  1115  				MatchRules: MatchRules{
  1116  					&MatchRuleALB{
  1117  						Type: "albMatchRule",
  1118  						End:  0,
  1119  						ForwardSettings: ForwardSettingsALB{
  1120  							OriginID: "alb_test_krk_mutable",
  1121  						},
  1122  						ID:       0,
  1123  						MatchURL: "",
  1124  						Matches: []MatchCriteriaALB{
  1125  							{
  1126  								CaseSensitive: false,
  1127  								MatchOperator: "equals",
  1128  								MatchType:     "header",
  1129  								Negate:        false,
  1130  								ObjectMatchValue: &ObjectMatchValueObject{
  1131  									Type: "object",
  1132  									Name: "ALB",
  1133  									Options: &Options{
  1134  										Value:            []string{"y"},
  1135  										ValueHasWildcard: true,
  1136  									},
  1137  								},
  1138  							},
  1139  						},
  1140  						MatchesAlways: true,
  1141  						Name:          "alb rule",
  1142  						Start:         0,
  1143  					},
  1144  				},
  1145  				PolicyID:    139743,
  1146  				RevisionID:  4819432,
  1147  				RulesLocked: false,
  1148  				Version:     796,
  1149  			},
  1150  		},
  1151  		"201 created, complex ALB with objectMatchValue - simple": {
  1152  			request: CreatePolicyVersionRequest{
  1153  				CreatePolicyVersion: CreatePolicyVersion{
  1154  
  1155  					Description:     "New version 1630480693371",
  1156  					MatchRuleFormat: "1.0",
  1157  					MatchRules: MatchRules{
  1158  						&MatchRuleALB{
  1159  							Matches: []MatchCriteriaALB{
  1160  								{
  1161  									CaseSensitive: false,
  1162  									MatchOperator: "equals",
  1163  									MatchType:     "method",
  1164  									Negate:        false,
  1165  									ObjectMatchValue: &ObjectMatchValueSimple{
  1166  										Type:  "simple",
  1167  										Value: []string{"GET"},
  1168  									},
  1169  								},
  1170  							},
  1171  							Start: 0,
  1172  							End:   0,
  1173  							Type:  "albMatchRule",
  1174  							Name:  "alb rule",
  1175  							ForwardSettings: ForwardSettingsALB{
  1176  								OriginID: "alb_test_krk_mutable",
  1177  							},
  1178  							ID:            0,
  1179  							MatchesAlways: true,
  1180  						},
  1181  					},
  1182  				},
  1183  				PolicyID: 139743,
  1184  			},
  1185  			responseStatus: http.StatusCreated,
  1186  			responseBody: `
  1187  {
  1188      "activations": [],
  1189      "createDate": 1630506044027,
  1190      "createdBy": "jsmith",
  1191      "deleted": false,
  1192      "description": "New version 1630480693371",
  1193      "lastModifiedBy": "jsmith",
  1194      "lastModifiedDate": 1630506044027,
  1195      "location": "/cloudlets/api/v2/policies/139743/versions/797",
  1196      "matchRuleFormat": "1.0",
  1197      "matchRules": [
  1198          {
  1199              "type": "albMatchRule",
  1200              "end": 0,
  1201              "forwardSettings": {
  1202                  "originId": "alb_test_krk_mutable"
  1203              },
  1204              "id": 0,
  1205              "matchURL": null,
  1206              "matches": [
  1207                  {
  1208                      "caseSensitive": false,
  1209                      "matchOperator": "equals",
  1210                      "matchType": "method",
  1211                      "negate": false,
  1212                      "objectMatchValue": {
  1213                          "type": "simple",
  1214                          "value": [
  1215                              "GET"
  1216                          ]
  1217                      }
  1218                  }
  1219              ],
  1220              "matchesAlways": true,
  1221              "name": "alb rule",
  1222              "start": 0
  1223          }
  1224      ],
  1225      "policyId": 139743,
  1226      "revisionId": 4819449,
  1227      "rulesLocked": false,
  1228      "version": 797
  1229  }`,
  1230  			expectedPath: "/cloudlets/api/v2/policies/139743/versions",
  1231  			expectedResponse: &PolicyVersion{
  1232  				Activations:      []PolicyActivation{},
  1233  				CreateDate:       1630506044027,
  1234  				CreatedBy:        "jsmith",
  1235  				Deleted:          false,
  1236  				Description:      "New version 1630480693371",
  1237  				LastModifiedBy:   "jsmith",
  1238  				LastModifiedDate: 1630506044027,
  1239  				Location:         "/cloudlets/api/v2/policies/139743/versions/797",
  1240  				MatchRuleFormat:  "1.0",
  1241  				MatchRules: MatchRules{
  1242  					&MatchRuleALB{
  1243  						Type: "albMatchRule",
  1244  						End:  0,
  1245  						ForwardSettings: ForwardSettingsALB{
  1246  							OriginID: "alb_test_krk_mutable",
  1247  						},
  1248  						ID:       0,
  1249  						MatchURL: "",
  1250  						Matches: []MatchCriteriaALB{
  1251  							{
  1252  								CaseSensitive: false,
  1253  								MatchOperator: "equals",
  1254  								MatchType:     "method",
  1255  								Negate:        false,
  1256  								ObjectMatchValue: &ObjectMatchValueSimple{
  1257  									Type:  "simple",
  1258  									Value: []string{"GET"},
  1259  								},
  1260  							},
  1261  						},
  1262  						MatchesAlways: true,
  1263  						Name:          "alb rule",
  1264  						Start:         0,
  1265  					},
  1266  				},
  1267  				PolicyID:    139743,
  1268  				RevisionID:  4819449,
  1269  				RulesLocked: false,
  1270  				Version:     797,
  1271  			},
  1272  		},
  1273  		"201 created, complex ALB with objectMatchValue - range": {
  1274  			request: CreatePolicyVersionRequest{
  1275  				CreatePolicyVersion: CreatePolicyVersion{
  1276  
  1277  					Description:     "New version 1630480693371",
  1278  					MatchRuleFormat: "1.0",
  1279  					MatchRules: MatchRules{
  1280  						&MatchRuleALB{
  1281  							Matches: []MatchCriteriaALB{
  1282  								{
  1283  									CaseSensitive: false,
  1284  									MatchOperator: "equals",
  1285  									MatchType:     "range",
  1286  									Negate:        false,
  1287  									ObjectMatchValue: &ObjectMatchValueRange{
  1288  										Type:  "range",
  1289  										Value: []int64{1, 50},
  1290  									},
  1291  								},
  1292  							},
  1293  							Start: 0,
  1294  							End:   0,
  1295  							Type:  "albMatchRule",
  1296  							Name:  "alb rule",
  1297  							ForwardSettings: ForwardSettingsALB{
  1298  								OriginID: "alb_test_krk_mutable",
  1299  							},
  1300  							ID:            0,
  1301  							MatchesAlways: true,
  1302  						},
  1303  					},
  1304  				},
  1305  				PolicyID: 139743,
  1306  			},
  1307  			responseStatus: http.StatusCreated,
  1308  			responseBody: `
  1309  {
  1310      "activations": [],
  1311      "createDate": 1630507099511,
  1312      "createdBy": "jsmith",
  1313      "deleted": false,
  1314      "description": "New version 1630480693371",
  1315      "lastModifiedBy": "jsmith",
  1316      "lastModifiedDate": 1630507099511,
  1317      "location": "/cloudlets/api/v2/policies/139743/versions/798",
  1318      "matchRuleFormat": "1.0",
  1319      "matchRules": [
  1320          {
  1321              "type": "albMatchRule",
  1322              "end": 0,
  1323              "forwardSettings": {
  1324                  "originId": "alb_test_krk_mutable"
  1325              },
  1326              "id": 0,
  1327              "matchURL": null,
  1328              "matches": [
  1329                  {
  1330                      "caseSensitive": false,
  1331                      "matchOperator": "equals",
  1332                      "matchType": "range",
  1333                      "negate": false,
  1334                      "objectMatchValue": {
  1335                          "type": "range",
  1336                          "value": [
  1337                              1,
  1338                              50
  1339                          ]
  1340                      }
  1341                  }
  1342              ],
  1343              "matchesAlways": true,
  1344              "name": "alb rule",
  1345              "start": 0
  1346          }
  1347      ],
  1348      "policyId": 139743,
  1349      "revisionId": 4819450,
  1350      "rulesLocked": false,
  1351      "version": 798
  1352  }`,
  1353  			expectedPath: "/cloudlets/api/v2/policies/139743/versions",
  1354  			expectedResponse: &PolicyVersion{
  1355  				Activations:      []PolicyActivation{},
  1356  				CreateDate:       1630507099511,
  1357  				CreatedBy:        "jsmith",
  1358  				Deleted:          false,
  1359  				Description:      "New version 1630480693371",
  1360  				LastModifiedBy:   "jsmith",
  1361  				LastModifiedDate: 1630507099511,
  1362  				Location:         "/cloudlets/api/v2/policies/139743/versions/798",
  1363  				MatchRuleFormat:  "1.0",
  1364  				MatchRules: MatchRules{
  1365  					&MatchRuleALB{
  1366  						Type: "albMatchRule",
  1367  						End:  0,
  1368  						ForwardSettings: ForwardSettingsALB{
  1369  							OriginID: "alb_test_krk_mutable",
  1370  						},
  1371  						ID:       0,
  1372  						MatchURL: "",
  1373  						Matches: []MatchCriteriaALB{
  1374  							{
  1375  								CaseSensitive: false,
  1376  								MatchOperator: "equals",
  1377  								MatchType:     "range",
  1378  								Negate:        false,
  1379  								ObjectMatchValue: &ObjectMatchValueRange{
  1380  									Type:  "range",
  1381  									Value: []int64{1, 50},
  1382  								},
  1383  							},
  1384  						},
  1385  						MatchesAlways: true,
  1386  						Name:          "alb rule",
  1387  						Start:         0,
  1388  					},
  1389  				},
  1390  				PolicyID:    139743,
  1391  				RevisionID:  4819450,
  1392  				RulesLocked: false,
  1393  				Version:     798,
  1394  			},
  1395  		},
  1396  		"201 created, complex AS": {
  1397  			request: CreatePolicyVersionRequest{
  1398  				CreatePolicyVersion: CreatePolicyVersion{
  1399  					MatchRules: MatchRules{
  1400  						&MatchRuleAS{
  1401  							Start: 0,
  1402  							End:   0,
  1403  							Type:  "asMatchRule",
  1404  							Name:  "Q1Sales",
  1405  							ID:    0,
  1406  							ForwardSettings: ForwardSettingsAS{
  1407  								OriginID:               "originremote2",
  1408  								PathAndQS:              "/sales/Q1/",
  1409  								UseIncomingQueryString: true,
  1410  							},
  1411  							Matches: []MatchCriteriaAS{
  1412  								{
  1413  									CaseSensitive: false,
  1414  									MatchOperator: "equals",
  1415  									MatchType:     "range",
  1416  									Negate:        false,
  1417  									ObjectMatchValue: &ObjectMatchValueRange{
  1418  										Type:  "range",
  1419  										Value: []int64{1, 25},
  1420  									},
  1421  								},
  1422  								{
  1423  									CaseSensitive: false,
  1424  									MatchOperator: "equals",
  1425  									MatchType:     "method",
  1426  									Negate:        false,
  1427  									ObjectMatchValue: &ObjectMatchValueSimple{
  1428  										Type:  "simple",
  1429  										Value: []string{"GET"},
  1430  									},
  1431  								},
  1432  								{
  1433  									MatchOperator: "equals",
  1434  									MatchType:     "header",
  1435  									Negate:        false,
  1436  									ObjectMatchValue: &ObjectMatchValueObject{
  1437  										Type: "object",
  1438  										Name: "AS",
  1439  										Options: &Options{
  1440  											Value: []string{
  1441  												"text/html*",
  1442  												"text/css*",
  1443  												"application/x-javascript*",
  1444  											},
  1445  											ValueHasWildcard: true,
  1446  										},
  1447  									},
  1448  								},
  1449  							},
  1450  						},
  1451  					},
  1452  				},
  1453  				PolicyID: 355557,
  1454  			},
  1455  			responseStatus: http.StatusCreated,
  1456  			responseBody: `{
  1457      "activations": [],
  1458      "createDate": 1643788763643,
  1459      "createdBy": "jsmith",
  1460      "deleted": false,
  1461      "description": "Initial version",
  1462      "lastModifiedBy": "jsmith",
  1463      "lastModifiedDate": 1643789091393,
  1464      "location": "/cloudlets/api/v2/policies/355557/versions/2",
  1465      "matchRuleFormat": "1.0",
  1466      "matchRules": [
  1467          {
  1468              "type": "asMatchRule",
  1469              "akaRuleId": "f58014ee0cc17ce",
  1470              "end": 0,
  1471              "forwardSettings": {
  1472                  "originId": "originremote2",
  1473                  "pathAndQS": "/sales/Q1/",
  1474                  "useIncomingQueryString": true
  1475              },
  1476              "id": 0,
  1477              "location": "/cloudlets/api/v2/policies/355557/versions/2/rules/f58014ee0cc17ce",
  1478              "matches": [
  1479  				{
  1480                      "caseSensitive": false,
  1481                      "matchOperator": "equals",
  1482                      "matchType": "range",
  1483                      "negate": false,
  1484                      "objectMatchValue": {
  1485                          "type": "range",
  1486                          "value": [
  1487                              1,
  1488                              25
  1489                          ]
  1490                      }
  1491                  },
  1492  				{
  1493                      "caseSensitive": false,
  1494                      "matchOperator": "equals",
  1495                      "matchType": "method",
  1496                      "negate": false,
  1497                      "objectMatchValue": {
  1498                          "type": "simple",
  1499                          "value": [
  1500                              "GET"
  1501                          ]
  1502                      }
  1503                  },
  1504  				{
  1505                      "matchOperator": "equals",
  1506                      "matchType": "header",
  1507                      "negate": false,
  1508  					"objectMatchValue": {
  1509  						"type": "object",
  1510  						"name": "AS",
  1511  						"options": {
  1512  							"value": [
  1513  								"text/html*",
  1514                                  "text/css*",
  1515                                  "application/x-javascript*"
  1516  							],
  1517  							"valueHasWildcard": true
  1518  						}
  1519  					}
  1520                  }
  1521              ],
  1522              "name": "Q1Sales",
  1523              "start": 0
  1524          }
  1525      ],
  1526      "policyId": 355557,
  1527      "revisionId": 4934569,
  1528      "rulesLocked": false,
  1529      "version": 2
  1530  }`,
  1531  			expectedPath: "/cloudlets/api/v2/policies/355557/versions",
  1532  			expectedResponse: &PolicyVersion{
  1533  				Activations:      []PolicyActivation{},
  1534  				CreateDate:       1643788763643,
  1535  				CreatedBy:        "jsmith",
  1536  				Deleted:          false,
  1537  				Description:      "Initial version",
  1538  				LastModifiedBy:   "jsmith",
  1539  				LastModifiedDate: 1643789091393,
  1540  				Location:         "/cloudlets/api/v2/policies/355557/versions/2",
  1541  				MatchRuleFormat:  "1.0",
  1542  				MatchRules: MatchRules{
  1543  					&MatchRuleAS{
  1544  						Type: "asMatchRule",
  1545  						End:  0,
  1546  						ForwardSettings: ForwardSettingsAS{
  1547  							OriginID:               "originremote2",
  1548  							PathAndQS:              "/sales/Q1/",
  1549  							UseIncomingQueryString: true,
  1550  						},
  1551  						ID: 0,
  1552  						Matches: []MatchCriteriaAS{
  1553  							{
  1554  								CaseSensitive: false,
  1555  								MatchOperator: "equals",
  1556  								MatchType:     "range",
  1557  								Negate:        false,
  1558  								ObjectMatchValue: &ObjectMatchValueRange{
  1559  									Type: "range",
  1560  									Value: []int64{
  1561  										1, 25},
  1562  								},
  1563  							},
  1564  							{
  1565  								CaseSensitive: false,
  1566  								MatchOperator: "equals",
  1567  								MatchType:     "method",
  1568  								Negate:        false,
  1569  								ObjectMatchValue: &ObjectMatchValueSimple{
  1570  									Type:  "simple",
  1571  									Value: []string{"GET"},
  1572  								},
  1573  							},
  1574  							{
  1575  								MatchOperator: "equals",
  1576  								MatchType:     "header",
  1577  								Negate:        false,
  1578  								ObjectMatchValue: &ObjectMatchValueObject{
  1579  									Type: "object",
  1580  									Name: "AS",
  1581  									Options: &Options{
  1582  										Value: []string{
  1583  											"text/html*",
  1584  											"text/css*",
  1585  											"application/x-javascript*",
  1586  										},
  1587  										ValueHasWildcard: true,
  1588  									},
  1589  								},
  1590  							},
  1591  						},
  1592  						Name:  "Q1Sales",
  1593  						Start: 0,
  1594  					},
  1595  				},
  1596  				PolicyID:    355557,
  1597  				RevisionID:  4934569,
  1598  				RulesLocked: false,
  1599  				Version:     2,
  1600  			},
  1601  		},
  1602  		"201 created, complex PR": {
  1603  			request: CreatePolicyVersionRequest{
  1604  				CreatePolicyVersion: CreatePolicyVersion{
  1605  					MatchRules: MatchRules{
  1606  						&MatchRulePR{
  1607  							Start: 0,
  1608  							End:   0,
  1609  							Type:  "cdMatchRule",
  1610  							Name:  "rul3",
  1611  							ID:    0,
  1612  							ForwardSettings: ForwardSettingsPR{
  1613  								OriginID: "some_origin",
  1614  								Percent:  10,
  1615  							},
  1616  							Matches: []MatchCriteriaPR{
  1617  								{
  1618  									MatchType:     "hostname",
  1619  									MatchValue:    "3333.dom",
  1620  									MatchOperator: "equals",
  1621  									CaseSensitive: true,
  1622  									Negate:        false,
  1623  								},
  1624  								{
  1625  									MatchType:     "cookie",
  1626  									MatchValue:    "cookie=cookievalue",
  1627  									MatchOperator: "equals",
  1628  									Negate:        false,
  1629  									CaseSensitive: false,
  1630  								},
  1631  								{
  1632  									MatchType:     "extension",
  1633  									MatchValue:    "txt",
  1634  									MatchOperator: "equals",
  1635  									Negate:        false,
  1636  									CaseSensitive: false,
  1637  								},
  1638  							},
  1639  						},
  1640  						&MatchRulePR{
  1641  							Start:    0,
  1642  							End:      0,
  1643  							Type:     "cdMatchRule",
  1644  							Name:     "rule 2",
  1645  							MatchURL: "ddd.aaa",
  1646  							ID:       0,
  1647  							ForwardSettings: ForwardSettingsPR{
  1648  								OriginID: "some_origin",
  1649  								Percent:  10,
  1650  							},
  1651  						},
  1652  						&MatchRulePR{
  1653  							Type:     "cdMatchRule",
  1654  							ID:       0,
  1655  							Name:     "r1",
  1656  							Start:    0,
  1657  							End:      0,
  1658  							MatchURL: "abc.com",
  1659  							ForwardSettings: ForwardSettingsPR{
  1660  								OriginID: "some_origin",
  1661  								Percent:  10,
  1662  							},
  1663  						},
  1664  					},
  1665  				},
  1666  				PolicyID: 276858,
  1667  			},
  1668  			responseStatus: http.StatusCreated,
  1669  			responseBody: `{
  1670      "activations": [],
  1671      "createDate": 1629981355165,
  1672      "createdBy": "jsmith",
  1673      "deleted": false,
  1674      "description": null,
  1675      "lastModifiedBy": "jsmith",
  1676      "lastModifiedDate": 1629981355165,
  1677      "location": "/cloudlets/api/v2/policies/276858/versions/6",
  1678      "matchRuleFormat": "1.0",
  1679      "matchRules": [
  1680          {
  1681              "type": "cdMatchRule",
  1682              "end": 0,
  1683              "id": 0,
  1684              "matchURL": null,
  1685              "matches": [
  1686                  {
  1687                      "caseSensitive": true,
  1688                      "matchOperator": "equals",
  1689                      "matchType": "hostname",
  1690                      "matchValue": "3333.dom",
  1691                      "negate": false
  1692                  },
  1693                  {
  1694                      "caseSensitive": false,
  1695                      "matchOperator": "equals",
  1696                      "matchType": "cookie",
  1697                      "matchValue": "cookie=cookievalue",
  1698                      "negate": false
  1699                  },
  1700                  {
  1701                      "caseSensitive": false,
  1702                      "matchOperator": "equals",
  1703                      "matchType": "extension",
  1704                      "matchValue": "txt",
  1705                      "negate": false
  1706                  }
  1707              ],
  1708              "name": "rul3",
  1709              "redirectURL": "/abc/sss",
  1710              "start": 0,
  1711              "forwardSettings": {
  1712                  "originId": "some_origin",
  1713                  "percent": 10
  1714              }
  1715          },
  1716          {
  1717              "type": "cdMatchRule",
  1718              "end": 0,
  1719              "id": 0,
  1720              "matchURL": "ddd.aaa",
  1721              "name": "rule 2",
  1722              "redirectURL": "sss.com",
  1723              "start": 0,
  1724              "statusCode": 301,
  1725              "useIncomingQueryString": true,
  1726              "useRelativeUrl": "none"
  1727          },
  1728          {
  1729              "type": "cdMatchRule",
  1730              "end": 0,
  1731              "id": 0,
  1732              "matchURL": "abc.com",
  1733              "name": "r1",
  1734              "redirectURL": "/ddd",
  1735              "start": 0,
  1736              "statusCode": 301,
  1737              "useIncomingQueryString": false,
  1738              "useIncomingSchemeAndHost": true,
  1739              "useRelativeUrl": "copy_scheme_hostname"
  1740          }
  1741      ],
  1742      "policyId": 276858,
  1743      "revisionId": 4815968,
  1744      "rulesLocked": false,
  1745      "version": 6
  1746  }`,
  1747  			expectedPath: "/cloudlets/api/v2/policies/276858/versions",
  1748  			expectedResponse: &PolicyVersion{
  1749  				Activations:      []PolicyActivation{},
  1750  				CreateDate:       1629981355165,
  1751  				CreatedBy:        "jsmith",
  1752  				Deleted:          false,
  1753  				Description:      "",
  1754  				LastModifiedBy:   "jsmith",
  1755  				LastModifiedDate: 1629981355165,
  1756  				Location:         "/cloudlets/api/v2/policies/276858/versions/6",
  1757  				MatchRuleFormat:  "1.0",
  1758  				PolicyID:         276858,
  1759  				RevisionID:       4815968,
  1760  				RulesLocked:      false,
  1761  				Version:          6,
  1762  				MatchRules: MatchRules{
  1763  					&MatchRulePR{
  1764  						Type:     "cdMatchRule",
  1765  						End:      0,
  1766  						ID:       0,
  1767  						MatchURL: "",
  1768  						Name:     "rul3",
  1769  						Start:    0,
  1770  						ForwardSettings: ForwardSettingsPR{
  1771  							OriginID: "some_origin",
  1772  							Percent:  10,
  1773  						},
  1774  						Matches: []MatchCriteriaPR{
  1775  							{
  1776  								MatchType:     "hostname",
  1777  								MatchValue:    "3333.dom",
  1778  								MatchOperator: "equals",
  1779  								CaseSensitive: true,
  1780  								Negate:        false,
  1781  							},
  1782  							{
  1783  								MatchType:     "cookie",
  1784  								MatchValue:    "cookie=cookievalue",
  1785  								MatchOperator: "equals",
  1786  								Negate:        false,
  1787  								CaseSensitive: false,
  1788  							},
  1789  							{
  1790  								MatchType:     "extension",
  1791  								MatchValue:    "txt",
  1792  								MatchOperator: "equals",
  1793  								Negate:        false,
  1794  								CaseSensitive: false,
  1795  							},
  1796  						},
  1797  					},
  1798  					&MatchRulePR{
  1799  						Type:     "cdMatchRule",
  1800  						End:      0,
  1801  						ID:       0,
  1802  						MatchURL: "ddd.aaa",
  1803  						Name:     "rule 2",
  1804  						Start:    0,
  1805  					},
  1806  					&MatchRulePR{
  1807  						Type:     "cdMatchRule",
  1808  						End:      0,
  1809  						ID:       0,
  1810  						MatchURL: "abc.com",
  1811  						Name:     "r1",
  1812  						Start:    0,
  1813  					},
  1814  				},
  1815  			},
  1816  		},
  1817  		"201 created, complex PR with objectMatchValue - simple": {
  1818  			request: CreatePolicyVersionRequest{
  1819  				CreatePolicyVersion: CreatePolicyVersion{
  1820  					MatchRules: MatchRules{
  1821  						&MatchRulePR{
  1822  							Start: 0,
  1823  							End:   0,
  1824  							Type:  "cdMatchRule",
  1825  							Name:  "rul3",
  1826  							ID:    0,
  1827  							ForwardSettings: ForwardSettingsPR{
  1828  								OriginID: "some_origin",
  1829  								Percent:  10,
  1830  							},
  1831  							Matches: []MatchCriteriaPR{
  1832  								{
  1833  									CaseSensitive: true,
  1834  									MatchOperator: "equals",
  1835  									MatchType:     "method",
  1836  									Negate:        false,
  1837  									ObjectMatchValue: &ObjectMatchValueSimple{
  1838  										Type:  "simple",
  1839  										Value: []string{"GET"},
  1840  									},
  1841  								},
  1842  							},
  1843  						},
  1844  					},
  1845  				},
  1846  				PolicyID: 276858,
  1847  			},
  1848  			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}}]}`,
  1849  			responseStatus: http.StatusCreated,
  1850  			responseBody: `{
  1851      "activations": [],
  1852      "createDate": 1629981355165,
  1853      "createdBy": "jsmith",
  1854      "deleted": false,
  1855      "description": null,
  1856      "lastModifiedBy": "jsmith",
  1857      "lastModifiedDate": 1629981355165,
  1858      "location": "/cloudlets/api/v2/policies/276858/versions/6",
  1859      "matchRuleFormat": "1.0",
  1860      "matchRules": [
  1861          {
  1862              "type": "cdMatchRule",
  1863              "end": 0,
  1864              "id": 0,
  1865              "matchURL": null,
  1866              "matches": [
  1867                  {
  1868                      "caseSensitive": true,
  1869                      "matchOperator": "equals",
  1870                      "matchType": "method",
  1871                      "negate": false,
  1872                      "objectMatchValue": {
  1873                          "type": "simple",
  1874                          "value": [
  1875                              "GET"
  1876                          ]
  1877                      }
  1878                  }
  1879              ],
  1880              "name": "rul3",
  1881              "redirectURL": "/abc/sss",
  1882              "start": 0,
  1883              "forwardSettings": {
  1884                  "originId": "some_origin",
  1885                  "percent": 10
  1886              }
  1887          }
  1888      ],
  1889      "policyId": 276858,
  1890      "revisionId": 4815968,
  1891      "rulesLocked": false,
  1892      "version": 6
  1893  }`,
  1894  			expectedPath: "/cloudlets/api/v2/policies/276858/versions",
  1895  			expectedResponse: &PolicyVersion{
  1896  				Activations:      []PolicyActivation{},
  1897  				CreateDate:       1629981355165,
  1898  				CreatedBy:        "jsmith",
  1899  				Deleted:          false,
  1900  				Description:      "",
  1901  				LastModifiedBy:   "jsmith",
  1902  				LastModifiedDate: 1629981355165,
  1903  				Location:         "/cloudlets/api/v2/policies/276858/versions/6",
  1904  				MatchRuleFormat:  "1.0",
  1905  				PolicyID:         276858,
  1906  				RevisionID:       4815968,
  1907  				RulesLocked:      false,
  1908  				Version:          6,
  1909  				MatchRules: MatchRules{
  1910  					&MatchRulePR{
  1911  						Type:     "cdMatchRule",
  1912  						End:      0,
  1913  						ID:       0,
  1914  						MatchURL: "",
  1915  						Name:     "rul3",
  1916  						Start:    0,
  1917  						ForwardSettings: ForwardSettingsPR{
  1918  							OriginID: "some_origin",
  1919  							Percent:  10,
  1920  						},
  1921  						Matches: []MatchCriteriaPR{
  1922  							{
  1923  								CaseSensitive: true,
  1924  								MatchOperator: "equals",
  1925  								MatchType:     "method",
  1926  								Negate:        false,
  1927  								ObjectMatchValue: &ObjectMatchValueSimple{
  1928  									Type:  "simple",
  1929  									Value: []string{"GET"},
  1930  								},
  1931  							},
  1932  						},
  1933  					},
  1934  				},
  1935  			},
  1936  		},
  1937  		"201 created, complex PR with objectMatchValue - object": {
  1938  			request: CreatePolicyVersionRequest{
  1939  				CreatePolicyVersion: CreatePolicyVersion{
  1940  					MatchRules: MatchRules{
  1941  						&MatchRulePR{
  1942  							Start: 0,
  1943  							End:   0,
  1944  							Type:  "cdMatchRule",
  1945  							Name:  "rul3",
  1946  							ID:    0,
  1947  							ForwardSettings: ForwardSettingsPR{
  1948  								OriginID: "some_origin",
  1949  								Percent:  10,
  1950  							},
  1951  							Matches: []MatchCriteriaPR{
  1952  								{
  1953  									MatchOperator: "equals",
  1954  									MatchType:     "header",
  1955  									Negate:        false,
  1956  									ObjectMatchValue: &ObjectMatchValueObject{
  1957  										Type: "object",
  1958  										Name: "PR",
  1959  										Options: &Options{
  1960  											Value: []string{
  1961  												"text/html*",
  1962  												"text/css*",
  1963  												"application/x-javascript*",
  1964  											},
  1965  											ValueHasWildcard: true,
  1966  										},
  1967  									},
  1968  								},
  1969  							},
  1970  						},
  1971  					},
  1972  				},
  1973  				PolicyID: 276858,
  1974  			},
  1975  			responseStatus: http.StatusCreated,
  1976  			responseBody: `{
  1977      "activations": [],
  1978      "createDate": 1629981355165,
  1979      "createdBy": "jsmith",
  1980      "deleted": false,
  1981      "description": null,
  1982      "lastModifiedBy": "jsmith",
  1983      "lastModifiedDate": 1629981355165,
  1984      "location": "/cloudlets/api/v2/policies/276858/versions/6",
  1985      "matchRuleFormat": "1.0",
  1986      "matchRules": [
  1987          {
  1988              "type": "cdMatchRule",
  1989              "end": 0,
  1990              "id": 0,
  1991              "matchURL": null,
  1992              "matches": [
  1993                  {
  1994                      "matchOperator": "equals",
  1995                      "matchType": "hostname",
  1996                      "negate": false,
  1997  					"objectMatchValue": {
  1998  						"type": "object",
  1999  						"name": "PR",
  2000  						"options": {
  2001  							"value": [
  2002  								"text/html*",
  2003                                  "text/css*",
  2004                                  "application/x-javascript*"
  2005  							],
  2006  							"valueHasWildcard": true
  2007  						}
  2008  					}
  2009                  }
  2010              ],
  2011              "name": "rul3",
  2012              "redirectURL": "/abc/sss",
  2013              "start": 0,
  2014              "forwardSettings": {
  2015                  "originId": "some_origin",
  2016                  "percent": 10
  2017              }
  2018          }
  2019      ],
  2020      "policyId": 276858,
  2021      "revisionId": 4815968,
  2022      "rulesLocked": false,
  2023      "version": 6
  2024  }`,
  2025  			expectedPath: "/cloudlets/api/v2/policies/276858/versions",
  2026  			expectedResponse: &PolicyVersion{
  2027  				Activations:      []PolicyActivation{},
  2028  				CreateDate:       1629981355165,
  2029  				CreatedBy:        "jsmith",
  2030  				Deleted:          false,
  2031  				Description:      "",
  2032  				LastModifiedBy:   "jsmith",
  2033  				LastModifiedDate: 1629981355165,
  2034  				Location:         "/cloudlets/api/v2/policies/276858/versions/6",
  2035  				MatchRuleFormat:  "1.0",
  2036  				PolicyID:         276858,
  2037  				RevisionID:       4815968,
  2038  				RulesLocked:      false,
  2039  				Version:          6,
  2040  				MatchRules: MatchRules{
  2041  					&MatchRulePR{
  2042  						Type:     "cdMatchRule",
  2043  						End:      0,
  2044  						ID:       0,
  2045  						MatchURL: "",
  2046  						Name:     "rul3",
  2047  						Start:    0,
  2048  						ForwardSettings: ForwardSettingsPR{
  2049  							OriginID: "some_origin",
  2050  							Percent:  10,
  2051  						},
  2052  						Matches: []MatchCriteriaPR{
  2053  							{
  2054  								MatchOperator: "equals",
  2055  								MatchType:     "hostname",
  2056  								Negate:        false,
  2057  								ObjectMatchValue: &ObjectMatchValueObject{
  2058  									Type: "object",
  2059  									Name: "PR",
  2060  									Options: &Options{
  2061  										Value: []string{
  2062  											"text/html*",
  2063  											"text/css*",
  2064  											"application/x-javascript*",
  2065  										},
  2066  										ValueHasWildcard: true,
  2067  									},
  2068  								},
  2069  							},
  2070  						},
  2071  					},
  2072  				},
  2073  			},
  2074  		},
  2075  		"validation error, complex PR with unavailable objectMatchValue type - range": {
  2076  			request: CreatePolicyVersionRequest{
  2077  				CreatePolicyVersion: CreatePolicyVersion{
  2078  					MatchRules: MatchRules{
  2079  						&MatchRulePR{
  2080  							Start: 0,
  2081  							End:   0,
  2082  							Type:  "cdMatchRule",
  2083  							Name:  "rul3",
  2084  							ID:    0,
  2085  							ForwardSettings: ForwardSettingsPR{
  2086  								OriginID: "some_origin",
  2087  								Percent:  10,
  2088  							},
  2089  							Matches: []MatchCriteriaPR{
  2090  								{
  2091  									MatchOperator: "equals",
  2092  									MatchType:     "header",
  2093  									Negate:        false,
  2094  									ObjectMatchValue: &ObjectMatchValueRange{
  2095  										Type:  "range",
  2096  										Value: []int64{1, 50},
  2097  									},
  2098  								},
  2099  							},
  2100  						},
  2101  					},
  2102  				},
  2103  				PolicyID: 276858,
  2104  			},
  2105  			withError: ErrStructValidation,
  2106  		},
  2107  		"validation error, complex PR missing forwardSettings": {
  2108  			request: CreatePolicyVersionRequest{
  2109  				CreatePolicyVersion: CreatePolicyVersion{
  2110  					MatchRules: MatchRules{
  2111  						&MatchRulePR{
  2112  							Start: 0,
  2113  							End:   0,
  2114  							Type:  "cdMatchRule",
  2115  							Name:  "rul3",
  2116  							ID:    0,
  2117  							ForwardSettings: ForwardSettingsPR{
  2118  								OriginID: "some_origin",
  2119  								Percent:  10,
  2120  							},
  2121  							Matches: []MatchCriteriaPR{
  2122  								{
  2123  									MatchType:     "hostname",
  2124  									MatchValue:    "3333.dom",
  2125  									MatchOperator: "equals",
  2126  									CaseSensitive: true,
  2127  									Negate:        false,
  2128  								},
  2129  								{
  2130  									MatchType:     "cookie",
  2131  									MatchValue:    "cookie=cookievalue",
  2132  									MatchOperator: "equals",
  2133  									Negate:        false,
  2134  									CaseSensitive: false,
  2135  								},
  2136  								{
  2137  									MatchType:     "extension",
  2138  									MatchValue:    "txt",
  2139  									MatchOperator: "equals",
  2140  									Negate:        false,
  2141  									CaseSensitive: false,
  2142  								},
  2143  							},
  2144  						},
  2145  						&MatchRulePR{
  2146  							Start:    0,
  2147  							End:      0,
  2148  							Type:     "cdMatchRule",
  2149  							Name:     "rule 2",
  2150  							MatchURL: "ddd.aaa",
  2151  							ID:       0,
  2152  						},
  2153  						&MatchRulePR{
  2154  							Type:     "cdMatchRule",
  2155  							ID:       0,
  2156  							Name:     "r1",
  2157  							Start:    0,
  2158  							End:      0,
  2159  							MatchURL: "abc.com",
  2160  							ForwardSettings: ForwardSettingsPR{
  2161  								OriginID: "some_origin",
  2162  								Percent:  10,
  2163  							},
  2164  						},
  2165  					},
  2166  				},
  2167  				PolicyID: 276858,
  2168  			},
  2169  			withError: ErrStructValidation,
  2170  		},
  2171  
  2172  		"201 created, complex ER": {
  2173  			request: CreatePolicyVersionRequest{
  2174  				CreatePolicyVersion: CreatePolicyVersion{
  2175  					MatchRules: MatchRules{
  2176  						&MatchRuleER{
  2177  							Start:          0,
  2178  							End:            0,
  2179  							Type:           "erMatchRule",
  2180  							UseRelativeURL: "copy_scheme_hostname",
  2181  							Name:           "rul3",
  2182  							StatusCode:     307,
  2183  							RedirectURL:    "/abc/sss",
  2184  							ID:             0,
  2185  							Matches: []MatchCriteriaER{
  2186  								{
  2187  									MatchType:     "hostname",
  2188  									MatchValue:    "3333.dom",
  2189  									MatchOperator: "equals",
  2190  									CaseSensitive: true,
  2191  									Negate:        false,
  2192  								},
  2193  								{
  2194  									MatchType:     "cookie",
  2195  									MatchValue:    "cookie=cookievalue",
  2196  									MatchOperator: "equals",
  2197  									Negate:        false,
  2198  									CaseSensitive: false,
  2199  								},
  2200  								{
  2201  									MatchType:     "extension",
  2202  									MatchValue:    "txt",
  2203  									MatchOperator: "equals",
  2204  									Negate:        false,
  2205  									CaseSensitive: false,
  2206  								},
  2207  							},
  2208  						},
  2209  						&MatchRuleER{
  2210  							Start:                  0,
  2211  							End:                    0,
  2212  							Type:                   "erMatchRule",
  2213  							UseRelativeURL:         "none",
  2214  							Name:                   "rule 2",
  2215  							MatchURL:               "ddd.aaa",
  2216  							RedirectURL:            "sss.com",
  2217  							StatusCode:             301,
  2218  							UseIncomingQueryString: true,
  2219  							ID:                     0,
  2220  						},
  2221  						&MatchRuleER{
  2222  							Type:                     "erMatchRule",
  2223  							ID:                       0,
  2224  							Name:                     "r1",
  2225  							Start:                    0,
  2226  							End:                      0,
  2227  							MatchURL:                 "abc.com",
  2228  							StatusCode:               301,
  2229  							RedirectURL:              "/ddd",
  2230  							UseIncomingQueryString:   false,
  2231  							UseIncomingSchemeAndHost: true,
  2232  							UseRelativeURL:           "copy_scheme_hostname",
  2233  						},
  2234  					},
  2235  				},
  2236  				PolicyID: 276858,
  2237  			},
  2238  			responseStatus: http.StatusCreated,
  2239  			responseBody: `{
  2240      "activations": [],
  2241      "createDate": 1629981355165,
  2242      "createdBy": "jsmith",
  2243      "deleted": false,
  2244      "description": null,
  2245      "lastModifiedBy": "jsmith",
  2246      "lastModifiedDate": 1629981355165,
  2247      "location": "/cloudlets/api/v2/policies/276858/versions/6",
  2248      "matchRuleFormat": "1.0",
  2249      "matchRules": [
  2250          {
  2251              "type": "erMatchRule",
  2252              "end": 0,
  2253              "id": 0,
  2254              "matchURL": null,
  2255              "matches": [
  2256                  {
  2257                      "caseSensitive": true,
  2258                      "matchOperator": "equals",
  2259                      "matchType": "hostname",
  2260                      "matchValue": "3333.dom",
  2261                      "negate": false
  2262                  },
  2263                  {
  2264                      "caseSensitive": false,
  2265                      "matchOperator": "equals",
  2266                      "matchType": "cookie",
  2267                      "matchValue": "cookie=cookievalue",
  2268                      "negate": false
  2269                  },
  2270                  {
  2271                      "caseSensitive": false,
  2272                      "matchOperator": "equals",
  2273                      "matchType": "extension",
  2274                      "matchValue": "txt",
  2275                      "negate": false
  2276                  }
  2277              ],
  2278              "name": "rul3",
  2279              "redirectURL": "/abc/sss",
  2280              "start": 0,
  2281              "statusCode": 307,
  2282              "useIncomingQueryString": false,
  2283              "useIncomingSchemeAndHost": true,
  2284              "useRelativeUrl": "copy_scheme_hostname"
  2285          },
  2286          {
  2287              "type": "erMatchRule",
  2288              "end": 0,
  2289              "id": 0,
  2290              "matchURL": "ddd.aaa",
  2291              "name": "rule 2",
  2292              "redirectURL": "sss.com",
  2293              "start": 0,
  2294              "statusCode": 301,
  2295              "useIncomingQueryString": true,
  2296              "useRelativeUrl": "none"
  2297          },
  2298          {
  2299              "type": "erMatchRule",
  2300              "end": 0,
  2301              "id": 0,
  2302              "matchURL": "abc.com",
  2303              "name": "r1",
  2304              "redirectURL": "/ddd",
  2305              "start": 0,
  2306              "statusCode": 301,
  2307              "useIncomingQueryString": false,
  2308              "useIncomingSchemeAndHost": true,
  2309              "useRelativeUrl": "copy_scheme_hostname"
  2310          }
  2311      ],
  2312      "policyId": 276858,
  2313      "revisionId": 4815968,
  2314      "rulesLocked": false,
  2315      "version": 6
  2316  }`,
  2317  			expectedPath: "/cloudlets/api/v2/policies/276858/versions",
  2318  			expectedResponse: &PolicyVersion{
  2319  				Activations:      []PolicyActivation{},
  2320  				CreateDate:       1629981355165,
  2321  				CreatedBy:        "jsmith",
  2322  				Deleted:          false,
  2323  				Description:      "",
  2324  				LastModifiedBy:   "jsmith",
  2325  				LastModifiedDate: 1629981355165,
  2326  				Location:         "/cloudlets/api/v2/policies/276858/versions/6",
  2327  				MatchRuleFormat:  "1.0",
  2328  				PolicyID:         276858,
  2329  				RevisionID:       4815968,
  2330  				RulesLocked:      false,
  2331  				Version:          6,
  2332  				MatchRules: MatchRules{
  2333  					&MatchRuleER{
  2334  						Type:                     "erMatchRule",
  2335  						End:                      0,
  2336  						ID:                       0,
  2337  						MatchURL:                 "",
  2338  						Name:                     "rul3",
  2339  						RedirectURL:              "/abc/sss",
  2340  						Start:                    0,
  2341  						StatusCode:               307,
  2342  						UseIncomingQueryString:   false,
  2343  						UseIncomingSchemeAndHost: true,
  2344  						UseRelativeURL:           "copy_scheme_hostname",
  2345  						Matches: []MatchCriteriaER{
  2346  							{
  2347  								MatchType:     "hostname",
  2348  								MatchValue:    "3333.dom",
  2349  								MatchOperator: "equals",
  2350  								CaseSensitive: true,
  2351  								Negate:        false,
  2352  							},
  2353  							{
  2354  								MatchType:     "cookie",
  2355  								MatchValue:    "cookie=cookievalue",
  2356  								MatchOperator: "equals",
  2357  								Negate:        false,
  2358  								CaseSensitive: false,
  2359  							},
  2360  							{
  2361  								MatchType:     "extension",
  2362  								MatchValue:    "txt",
  2363  								MatchOperator: "equals",
  2364  								Negate:        false,
  2365  								CaseSensitive: false,
  2366  							},
  2367  						},
  2368  					},
  2369  					&MatchRuleER{
  2370  						Type:                   "erMatchRule",
  2371  						End:                    0,
  2372  						ID:                     0,
  2373  						MatchURL:               "ddd.aaa",
  2374  						Name:                   "rule 2",
  2375  						RedirectURL:            "sss.com",
  2376  						Start:                  0,
  2377  						StatusCode:             301,
  2378  						UseIncomingQueryString: true,
  2379  						UseRelativeURL:         "none",
  2380  					},
  2381  					&MatchRuleER{
  2382  						Type:                     "erMatchRule",
  2383  						End:                      0,
  2384  						ID:                       0,
  2385  						MatchURL:                 "abc.com",
  2386  						Name:                     "r1",
  2387  						RedirectURL:              "/ddd",
  2388  						Start:                    0,
  2389  						StatusCode:               301,
  2390  						UseIncomingQueryString:   false,
  2391  						UseIncomingSchemeAndHost: true,
  2392  						UseRelativeURL:           "copy_scheme_hostname",
  2393  					},
  2394  				},
  2395  			},
  2396  		},
  2397  		"201 created, complex ER with objectMatchValue - simple": {
  2398  			request: CreatePolicyVersionRequest{
  2399  				CreatePolicyVersion: CreatePolicyVersion{
  2400  					MatchRules: MatchRules{
  2401  						&MatchRuleER{
  2402  							Start:          0,
  2403  							End:            0,
  2404  							Type:           "erMatchRule",
  2405  							UseRelativeURL: "copy_scheme_hostname",
  2406  							Name:           "rul3",
  2407  							StatusCode:     307,
  2408  							RedirectURL:    "/abc/sss",
  2409  							ID:             0,
  2410  							Matches: []MatchCriteriaER{
  2411  								{
  2412  									CaseSensitive: true,
  2413  									MatchOperator: "equals",
  2414  									MatchType:     "method",
  2415  									Negate:        false,
  2416  									ObjectMatchValue: &ObjectMatchValueSimple{
  2417  										Type:  "simple",
  2418  										Value: []string{"GET"},
  2419  									},
  2420  								},
  2421  							},
  2422  						},
  2423  					},
  2424  				},
  2425  				PolicyID: 276858,
  2426  			},
  2427  			responseStatus: http.StatusCreated,
  2428  			responseBody: `{
  2429      "activations": [],
  2430      "createDate": 1629981355165,
  2431      "createdBy": "jsmith",
  2432      "deleted": false,
  2433      "description": null,
  2434      "lastModifiedBy": "jsmith",
  2435      "lastModifiedDate": 1629981355165,
  2436      "location": "/cloudlets/api/v2/policies/276858/versions/6",
  2437      "matchRuleFormat": "1.0",
  2438      "matchRules": [
  2439          {
  2440              "type": "erMatchRule",
  2441              "end": 0,
  2442              "id": 0,
  2443              "matchURL": null,
  2444              "matches": [
  2445                  {
  2446                      "caseSensitive": true,
  2447                      "matchOperator": "equals",
  2448                      "matchType": "method",
  2449                      "negate": false,
  2450                      "objectMatchValue": {
  2451                          "type": "simple",
  2452                          "value": [
  2453                              "GET"
  2454                          ]
  2455                      }
  2456                  }
  2457              ],
  2458              "name": "rul3",
  2459              "redirectURL": "/abc/sss",
  2460              "start": 0,
  2461              "statusCode": 307,
  2462              "useIncomingQueryString": false,
  2463              "useIncomingSchemeAndHost": true,
  2464              "useRelativeUrl": "copy_scheme_hostname"
  2465          }
  2466      ],
  2467      "policyId": 276858,
  2468      "revisionId": 4815968,
  2469      "rulesLocked": false,
  2470      "version": 6
  2471  }`,
  2472  			expectedPath: "/cloudlets/api/v2/policies/276858/versions",
  2473  			expectedResponse: &PolicyVersion{
  2474  				Activations:      []PolicyActivation{},
  2475  				CreateDate:       1629981355165,
  2476  				CreatedBy:        "jsmith",
  2477  				Deleted:          false,
  2478  				Description:      "",
  2479  				LastModifiedBy:   "jsmith",
  2480  				LastModifiedDate: 1629981355165,
  2481  				Location:         "/cloudlets/api/v2/policies/276858/versions/6",
  2482  				MatchRuleFormat:  "1.0",
  2483  				PolicyID:         276858,
  2484  				RevisionID:       4815968,
  2485  				RulesLocked:      false,
  2486  				Version:          6,
  2487  				MatchRules: MatchRules{
  2488  					&MatchRuleER{
  2489  						Type:                     "erMatchRule",
  2490  						End:                      0,
  2491  						ID:                       0,
  2492  						MatchURL:                 "",
  2493  						Name:                     "rul3",
  2494  						RedirectURL:              "/abc/sss",
  2495  						Start:                    0,
  2496  						StatusCode:               307,
  2497  						UseIncomingQueryString:   false,
  2498  						UseIncomingSchemeAndHost: true,
  2499  						UseRelativeURL:           "copy_scheme_hostname",
  2500  						Matches: []MatchCriteriaER{
  2501  							{
  2502  								CaseSensitive: true,
  2503  								MatchOperator: "equals",
  2504  								MatchType:     "method",
  2505  								Negate:        false,
  2506  								ObjectMatchValue: &ObjectMatchValueSimple{
  2507  									Type:  "simple",
  2508  									Value: []string{"GET"},
  2509  								},
  2510  							},
  2511  						},
  2512  					},
  2513  				},
  2514  			},
  2515  		},
  2516  		"201 created, complex ER with objectMatchValue - object": {
  2517  			request: CreatePolicyVersionRequest{
  2518  				CreatePolicyVersion: CreatePolicyVersion{
  2519  					MatchRules: MatchRules{
  2520  						&MatchRuleER{
  2521  							Start:          0,
  2522  							End:            0,
  2523  							Type:           "erMatchRule",
  2524  							UseRelativeURL: "copy_scheme_hostname",
  2525  							Name:           "rul3",
  2526  							StatusCode:     307,
  2527  							RedirectURL:    "/abc/sss",
  2528  							ID:             0,
  2529  							Matches: []MatchCriteriaER{
  2530  								{
  2531  									MatchOperator: "equals",
  2532  									MatchType:     "header",
  2533  									Negate:        false,
  2534  									ObjectMatchValue: &ObjectMatchValueObject{
  2535  										Type: "object",
  2536  										Name: "ER",
  2537  										Options: &Options{
  2538  											Value: []string{
  2539  												"text/html*",
  2540  												"text/css*",
  2541  												"application/x-javascript*",
  2542  											},
  2543  											ValueHasWildcard: true,
  2544  										},
  2545  									},
  2546  								},
  2547  							},
  2548  						},
  2549  					},
  2550  				},
  2551  				PolicyID: 276858,
  2552  			},
  2553  			responseStatus: http.StatusCreated,
  2554  			responseBody: `{
  2555      "activations": [],
  2556      "createDate": 1629981355165,
  2557      "createdBy": "jsmith",
  2558      "deleted": false,
  2559      "description": null,
  2560      "lastModifiedBy": "jsmith",
  2561      "lastModifiedDate": 1629981355165,
  2562      "location": "/cloudlets/api/v2/policies/276858/versions/6",
  2563      "matchRuleFormat": "1.0",
  2564      "matchRules": [
  2565          {
  2566              "type": "erMatchRule",
  2567              "end": 0,
  2568              "id": 0,
  2569              "matchURL": null,
  2570              "matches": [
  2571                  {
  2572                      "matchOperator": "equals",
  2573                      "matchType": "hostname",
  2574                      "negate": false,
  2575  					"objectMatchValue": {
  2576  						"type": "object",
  2577  						"name": "ER",
  2578  						"options": {
  2579  							"value": [
  2580  								"text/html*",
  2581                                  "text/css*",
  2582                                  "application/x-javascript*"
  2583  							],
  2584  							"valueHasWildcard": true
  2585  						}
  2586  					}
  2587                  }
  2588              ],
  2589              "name": "rul3",
  2590              "redirectURL": "/abc/sss",
  2591              "start": 0,
  2592              "statusCode": 307,
  2593              "useIncomingQueryString": false,
  2594              "useIncomingSchemeAndHost": true,
  2595              "useRelativeUrl": "copy_scheme_hostname"
  2596          }
  2597      ],
  2598      "policyId": 276858,
  2599      "revisionId": 4815968,
  2600      "rulesLocked": false,
  2601      "version": 6
  2602  }`,
  2603  			expectedPath: "/cloudlets/api/v2/policies/276858/versions",
  2604  			expectedResponse: &PolicyVersion{
  2605  				Activations:      []PolicyActivation{},
  2606  				CreateDate:       1629981355165,
  2607  				CreatedBy:        "jsmith",
  2608  				Deleted:          false,
  2609  				Description:      "",
  2610  				LastModifiedBy:   "jsmith",
  2611  				LastModifiedDate: 1629981355165,
  2612  				Location:         "/cloudlets/api/v2/policies/276858/versions/6",
  2613  				MatchRuleFormat:  "1.0",
  2614  				PolicyID:         276858,
  2615  				RevisionID:       4815968,
  2616  				RulesLocked:      false,
  2617  				Version:          6,
  2618  				MatchRules: MatchRules{
  2619  					&MatchRuleER{
  2620  						Type:                     "erMatchRule",
  2621  						End:                      0,
  2622  						ID:                       0,
  2623  						MatchURL:                 "",
  2624  						Name:                     "rul3",
  2625  						RedirectURL:              "/abc/sss",
  2626  						Start:                    0,
  2627  						StatusCode:               307,
  2628  						UseIncomingQueryString:   false,
  2629  						UseIncomingSchemeAndHost: true,
  2630  						UseRelativeURL:           "copy_scheme_hostname",
  2631  						Matches: []MatchCriteriaER{
  2632  							{
  2633  								MatchOperator: "equals",
  2634  								MatchType:     "hostname",
  2635  								Negate:        false,
  2636  								ObjectMatchValue: &ObjectMatchValueObject{
  2637  									Type: "object",
  2638  									Name: "ER",
  2639  									Options: &Options{
  2640  										Value: []string{
  2641  											"text/html*",
  2642  											"text/css*",
  2643  											"application/x-javascript*",
  2644  										},
  2645  										ValueHasWildcard: true,
  2646  									},
  2647  								},
  2648  							},
  2649  						},
  2650  					},
  2651  				},
  2652  			},
  2653  		},
  2654  		"201 created, ER with empty/no useRelativeURL": {
  2655  			request: CreatePolicyVersionRequest{
  2656  				CreatePolicyVersion: CreatePolicyVersion{
  2657  					MatchRules: MatchRules{
  2658  						&MatchRuleER{
  2659  							Start:                  0,
  2660  							End:                    0,
  2661  							Type:                   "erMatchRule",
  2662  							Name:                   "rule 2",
  2663  							MatchURL:               "ddd.aaa",
  2664  							RedirectURL:            "sss.com",
  2665  							StatusCode:             301,
  2666  							UseIncomingQueryString: true,
  2667  							ID:                     0,
  2668  						},
  2669  						&MatchRuleER{
  2670  							Type:                     "erMatchRule",
  2671  							ID:                       0,
  2672  							Name:                     "r1",
  2673  							Start:                    0,
  2674  							End:                      0,
  2675  							MatchURL:                 "abc.com",
  2676  							StatusCode:               301,
  2677  							RedirectURL:              "/ddd",
  2678  							UseIncomingQueryString:   false,
  2679  							UseIncomingSchemeAndHost: true,
  2680  							UseRelativeURL:           "",
  2681  						},
  2682  						&MatchRuleER{
  2683  							Start:       0,
  2684  							End:         0,
  2685  							Type:        "erMatchRule",
  2686  							Name:        "rul3",
  2687  							StatusCode:  307,
  2688  							RedirectURL: "/abc/sss",
  2689  							ID:          0,
  2690  						},
  2691  					},
  2692  				},
  2693  				PolicyID: 276858,
  2694  			},
  2695  			responseStatus: http.StatusCreated,
  2696  			responseBody: `{
  2697      "activations": [],
  2698      "createDate": 1629981355165,
  2699      "createdBy": "jsmith",
  2700      "deleted": false,
  2701      "description": null,
  2702      "lastModifiedBy": "jsmith",
  2703      "lastModifiedDate": 1629981355165,
  2704      "location": "/cloudlets/api/v2/policies/276858/versions/6",
  2705      "matchRuleFormat": "1.0",
  2706      "matchRules": [
  2707          {
  2708              "type": "erMatchRule",
  2709              "end": 0,
  2710              "id": 0,
  2711              "matchURL": "ddd.aaa",
  2712              "name": "rule 2",
  2713              "redirectURL": "sss.com",
  2714              "start": 0,
  2715              "statusCode": 301,
  2716              "useIncomingQueryString": true
  2717          },
  2718          {
  2719              "type": "erMatchRule",
  2720              "end": 0,
  2721              "id": 0,
  2722              "matchURL": "abc.com",
  2723              "name": "r1",
  2724              "redirectURL": "/ddd",
  2725              "start": 0,
  2726              "statusCode": 301,
  2727              "useIncomingQueryString": false,
  2728              "useIncomingSchemeAndHost": true,
  2729              "useRelativeUrl": "copy_scheme_hostname"
  2730          },
  2731  		{
  2732  			"type": "erMatchRule",
  2733              "end": 0,
  2734              "id": 0,
  2735  			"name": "rul3",
  2736  			"redirectURL": "/abc/sss",
  2737  			"start": 0,
  2738  			"statusCode": 307
  2739  		}
  2740      ],
  2741      "policyId": 276858,
  2742      "revisionId": 4815968,
  2743      "rulesLocked": false,
  2744      "version": 6
  2745  }`,
  2746  			expectedPath: "/cloudlets/api/v2/policies/276858/versions",
  2747  			expectedResponse: &PolicyVersion{
  2748  				Activations:      []PolicyActivation{},
  2749  				CreateDate:       1629981355165,
  2750  				CreatedBy:        "jsmith",
  2751  				Deleted:          false,
  2752  				Description:      "",
  2753  				LastModifiedBy:   "jsmith",
  2754  				LastModifiedDate: 1629981355165,
  2755  				Location:         "/cloudlets/api/v2/policies/276858/versions/6",
  2756  				MatchRuleFormat:  "1.0",
  2757  				PolicyID:         276858,
  2758  				RevisionID:       4815968,
  2759  				RulesLocked:      false,
  2760  				Version:          6,
  2761  				MatchRules: MatchRules{
  2762  					&MatchRuleER{
  2763  						Type:                   "erMatchRule",
  2764  						End:                    0,
  2765  						ID:                     0,
  2766  						MatchURL:               "ddd.aaa",
  2767  						Name:                   "rule 2",
  2768  						RedirectURL:            "sss.com",
  2769  						Start:                  0,
  2770  						StatusCode:             301,
  2771  						UseIncomingQueryString: true,
  2772  					},
  2773  					&MatchRuleER{
  2774  						Type:                     "erMatchRule",
  2775  						End:                      0,
  2776  						ID:                       0,
  2777  						MatchURL:                 "abc.com",
  2778  						Name:                     "r1",
  2779  						RedirectURL:              "/ddd",
  2780  						Start:                    0,
  2781  						StatusCode:               301,
  2782  						UseIncomingQueryString:   false,
  2783  						UseIncomingSchemeAndHost: true,
  2784  						UseRelativeURL:           "copy_scheme_hostname",
  2785  					},
  2786  					&MatchRuleER{
  2787  						Start:       0,
  2788  						End:         0,
  2789  						Type:        "erMatchRule",
  2790  						Name:        "rul3",
  2791  						StatusCode:  307,
  2792  						RedirectURL: "/abc/sss",
  2793  						ID:          0,
  2794  					},
  2795  				},
  2796  			},
  2797  		},
  2798  		"validation error, complex ER with unavailable objectMatchValue type - range": {
  2799  			request: CreatePolicyVersionRequest{
  2800  				CreatePolicyVersion: CreatePolicyVersion{
  2801  					MatchRules: MatchRules{
  2802  						&MatchRuleER{
  2803  							Start:          0,
  2804  							End:            0,
  2805  							Type:           "erMatchRule",
  2806  							UseRelativeURL: "copy_scheme_hostname",
  2807  							Name:           "rul3",
  2808  							StatusCode:     307,
  2809  							RedirectURL:    "/abc/sss",
  2810  							ID:             0,
  2811  							Matches: []MatchCriteriaER{
  2812  								{
  2813  									MatchOperator: "equals",
  2814  									MatchType:     "header",
  2815  									Negate:        false,
  2816  									ObjectMatchValue: &ObjectMatchValueRange{
  2817  										Type:  "range",
  2818  										Value: []int64{1, 50},
  2819  									},
  2820  								},
  2821  							},
  2822  						},
  2823  					},
  2824  				},
  2825  				PolicyID: 276858,
  2826  			},
  2827  			withError: ErrStructValidation,
  2828  		},
  2829  
  2830  		"201 created, complex FR": {
  2831  			request: CreatePolicyVersionRequest{
  2832  				CreatePolicyVersion: CreatePolicyVersion{
  2833  					MatchRules: MatchRules{
  2834  						&MatchRuleFR{
  2835  							Start: 0,
  2836  							End:   0,
  2837  							Type:  "frMatchRule",
  2838  							Name:  "rul3",
  2839  							ID:    0,
  2840  							Matches: []MatchCriteriaFR{
  2841  								{
  2842  									MatchType:     "hostname",
  2843  									MatchValue:    "3333.dom",
  2844  									MatchOperator: "equals",
  2845  									CaseSensitive: true,
  2846  									Negate:        false,
  2847  								},
  2848  								{
  2849  									MatchType:     "cookie",
  2850  									MatchValue:    "cookie=cookievalue",
  2851  									MatchOperator: "equals",
  2852  									Negate:        false,
  2853  									CaseSensitive: false,
  2854  								},
  2855  								{
  2856  									MatchType:     "extension",
  2857  									MatchValue:    "txt",
  2858  									MatchOperator: "equals",
  2859  									Negate:        false,
  2860  									CaseSensitive: false,
  2861  								},
  2862  							},
  2863  							ForwardSettings: ForwardSettingsFR{
  2864  								PathAndQS:              "/test_images/simpleimg.jpg",
  2865  								UseIncomingQueryString: true,
  2866  								OriginID:               "1234",
  2867  							},
  2868  						},
  2869  						&MatchRuleFR{
  2870  							Name:     "rule 1",
  2871  							Type:     "frMatchRule",
  2872  							Start:    0,
  2873  							End:      0,
  2874  							ID:       0,
  2875  							MatchURL: "ddd.aaa",
  2876  							ForwardSettings: ForwardSettingsFR{
  2877  								PathAndQS:              "/test_images/simpleimg.jpg",
  2878  								UseIncomingQueryString: true,
  2879  								OriginID:               "1234",
  2880  							},
  2881  						},
  2882  						&MatchRuleFR{
  2883  							Name:     "rule 2",
  2884  							Type:     "frMatchRule",
  2885  							Start:    0,
  2886  							End:      0,
  2887  							ID:       0,
  2888  							MatchURL: "abc.com",
  2889  							ForwardSettings: ForwardSettingsFR{
  2890  								PathAndQS:              "/test_images/otherimage.jpg",
  2891  								UseIncomingQueryString: true,
  2892  								OriginID:               "1234",
  2893  							},
  2894  						},
  2895  					},
  2896  				},
  2897  				PolicyID: 276858,
  2898  			},
  2899  			responseStatus: http.StatusCreated,
  2900  			responseBody: `{
  2901      "activations": [],
  2902      "createDate": 1629981355165,
  2903      "createdBy": "jsmith",
  2904      "deleted": false,
  2905      "description": null,
  2906      "lastModifiedBy": "jsmith",
  2907      "lastModifiedDate": 1629981355165,
  2908      "location": "/cloudlets/api/v2/policies/276858/versions/6",
  2909      "matchRuleFormat": "1.0",
  2910      "matchRules": [
  2911          {
  2912              "type": "frMatchRule",
  2913              "akaRuleId": "893947a3d5a85c1b",
  2914              "end": 0,
  2915              "forwardSettings": {
  2916                  "pathAndQS": "/test_images/otherimage.jpg",
  2917                  "useIncomingQueryString": true,
  2918  				"originId": "1234"
  2919              },
  2920              "id": 0,
  2921              "location": "/cloudlets/api/v2/policies/276858/versions/1/rules/893947a3d5a85c1b",
  2922              "matchURL": null,
  2923              "matches": [
  2924                  {
  2925                      "caseSensitive": true,
  2926                      "matchOperator": "equals",
  2927                      "matchType": "hostname",
  2928                      "matchValue": "3333.dom",
  2929                      "negate": false
  2930                  },
  2931                  {
  2932                      "caseSensitive": false,
  2933                      "matchOperator": "equals",
  2934                      "matchType": "cookie",
  2935                      "matchValue": "cookie=cookievalue",
  2936                      "negate": false
  2937                  },
  2938                  {
  2939                      "caseSensitive": false,
  2940                      "matchOperator": "equals",
  2941                      "matchType": "extension",
  2942                      "matchValue": "txt",
  2943                      "negate": false
  2944                  }
  2945              ],
  2946              "name": "rul3",
  2947              "start": 0
  2948          },
  2949          {
  2950              "type": "frMatchRule",
  2951              "akaRuleId": "aa379d230efcded0",
  2952              "end": 0,
  2953              "forwardSettings": {
  2954                  "pathAndQS": "/test_images/simpleimg.jpg",
  2955                  "useIncomingQueryString": true,
  2956  				"originId": "1234"
  2957              },
  2958              "id": 0,
  2959              "location": "/cloudlets/api/v2/policies/276858/versions/1/rules/aa379d230efcded0",
  2960              "matchURL": "ddd.aaa",
  2961              "name": "rule 1",
  2962              "start": 0
  2963          },
  2964          {
  2965              "type": "frMatchRule",
  2966              "akaRuleId": "1afe03d843996766",
  2967              "end": 0,
  2968              "forwardSettings": {
  2969                  "pathAndQS": "/test_images/otherimage.jpg",
  2970                  "useIncomingQueryString": true,
  2971  				"originId": "1234"
  2972              },
  2973              "id": 0,
  2974              "location": "/cloudlets/api/v2/policies/276858/versions/1/rules/1afe03d843996766",
  2975              "matchURL": "abc.com",
  2976              "name": "rule 2",
  2977              "start": 0
  2978          }
  2979      ],
  2980      "policyId": 276858,
  2981      "revisionId": 4815968,
  2982      "rulesLocked": false,
  2983      "version": 6
  2984  }`,
  2985  			expectedPath: "/cloudlets/api/v2/policies/276858/versions",
  2986  			expectedResponse: &PolicyVersion{
  2987  				Activations:      []PolicyActivation{},
  2988  				CreateDate:       1629981355165,
  2989  				CreatedBy:        "jsmith",
  2990  				Deleted:          false,
  2991  				Description:      "",
  2992  				LastModifiedBy:   "jsmith",
  2993  				LastModifiedDate: 1629981355165,
  2994  				Location:         "/cloudlets/api/v2/policies/276858/versions/6",
  2995  				MatchRuleFormat:  "1.0",
  2996  				PolicyID:         276858,
  2997  				RevisionID:       4815968,
  2998  				RulesLocked:      false,
  2999  				Version:          6,
  3000  				MatchRules: MatchRules{
  3001  					&MatchRuleFR{
  3002  						Type:     "frMatchRule",
  3003  						End:      0,
  3004  						ID:       0,
  3005  						MatchURL: "",
  3006  						Name:     "rul3",
  3007  						Start:    0,
  3008  						Matches: []MatchCriteriaFR{
  3009  							{
  3010  								MatchType:     "hostname",
  3011  								MatchValue:    "3333.dom",
  3012  								MatchOperator: "equals",
  3013  								CaseSensitive: true,
  3014  								Negate:        false,
  3015  							},
  3016  							{
  3017  								MatchType:     "cookie",
  3018  								MatchValue:    "cookie=cookievalue",
  3019  								MatchOperator: "equals",
  3020  								Negate:        false,
  3021  								CaseSensitive: false,
  3022  							},
  3023  							{
  3024  								MatchType:     "extension",
  3025  								MatchValue:    "txt",
  3026  								MatchOperator: "equals",
  3027  								Negate:        false,
  3028  								CaseSensitive: false,
  3029  							},
  3030  						},
  3031  						ForwardSettings: ForwardSettingsFR{
  3032  							PathAndQS:              "/test_images/otherimage.jpg",
  3033  							UseIncomingQueryString: true,
  3034  							OriginID:               "1234",
  3035  						},
  3036  					},
  3037  					&MatchRuleFR{
  3038  						Name:     "rule 1",
  3039  						Type:     "frMatchRule",
  3040  						Start:    0,
  3041  						End:      0,
  3042  						ID:       0,
  3043  						MatchURL: "ddd.aaa",
  3044  						ForwardSettings: ForwardSettingsFR{
  3045  							PathAndQS:              "/test_images/simpleimg.jpg",
  3046  							UseIncomingQueryString: true,
  3047  							OriginID:               "1234",
  3048  						},
  3049  					},
  3050  					&MatchRuleFR{
  3051  						Name:     "rule 2",
  3052  						Type:     "frMatchRule",
  3053  						Start:    0,
  3054  						End:      0,
  3055  						ID:       0,
  3056  						MatchURL: "abc.com",
  3057  						ForwardSettings: ForwardSettingsFR{
  3058  							PathAndQS:              "/test_images/otherimage.jpg",
  3059  							UseIncomingQueryString: true,
  3060  							OriginID:               "1234",
  3061  						},
  3062  					},
  3063  				},
  3064  			},
  3065  		},
  3066  		"201 created, complex FR with objectMatchValue - object": {
  3067  			request: CreatePolicyVersionRequest{
  3068  				CreatePolicyVersion: CreatePolicyVersion{
  3069  					Description:     "New version 1630480693371",
  3070  					MatchRuleFormat: "1.0",
  3071  					MatchRules: MatchRules{
  3072  						&MatchRuleFR{
  3073  							ForwardSettings: ForwardSettingsFR{},
  3074  							Matches: []MatchCriteriaFR{
  3075  								{
  3076  									CaseSensitive: false,
  3077  									MatchOperator: "equals",
  3078  									MatchType:     "header",
  3079  									Negate:        false,
  3080  									ObjectMatchValue: &ObjectMatchValueObject{
  3081  										Type:              "object",
  3082  										Name:              "Accept",
  3083  										NameCaseSensitive: false,
  3084  										NameHasWildcard:   false,
  3085  										Options: &Options{
  3086  											Value:              []string{"asd", "qwe"},
  3087  											ValueHasWildcard:   false,
  3088  											ValueCaseSensitive: true,
  3089  											ValueEscaped:       false,
  3090  										},
  3091  									},
  3092  								},
  3093  							},
  3094  							Start: 0,
  3095  							End:   0,
  3096  							Type:  "frMatchRule",
  3097  							Name:  "rul3",
  3098  							ID:    0,
  3099  						},
  3100  					},
  3101  				},
  3102  				PolicyID: 139743,
  3103  			},
  3104  			responseStatus: http.StatusCreated,
  3105  			responseBody: `
  3106  {
  3107      "activations": [],
  3108      "createDate": 1630507099511,
  3109      "createdBy": "jsmith",
  3110      "deleted": false,
  3111      "description": "New version 1630480693371",
  3112      "lastModifiedBy": "jsmith",
  3113      "lastModifiedDate": 1630507099511,
  3114      "location": "/cloudlets/api/v2/policies/139743/versions/798",
  3115      "matchRuleFormat": "1.0",
  3116      "matchRules": [
  3117          {
  3118              "type": "frMatchRule",
  3119              "akaRuleId": "f2168e71692e6d9f",
  3120              "end": 0,
  3121              "forwardSettings": {},
  3122              "id": 0,
  3123              "matchURL": null,
  3124              "matches": [
  3125                  {
  3126                      "caseSensitive": false,
  3127                      "matchOperator": "equals",
  3128                      "matchType": "header",
  3129                      "negate": false,
  3130                      "objectMatchValue": {
  3131                          "type": "object",
  3132                          "name": "Accept",
  3133                          "options": {
  3134                              "value": [
  3135                                  "asd",
  3136                                  "qwe"
  3137                              ],
  3138                              "valueCaseSensitive": true
  3139                          }
  3140                      }
  3141                  }
  3142              ],
  3143              "name": "rul3",
  3144              "start": 0
  3145          }
  3146      ],
  3147  	"policyId": 139743,
  3148      "revisionId": 4819450,
  3149      "rulesLocked": false,
  3150      "version": 798
  3151  }`,
  3152  			expectedPath: "/cloudlets/api/v2/policies/139743/versions",
  3153  			expectedResponse: &PolicyVersion{
  3154  				Activations:      []PolicyActivation{},
  3155  				CreateDate:       1630507099511,
  3156  				CreatedBy:        "jsmith",
  3157  				Deleted:          false,
  3158  				Description:      "New version 1630480693371",
  3159  				LastModifiedBy:   "jsmith",
  3160  				LastModifiedDate: 1630507099511,
  3161  				Location:         "/cloudlets/api/v2/policies/139743/versions/798",
  3162  				MatchRuleFormat:  "1.0",
  3163  				MatchRules: MatchRules{
  3164  					&MatchRuleFR{
  3165  						ForwardSettings: ForwardSettingsFR{},
  3166  						Matches: []MatchCriteriaFR{
  3167  							{
  3168  								CaseSensitive: false,
  3169  								MatchOperator: "equals",
  3170  								MatchType:     "header",
  3171  								Negate:        false,
  3172  								ObjectMatchValue: &ObjectMatchValueObject{
  3173  									Name:              "Accept",
  3174  									Type:              "object",
  3175  									NameCaseSensitive: false,
  3176  									NameHasWildcard:   false,
  3177  									Options: &Options{
  3178  										Value:              []string{"asd", "qwe"},
  3179  										ValueHasWildcard:   false,
  3180  										ValueCaseSensitive: true,
  3181  										ValueEscaped:       false,
  3182  									},
  3183  								},
  3184  							},
  3185  						},
  3186  						Start: 0,
  3187  						End:   0,
  3188  						Type:  "frMatchRule",
  3189  						Name:  "rul3",
  3190  						ID:    0,
  3191  					},
  3192  				},
  3193  				PolicyID:    139743,
  3194  				RevisionID:  4819450,
  3195  				RulesLocked: false,
  3196  				Version:     798,
  3197  			},
  3198  		},
  3199  		"201 created, complex FR with objectMatchValue - simple": {
  3200  			request: CreatePolicyVersionRequest{
  3201  				CreatePolicyVersion: CreatePolicyVersion{
  3202  					Description:     "New version 1630480693371",
  3203  					MatchRuleFormat: "1.0",
  3204  					MatchRules: MatchRules{
  3205  						&MatchRuleFR{
  3206  							ForwardSettings: ForwardSettingsFR{
  3207  								PathAndQS:              "/test_images/otherimage.jpg",
  3208  								UseIncomingQueryString: true,
  3209  							},
  3210  							Matches: []MatchCriteriaFR{
  3211  								{
  3212  									CaseSensitive: false,
  3213  									MatchOperator: "equals",
  3214  									MatchType:     "method",
  3215  									Negate:        false,
  3216  									ObjectMatchValue: &ObjectMatchValueSimple{
  3217  										Type:  "simple",
  3218  										Value: []string{"GET"},
  3219  									},
  3220  								},
  3221  							},
  3222  							Start: 0,
  3223  							End:   0,
  3224  							Type:  "frMatchRule",
  3225  							Name:  "rul3",
  3226  							ID:    0,
  3227  						},
  3228  					},
  3229  				},
  3230  				PolicyID: 139743,
  3231  			},
  3232  			responseStatus: http.StatusCreated,
  3233  			responseBody: `
  3234  {
  3235      "activations": [],
  3236      "createDate": 1630507099511,
  3237      "createdBy": "jsmith",
  3238      "deleted": false,
  3239      "description": "New version 1630480693371",
  3240      "lastModifiedBy": "jsmith",
  3241      "lastModifiedDate": 1630507099511,
  3242      "location": "/cloudlets/api/v2/policies/139743/versions/798",
  3243      "matchRuleFormat": "1.0",
  3244      "matchRules": [
  3245          {
  3246              "type": "frMatchRule",
  3247              "akaRuleId": "f2168e71692e6d9f",
  3248              "end": 0,
  3249              "forwardSettings": {
  3250                  "pathAndQS": "/test_images/otherimage.jpg",
  3251                  "useIncomingQueryString": true
  3252              },
  3253              "id": 0,
  3254              "matchURL": null,
  3255              "matches": [
  3256                  {
  3257                      "caseSensitive": false,
  3258                      "matchOperator": "equals",
  3259                      "matchType": "method",
  3260                      "negate": false,
  3261                      "objectMatchValue": {
  3262                          "type": "simple",
  3263                          "value": [
  3264                              "GET"
  3265                          ]
  3266                      }
  3267                  }
  3268  			],
  3269              "name": "rul3",
  3270              "start": 0
  3271          }
  3272      ],
  3273  	"policyId": 139743,
  3274      "revisionId": 4819450,
  3275      "rulesLocked": false,
  3276      "version": 798
  3277  }`,
  3278  			expectedPath: "/cloudlets/api/v2/policies/139743/versions",
  3279  			expectedResponse: &PolicyVersion{
  3280  				Activations:      []PolicyActivation{},
  3281  				CreateDate:       1630507099511,
  3282  				CreatedBy:        "jsmith",
  3283  				Deleted:          false,
  3284  				Description:      "New version 1630480693371",
  3285  				LastModifiedBy:   "jsmith",
  3286  				LastModifiedDate: 1630507099511,
  3287  				Location:         "/cloudlets/api/v2/policies/139743/versions/798",
  3288  				MatchRuleFormat:  "1.0",
  3289  				MatchRules: MatchRules{
  3290  					&MatchRuleFR{
  3291  						ForwardSettings: ForwardSettingsFR{
  3292  							PathAndQS:              "/test_images/otherimage.jpg",
  3293  							UseIncomingQueryString: true,
  3294  						},
  3295  						Matches: []MatchCriteriaFR{
  3296  							{
  3297  								CaseSensitive: false,
  3298  								MatchOperator: "equals",
  3299  								MatchType:     "method",
  3300  								Negate:        false,
  3301  								ObjectMatchValue: &ObjectMatchValueSimple{
  3302  									Type:  "simple",
  3303  									Value: []string{"GET"},
  3304  								},
  3305  							},
  3306  						},
  3307  						Start: 0,
  3308  						End:   0,
  3309  						Type:  "frMatchRule",
  3310  						Name:  "rul3",
  3311  						ID:    0,
  3312  					},
  3313  				},
  3314  				PolicyID:    139743,
  3315  				RevisionID:  4819450,
  3316  				RulesLocked: false,
  3317  				Version:     798,
  3318  			},
  3319  		},
  3320  
  3321  		"201 created, complex VP with objectMatchValue - simple": {
  3322  			request: CreatePolicyVersionRequest{
  3323  				CreatePolicyVersion: CreatePolicyVersion{
  3324  					MatchRules: MatchRules{
  3325  						&MatchRuleVP{
  3326  							Start:              0,
  3327  							End:                0,
  3328  							Type:               "vpMatchRule",
  3329  							Name:               "rul3",
  3330  							PassThroughPercent: tools.Float64Ptr(-1),
  3331  							ID:                 0,
  3332  							Matches: []MatchCriteriaVP{
  3333  								{
  3334  									CaseSensitive: true,
  3335  									MatchOperator: "equals",
  3336  									MatchType:     "method",
  3337  									Negate:        false,
  3338  									ObjectMatchValue: &ObjectMatchValueSimple{
  3339  										Type:  "simple",
  3340  										Value: []string{"GET"},
  3341  									},
  3342  								},
  3343  							},
  3344  						},
  3345  					},
  3346  				},
  3347  				PolicyID: 276858,
  3348  			},
  3349  			responseStatus: http.StatusCreated,
  3350  			responseBody: `{
  3351      "activations": [],
  3352      "createDate": 1629981355165,
  3353      "createdBy": "jsmith",
  3354      "deleted": false,
  3355      "description": null,
  3356      "lastModifiedBy": "jsmith",
  3357      "lastModifiedDate": 1629981355165,
  3358      "location": "/cloudlets/api/v2/policies/276858/versions/6",
  3359      "matchRuleFormat": "1.0",
  3360      "matchRules": [
  3361          {
  3362              "type": "vpMatchRule",
  3363              "end": 0,
  3364              "id": 0,
  3365              "matchURL": null,
  3366              "matches": [
  3367                  {
  3368                      "caseSensitive": true,
  3369                      "matchOperator": "equals",
  3370                      "matchType": "method",
  3371                      "negate": false,
  3372                      "objectMatchValue": {
  3373                          "type": "simple",
  3374                          "value": [
  3375                              "GET"
  3376                          ]
  3377                      }
  3378                  }
  3379              ],
  3380              "name": "rul3",
  3381              "start": 0,
  3382  			"passThroughPercent": -1
  3383          }
  3384      ],
  3385      "policyId": 276858,
  3386      "revisionId": 4815968,
  3387      "rulesLocked": false,
  3388      "version": 6
  3389  }`,
  3390  			expectedPath: "/cloudlets/api/v2/policies/276858/versions",
  3391  			expectedResponse: &PolicyVersion{
  3392  				Activations:      []PolicyActivation{},
  3393  				CreateDate:       1629981355165,
  3394  				CreatedBy:        "jsmith",
  3395  				Deleted:          false,
  3396  				Description:      "",
  3397  				LastModifiedBy:   "jsmith",
  3398  				LastModifiedDate: 1629981355165,
  3399  				Location:         "/cloudlets/api/v2/policies/276858/versions/6",
  3400  				MatchRuleFormat:  "1.0",
  3401  				PolicyID:         276858,
  3402  				RevisionID:       4815968,
  3403  				RulesLocked:      false,
  3404  				Version:          6,
  3405  				MatchRules: MatchRules{
  3406  					&MatchRuleVP{
  3407  						Type:               "vpMatchRule",
  3408  						End:                0,
  3409  						ID:                 0,
  3410  						MatchURL:           "",
  3411  						Name:               "rul3",
  3412  						PassThroughPercent: tools.Float64Ptr(-1),
  3413  						Start:              0,
  3414  						Matches: []MatchCriteriaVP{
  3415  							{
  3416  								CaseSensitive: true,
  3417  								MatchOperator: "equals",
  3418  								MatchType:     "method",
  3419  								Negate:        false,
  3420  								ObjectMatchValue: &ObjectMatchValueSimple{
  3421  									Type:  "simple",
  3422  									Value: []string{"GET"},
  3423  								},
  3424  							},
  3425  						},
  3426  					},
  3427  				},
  3428  			},
  3429  		},
  3430  
  3431  		"201 created, complex AP with objectMatchValue - simple": {
  3432  			request: CreatePolicyVersionRequest{
  3433  				CreatePolicyVersion: CreatePolicyVersion{
  3434  					MatchRules: MatchRules{
  3435  						&MatchRuleAP{
  3436  							Start:              0,
  3437  							End:                0,
  3438  							Type:               "apMatchRule",
  3439  							Name:               "rul3",
  3440  							PassThroughPercent: tools.Float64Ptr(0),
  3441  							ID:                 0,
  3442  							Matches: []MatchCriteriaAP{
  3443  								{
  3444  									CaseSensitive: true,
  3445  									MatchOperator: "equals",
  3446  									MatchType:     "method",
  3447  									Negate:        false,
  3448  									ObjectMatchValue: &ObjectMatchValueSimple{
  3449  										Type:  "simple",
  3450  										Value: []string{"GET"},
  3451  									},
  3452  								},
  3453  							},
  3454  						},
  3455  					},
  3456  				},
  3457  				PolicyID: 276858,
  3458  			},
  3459  			responseStatus: http.StatusCreated,
  3460  			responseBody: `{
  3461      "activations": [],
  3462      "createDate": 1629981355165,
  3463      "createdBy": "jsmith",
  3464      "deleted": false,
  3465      "description": null,
  3466      "lastModifiedBy": "jsmith",
  3467      "lastModifiedDate": 1629981355165,
  3468      "location": "/cloudlets/api/v2/policies/276858/versions/6",
  3469      "matchRuleFormat": "1.0",
  3470      "matchRules": [
  3471          {
  3472              "type": "apMatchRule",
  3473              "end": 0,
  3474              "id": 0,
  3475              "matchURL": null,
  3476              "matches": [
  3477                  {
  3478                      "caseSensitive": true,
  3479                      "matchOperator": "equals",
  3480                      "matchType": "method",
  3481                      "negate": false,
  3482                      "objectMatchValue": {
  3483                          "type": "simple",
  3484                          "value": [
  3485                              "GET"
  3486                          ]
  3487                      }
  3488                  }
  3489              ],
  3490              "name": "rul3",
  3491              "start": 0,
  3492              "useIncomingQueryString": false,
  3493  			"passThroughPercent": -1
  3494          }
  3495      ],
  3496      "policyId": 276858,
  3497      "revisionId": 4815968,
  3498      "rulesLocked": false,
  3499      "version": 6
  3500  }`,
  3501  			expectedPath: "/cloudlets/api/v2/policies/276858/versions",
  3502  			expectedResponse: &PolicyVersion{
  3503  				Activations:      []PolicyActivation{},
  3504  				CreateDate:       1629981355165,
  3505  				CreatedBy:        "jsmith",
  3506  				Deleted:          false,
  3507  				Description:      "",
  3508  				LastModifiedBy:   "jsmith",
  3509  				LastModifiedDate: 1629981355165,
  3510  				Location:         "/cloudlets/api/v2/policies/276858/versions/6",
  3511  				MatchRuleFormat:  "1.0",
  3512  				PolicyID:         276858,
  3513  				RevisionID:       4815968,
  3514  				RulesLocked:      false,
  3515  				Version:          6,
  3516  				MatchRules: MatchRules{
  3517  					&MatchRuleAP{
  3518  						Type:               "apMatchRule",
  3519  						End:                0,
  3520  						ID:                 0,
  3521  						MatchURL:           "",
  3522  						Name:               "rul3",
  3523  						PassThroughPercent: tools.Float64Ptr(-1),
  3524  						Start:              0,
  3525  						Matches: []MatchCriteriaAP{
  3526  							{
  3527  								CaseSensitive: true,
  3528  								MatchOperator: "equals",
  3529  								MatchType:     "method",
  3530  								Negate:        false,
  3531  								ObjectMatchValue: &ObjectMatchValueSimple{
  3532  									Type:  "simple",
  3533  									Value: []string{"GET"},
  3534  								},
  3535  							},
  3536  						},
  3537  					},
  3538  				},
  3539  			},
  3540  		},
  3541  		"201 created, complex AP with objectMatchValue - object": {
  3542  			request: CreatePolicyVersionRequest{
  3543  				CreatePolicyVersion: CreatePolicyVersion{
  3544  					MatchRules: MatchRules{
  3545  						&MatchRuleAP{
  3546  							Start:              0,
  3547  							End:                0,
  3548  							Type:               "apMatchRule",
  3549  							Name:               "rul3",
  3550  							PassThroughPercent: tools.Float64Ptr(-1),
  3551  							ID:                 0,
  3552  							Matches: []MatchCriteriaAP{
  3553  								{
  3554  									CaseSensitive: false,
  3555  									MatchOperator: "equals",
  3556  									MatchType:     "header",
  3557  									Negate:        false,
  3558  									ObjectMatchValue: &ObjectMatchValueObject{
  3559  										Type: "object",
  3560  										Name: "AP",
  3561  										Options: &Options{
  3562  											Value:            []string{"y"},
  3563  											ValueHasWildcard: true,
  3564  										},
  3565  									},
  3566  								},
  3567  							},
  3568  						},
  3569  					},
  3570  				},
  3571  				PolicyID: 276858,
  3572  			},
  3573  			responseStatus: http.StatusCreated,
  3574  			responseBody: `{
  3575      "activations": [],
  3576      "createDate": 1629981355165,
  3577      "createdBy": "jsmith",
  3578      "deleted": false,
  3579      "description": null,
  3580      "lastModifiedBy": "jsmith",
  3581      "lastModifiedDate": 1629981355165,
  3582      "location": "/cloudlets/api/v2/policies/276858/versions/6",
  3583      "matchRuleFormat": "1.0",
  3584      "matchRules": [
  3585          {
  3586              "type": "apMatchRule",
  3587              "end": 0,
  3588              "id": 0,
  3589              "matchURL": null,
  3590              "matches": [
  3591                  {
  3592                      "caseSensitive": false,
  3593                      "matchOperator": "equals",
  3594                      "matchType": "header",
  3595                      "negate": false,
  3596                      "objectMatchValue": {
  3597                          "type": "object",
  3598                          "name": "AP",
  3599  						"options": {
  3600                              "value": [
  3601                                  "y"
  3602                              ],
  3603                              "valueHasWildcard": true
  3604                          }
  3605                      }
  3606                  }
  3607              ],
  3608              "name": "rul3",
  3609              "start": 0,
  3610  			"passThroughPercent": -1
  3611          }
  3612      ],
  3613      "policyId": 276858,
  3614      "revisionId": 4815968,
  3615      "rulesLocked": false,
  3616      "version": 6
  3617  }`,
  3618  			expectedPath: "/cloudlets/api/v2/policies/276858/versions",
  3619  			expectedResponse: &PolicyVersion{
  3620  				Activations:      []PolicyActivation{},
  3621  				CreateDate:       1629981355165,
  3622  				CreatedBy:        "jsmith",
  3623  				Deleted:          false,
  3624  				Description:      "",
  3625  				LastModifiedBy:   "jsmith",
  3626  				LastModifiedDate: 1629981355165,
  3627  				Location:         "/cloudlets/api/v2/policies/276858/versions/6",
  3628  				MatchRuleFormat:  "1.0",
  3629  				PolicyID:         276858,
  3630  				RevisionID:       4815968,
  3631  				RulesLocked:      false,
  3632  				Version:          6,
  3633  				MatchRules: MatchRules{
  3634  					&MatchRuleAP{
  3635  						Type:               "apMatchRule",
  3636  						End:                0,
  3637  						ID:                 0,
  3638  						MatchURL:           "",
  3639  						Name:               "rul3",
  3640  						PassThroughPercent: tools.Float64Ptr(-1),
  3641  						Start:              0,
  3642  						Matches: []MatchCriteriaAP{
  3643  							{
  3644  								CaseSensitive: false,
  3645  								MatchOperator: "equals",
  3646  								MatchType:     "header",
  3647  								Negate:        false,
  3648  								ObjectMatchValue: &ObjectMatchValueObject{
  3649  									Type: "object",
  3650  									Name: "AP",
  3651  									Options: &Options{
  3652  										Value:            []string{"y"},
  3653  										ValueHasWildcard: true,
  3654  									},
  3655  								},
  3656  							},
  3657  						},
  3658  					},
  3659  				},
  3660  			},
  3661  		},
  3662  		"201 created, complex RC": {
  3663  			request: CreatePolicyVersionRequest{
  3664  				CreatePolicyVersion: CreatePolicyVersion{
  3665  					MatchRules: MatchRules{
  3666  						&MatchRuleRC{
  3667  							Start:     0,
  3668  							End:       0,
  3669  							Type:      "igMatchRule",
  3670  							Name:      "rul3",
  3671  							AllowDeny: DenyBranded,
  3672  							ID:        0,
  3673  							Matches: []MatchCriteriaRC{
  3674  								{
  3675  									CaseSensitive: false,
  3676  									MatchOperator: "equals",
  3677  									MatchType:     "protocol",
  3678  									MatchValue:    "https",
  3679  									Negate:        false,
  3680  								},
  3681  								{
  3682  									CaseSensitive: true,
  3683  									MatchOperator: "equals",
  3684  									MatchType:     "method",
  3685  									Negate:        false,
  3686  									ObjectMatchValue: &ObjectMatchValueSimple{
  3687  										Type:  "simple",
  3688  										Value: []string{"GET"},
  3689  									},
  3690  								},
  3691  								{
  3692  									MatchOperator: "equals",
  3693  									MatchType:     "header",
  3694  									Negate:        false,
  3695  									ObjectMatchValue: &ObjectMatchValueObject{
  3696  										Type: "object",
  3697  										Name: "RC",
  3698  										Options: &Options{
  3699  											Value: []string{
  3700  												"text/html*",
  3701  												"text/css*",
  3702  												"application/x-javascript*",
  3703  											},
  3704  											ValueHasWildcard: true,
  3705  										},
  3706  									},
  3707  								},
  3708  							},
  3709  						},
  3710  					},
  3711  				},
  3712  				PolicyID: 276858,
  3713  			},
  3714  			responseStatus: http.StatusCreated,
  3715  			responseBody: `{
  3716      "activations": [],
  3717      "createDate": 1629981355165,
  3718      "createdBy": "jsmith",
  3719      "deleted": false,
  3720      "description": null,
  3721      "lastModifiedBy": "jsmith",
  3722      "lastModifiedDate": 1629981355165,
  3723      "location": "/cloudlets/api/v2/policies/276858/versions/6",
  3724      "matchRuleFormat": "1.0",
  3725      "matchRules": [
  3726          {
  3727              "type": "igMatchRule",
  3728              "end": 0,
  3729              "id": 0,
  3730              "matchesAlways": false,
  3731              "matches": [
  3732  				{
  3733                      "caseSensitive": false,
  3734                      "matchOperator": "equals",
  3735                      "matchType": "protocol",
  3736                      "negate": false,
  3737  					"matchValue": "https"
  3738  				},
  3739                  {
  3740                      "caseSensitive": true,
  3741                      "matchOperator": "equals",
  3742                      "matchType": "method",
  3743                      "negate": false,
  3744                      "objectMatchValue": {
  3745                          "type": "simple",
  3746                          "value": [
  3747                              "GET"
  3748                          ]
  3749                      }
  3750                  },
  3751  				{
  3752                      "matchOperator": "equals",
  3753                      "matchType": "header",
  3754                      "negate": false,
  3755  					"objectMatchValue": {
  3756                          "type": "object",
  3757                          "name": "RC",
  3758  						"options": {
  3759  							"value": [
  3760  								"text/html*",
  3761  								"text/css*",
  3762  								"application/x-javascript*"
  3763                              ],
  3764                              "valueHasWildcard": true
  3765  						}
  3766                      }
  3767  				}
  3768              ],
  3769              "name": "rul3",
  3770              "start": 0,
  3771  			"allowDeny": "denybranded"
  3772          }
  3773      ],
  3774      "policyId": 276858,
  3775      "revisionId": 4815968,
  3776      "rulesLocked": false,
  3777      "version": 6
  3778  }`,
  3779  			expectedPath: "/cloudlets/api/v2/policies/276858/versions",
  3780  			expectedResponse: &PolicyVersion{
  3781  				Activations:      []PolicyActivation{},
  3782  				CreateDate:       1629981355165,
  3783  				CreatedBy:        "jsmith",
  3784  				Deleted:          false,
  3785  				Description:      "",
  3786  				LastModifiedBy:   "jsmith",
  3787  				LastModifiedDate: 1629981355165,
  3788  				Location:         "/cloudlets/api/v2/policies/276858/versions/6",
  3789  				MatchRuleFormat:  "1.0",
  3790  				PolicyID:         276858,
  3791  				RevisionID:       4815968,
  3792  				RulesLocked:      false,
  3793  				Version:          6,
  3794  				MatchRules: MatchRules{
  3795  					&MatchRuleRC{
  3796  						Type:          "igMatchRule",
  3797  						End:           0,
  3798  						ID:            0,
  3799  						MatchesAlways: false,
  3800  						Name:          "rul3",
  3801  						AllowDeny:     DenyBranded,
  3802  						Start:         0,
  3803  						Matches: []MatchCriteriaRC{
  3804  							{
  3805  								CaseSensitive: false,
  3806  								MatchOperator: "equals",
  3807  								MatchType:     "protocol",
  3808  								MatchValue:    "https",
  3809  								Negate:        false,
  3810  							},
  3811  							{
  3812  								CaseSensitive: true,
  3813  								MatchOperator: "equals",
  3814  								MatchType:     "method",
  3815  								Negate:        false,
  3816  								ObjectMatchValue: &ObjectMatchValueSimple{
  3817  									Type:  "simple",
  3818  									Value: []string{"GET"},
  3819  								},
  3820  							},
  3821  							{
  3822  								MatchOperator: "equals",
  3823  								MatchType:     "header",
  3824  								Negate:        false,
  3825  								ObjectMatchValue: &ObjectMatchValueObject{
  3826  									Type: "object",
  3827  									Name: "RC",
  3828  									Options: &Options{
  3829  										Value: []string{
  3830  											"text/html*",
  3831  											"text/css*",
  3832  											"application/x-javascript*",
  3833  										},
  3834  										ValueHasWildcard: true,
  3835  									},
  3836  								},
  3837  							},
  3838  						},
  3839  					},
  3840  				},
  3841  			},
  3842  		},
  3843  		"validation error, complex RC with unavailable objectMatchValue type - range": {
  3844  			request: CreatePolicyVersionRequest{
  3845  				CreatePolicyVersion: CreatePolicyVersion{
  3846  					MatchRules: MatchRules{
  3847  						&MatchRuleRC{
  3848  							Start:     0,
  3849  							End:       0,
  3850  							Type:      "igMatchRule",
  3851  							AllowDeny: Allow,
  3852  							Name:      "rul3",
  3853  							ID:        0,
  3854  							Matches: []MatchCriteriaRC{
  3855  								{
  3856  									MatchOperator: "equals",
  3857  									MatchType:     "header",
  3858  									Negate:        false,
  3859  									ObjectMatchValue: &ObjectMatchValueRange{
  3860  										Type:  "range",
  3861  										Value: []int64{1, 50},
  3862  									},
  3863  								},
  3864  							},
  3865  						},
  3866  					},
  3867  				},
  3868  				PolicyID: 276858,
  3869  			},
  3870  			withError: ErrStructValidation,
  3871  		},
  3872  		"validation error, complex VP with unavailable objectMatchValue type - range": {
  3873  			request: CreatePolicyVersionRequest{
  3874  				CreatePolicyVersion: CreatePolicyVersion{
  3875  					MatchRules: MatchRules{
  3876  						&MatchRuleVP{
  3877  							Start:              0,
  3878  							End:                0,
  3879  							Type:               "vpMatchRule",
  3880  							PassThroughPercent: tools.Float64Ptr(50.50),
  3881  							Name:               "rul3",
  3882  							ID:                 0,
  3883  							Matches: []MatchCriteriaVP{
  3884  								{
  3885  									MatchOperator: "equals",
  3886  									MatchType:     "header",
  3887  									Negate:        false,
  3888  									ObjectMatchValue: &ObjectMatchValueRange{
  3889  										Type:  "range",
  3890  										Value: []int64{1, 50},
  3891  									},
  3892  								},
  3893  							},
  3894  						},
  3895  					},
  3896  				},
  3897  				PolicyID: 276858,
  3898  			},
  3899  			withError: ErrStructValidation,
  3900  		},
  3901  
  3902  		"validation error, complex AP with unavailable objectMatchValue type - range": {
  3903  			request: CreatePolicyVersionRequest{
  3904  				CreatePolicyVersion: CreatePolicyVersion{
  3905  					MatchRules: MatchRules{
  3906  						&MatchRuleAP{
  3907  							Start:              0,
  3908  							End:                0,
  3909  							Type:               "apMatchRule",
  3910  							PassThroughPercent: tools.Float64Ptr(50.50),
  3911  							Name:               "rul3",
  3912  							ID:                 0,
  3913  							Matches: []MatchCriteriaAP{
  3914  								{
  3915  									MatchOperator: "equals",
  3916  									MatchType:     "header",
  3917  									Negate:        false,
  3918  									ObjectMatchValue: &ObjectMatchValueRange{
  3919  										Type:  "range",
  3920  										Value: []int64{1, 50},
  3921  									},
  3922  								},
  3923  							},
  3924  						},
  3925  					},
  3926  				},
  3927  				PolicyID: 276858,
  3928  			},
  3929  			withError: ErrStructValidation,
  3930  		},
  3931  
  3932  		"validation error, simple RC missing allowDeny": {
  3933  			request: CreatePolicyVersionRequest{
  3934  				CreatePolicyVersion: CreatePolicyVersion{
  3935  					MatchRules: MatchRules{
  3936  						&MatchRuleRC{
  3937  							Start: 0,
  3938  							End:   0,
  3939  							Type:  "igMatchRule",
  3940  							Name:  "rul3",
  3941  							ID:    0,
  3942  						},
  3943  					},
  3944  				},
  3945  				PolicyID: 276858,
  3946  			},
  3947  			withError: ErrStructValidation,
  3948  		},
  3949  		"validation error, simple VP missing passThroughPercent": {
  3950  			request: CreatePolicyVersionRequest{
  3951  				CreatePolicyVersion: CreatePolicyVersion{
  3952  					MatchRules: MatchRules{
  3953  						&MatchRuleVP{
  3954  							Start: 0,
  3955  							End:   0,
  3956  							Type:  "vpMatchRule",
  3957  							Name:  "rul3",
  3958  							ID:    0,
  3959  						},
  3960  					},
  3961  				},
  3962  				PolicyID: 276858,
  3963  			},
  3964  			withError: ErrStructValidation,
  3965  		},
  3966  
  3967  		"validation error, simple AP missing passThrughPercent": {
  3968  			request: CreatePolicyVersionRequest{
  3969  				CreatePolicyVersion: CreatePolicyVersion{
  3970  					MatchRules: MatchRules{
  3971  						&MatchRuleAP{
  3972  							Start: 0,
  3973  							End:   0,
  3974  							Type:  "apMatchRule",
  3975  							Name:  "rul3",
  3976  							ID:    0,
  3977  						},
  3978  					},
  3979  				},
  3980  				PolicyID: 276858,
  3981  			},
  3982  			withError: ErrStructValidation,
  3983  		},
  3984  
  3985  		"validation error, simple VP passThroughPercent out of range": {
  3986  			request: CreatePolicyVersionRequest{
  3987  				CreatePolicyVersion: CreatePolicyVersion{
  3988  					MatchRules: MatchRules{
  3989  						&MatchRuleVP{
  3990  							Start:              0,
  3991  							End:                0,
  3992  							Type:               "vpMatchRule",
  3993  							PassThroughPercent: tools.Float64Ptr(101),
  3994  							Name:               "rul3",
  3995  							ID:                 0,
  3996  						},
  3997  					},
  3998  				},
  3999  				PolicyID: 276858,
  4000  			},
  4001  			withError: ErrStructValidation,
  4002  		},
  4003  
  4004  		"validation error, simple AP passThroughPercent out of range": {
  4005  			request: CreatePolicyVersionRequest{
  4006  				CreatePolicyVersion: CreatePolicyVersion{
  4007  					MatchRules: MatchRules{
  4008  						&MatchRuleAP{
  4009  							Start:              0,
  4010  							End:                0,
  4011  							Type:               "apMatchRule",
  4012  							PassThroughPercent: tools.Float64Ptr(101),
  4013  							Name:               "rul3",
  4014  							ID:                 0,
  4015  						},
  4016  					},
  4017  				},
  4018  				PolicyID: 276858,
  4019  			},
  4020  			withError: ErrStructValidation,
  4021  		},
  4022  
  4023  		"500 internal server error": {
  4024  			request: CreatePolicyVersionRequest{
  4025  				PolicyID: 1,
  4026  			},
  4027  			responseStatus: http.StatusInternalServerError,
  4028  			responseBody: `
  4029  {
  4030    "type": "internal_error",
  4031    "title": "Internal Server Error",
  4032    "detail": "Error creating enrollment",
  4033    "status": 500
  4034  }`,
  4035  			expectedPath: "/cloudlets/api/v2/policies/1/versions",
  4036  			withError: &Error{
  4037  				Type:       "internal_error",
  4038  				Title:      "Internal Server Error",
  4039  				Detail:     "Error creating enrollment",
  4040  				StatusCode: http.StatusInternalServerError,
  4041  			},
  4042  		},
  4043  		"validation error": {
  4044  			request: CreatePolicyVersionRequest{
  4045  				CreatePolicyVersion: CreatePolicyVersion{
  4046  					MatchRuleFormat: "2.0",
  4047  				},
  4048  			},
  4049  			expectedPath: "/cloudlets/api/v2/policies/0/versions",
  4050  			withError:    ErrStructValidation,
  4051  		},
  4052  	}
  4053  
  4054  	for name, test := range tests {
  4055  		t.Run(name, func(t *testing.T) {
  4056  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  4057  				assert.Equal(t, test.expectedPath, r.URL.String())
  4058  				assert.Equal(t, http.MethodPost, r.Method)
  4059  				if test.requestBody != "" {
  4060  					buf := new(bytes.Buffer)
  4061  					_, err := buf.ReadFrom(r.Body)
  4062  					assert.NoError(t, err)
  4063  					req := buf.String()
  4064  					assert.Equal(t, test.requestBody, req)
  4065  				}
  4066  				w.WriteHeader(test.responseStatus)
  4067  				_, err := w.Write([]byte(test.responseBody))
  4068  				assert.NoError(t, err)
  4069  			}))
  4070  			client := mockAPIClient(t, mockServer)
  4071  			result, err := client.CreatePolicyVersion(context.Background(), test.request)
  4072  			if test.withError != nil {
  4073  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
  4074  				return
  4075  			}
  4076  			require.NoError(t, err)
  4077  			assert.Equal(t, test.expectedResponse, result)
  4078  		})
  4079  	}
  4080  }
  4081  
  4082  func TestDeletePolicyVersion(t *testing.T) {
  4083  	tests := map[string]struct {
  4084  		request        DeletePolicyVersionRequest
  4085  		responseStatus int
  4086  		responseBody   string
  4087  		expectedPath   string
  4088  		withError      error
  4089  	}{
  4090  		"204 no content": {
  4091  			request: DeletePolicyVersionRequest{
  4092  				PolicyID: 276858,
  4093  				Version:  5,
  4094  			},
  4095  			responseStatus: http.StatusNoContent,
  4096  			responseBody:   "",
  4097  			expectedPath:   "/cloudlets/api/v2/policies/276858/versions/5",
  4098  		},
  4099  
  4100  		"500 internal server error": {
  4101  			request: DeletePolicyVersionRequest{
  4102  				PolicyID: 1,
  4103  				Version:  2,
  4104  			},
  4105  			responseStatus: http.StatusInternalServerError,
  4106  			responseBody: `
  4107  {
  4108    "type": "internal_error",
  4109    "title": "Internal Server Error",
  4110    "detail": "Error creating enrollment",
  4111    "status": 500
  4112  }`,
  4113  			expectedPath: "/cloudlets/api/v2/policies/1/versions/2",
  4114  			withError: &Error{
  4115  				Type:       "internal_error",
  4116  				Title:      "Internal Server Error",
  4117  				Detail:     "Error creating enrollment",
  4118  				StatusCode: http.StatusInternalServerError,
  4119  			},
  4120  		},
  4121  	}
  4122  
  4123  	for name, test := range tests {
  4124  		t.Run(name, func(t *testing.T) {
  4125  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  4126  				assert.Equal(t, test.expectedPath, r.URL.String())
  4127  				assert.Equal(t, http.MethodDelete, r.Method)
  4128  				w.WriteHeader(test.responseStatus)
  4129  				_, err := w.Write([]byte(test.responseBody))
  4130  				assert.NoError(t, err)
  4131  			}))
  4132  			client := mockAPIClient(t, mockServer)
  4133  			err := client.DeletePolicyVersion(context.Background(), test.request)
  4134  			if test.withError != nil {
  4135  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
  4136  				return
  4137  			}
  4138  			require.NoError(t, err)
  4139  		})
  4140  	}
  4141  }
  4142  
  4143  func TestUpdatePolicyVersion(t *testing.T) {
  4144  	tests := map[string]struct {
  4145  		request          UpdatePolicyVersionRequest
  4146  		requestBody      string
  4147  		responseStatus   int
  4148  		responseBody     string
  4149  		expectedPath     string
  4150  		expectedResponse *PolicyVersion
  4151  		withError        error
  4152  	}{
  4153  		"201 updated simple ER": {
  4154  			request: UpdatePolicyVersionRequest{
  4155  				UpdatePolicyVersion: UpdatePolicyVersion{
  4156  					Description: "Updated description",
  4157  				},
  4158  				PolicyID: 276858,
  4159  				Version:  5,
  4160  			},
  4161  			responseStatus: http.StatusOK,
  4162  			responseBody: `
  4163  {
  4164      "activations": [],
  4165      "createDate": 1629817335218,
  4166      "createdBy": "jsmith",
  4167      "deleted": false,
  4168      "description": "Updated description",
  4169      "lastModifiedBy": "jsmith",
  4170      "lastModifiedDate": 1629821693867,
  4171      "location": "/cloudlets/api/v2/policies/276858/versions/5",
  4172      "matchRuleFormat": "1.0",
  4173      "matchRules": null,
  4174      "policyId": 276858,
  4175      "revisionId": 4814876,
  4176      "rulesLocked": false,
  4177      "version": 5
  4178  }`,
  4179  			expectedPath: "/cloudlets/api/v2/policies/276858/versions/5",
  4180  			expectedResponse: &PolicyVersion{
  4181  				CreateDate:       1629817335218,
  4182  				CreatedBy:        "jsmith",
  4183  				Deleted:          false,
  4184  				Description:      "Updated description",
  4185  				LastModifiedBy:   "jsmith",
  4186  				LastModifiedDate: 1629821693867,
  4187  				Location:         "/cloudlets/api/v2/policies/276858/versions/5",
  4188  				Activations:      []PolicyActivation{},
  4189  				MatchRules:       nil,
  4190  				MatchRuleFormat:  "1.0",
  4191  				PolicyID:         276858,
  4192  				RevisionID:       4814876,
  4193  				RulesLocked:      false,
  4194  				Version:          5,
  4195  			},
  4196  		},
  4197  
  4198  		"201 updated complex ALB with warnings": {
  4199  			request: UpdatePolicyVersionRequest{
  4200  				UpdatePolicyVersion: UpdatePolicyVersion{
  4201  					Description: "Updated description",
  4202  					MatchRules: MatchRules{
  4203  						&MatchRuleALB{
  4204  							Matches: []MatchCriteriaALB{
  4205  								{
  4206  									MatchType:     "protocol",
  4207  									MatchValue:    "https",
  4208  									MatchOperator: "equals",
  4209  									Negate:        false,
  4210  									CaseSensitive: false,
  4211  								},
  4212  							},
  4213  							Start: 1,
  4214  							End:   2,
  4215  							Type:  "albMatchRule",
  4216  							Name:  "Rule3",
  4217  							ForwardSettings: ForwardSettingsALB{
  4218  								OriginID: "alb_test_krk_dc1_only",
  4219  							},
  4220  							ID: 0,
  4221  						},
  4222  						&MatchRuleALB{
  4223  							Matches: []MatchCriteriaALB{
  4224  								{
  4225  									MatchType:     "protocol",
  4226  									MatchValue:    "http",
  4227  									MatchOperator: "equals",
  4228  									Negate:        false,
  4229  									CaseSensitive: false,
  4230  								},
  4231  							},
  4232  							Start: 0,
  4233  							End:   0,
  4234  							Type:  "albMatchRule",
  4235  							Name:  "Rule1",
  4236  							ForwardSettings: ForwardSettingsALB{
  4237  								OriginID: "alb_test_krk_0_100",
  4238  							},
  4239  							ID: 0,
  4240  						},
  4241  					},
  4242  				},
  4243  				PolicyID: 276858,
  4244  				Version:  5,
  4245  			},
  4246  			responseStatus: http.StatusOK,
  4247  			responseBody: `
  4248  {
  4249      "activations": [],
  4250      "createDate": 1629981546401,
  4251      "createdBy": "jsmith",
  4252      "deleted": false,
  4253      "description": "Updated description",
  4254      "lastModifiedBy": "jsmith",
  4255      "lastModifiedDate": 1630414029735,
  4256      "location": "/cloudlets/api/v2/policies/279628/versions/2",
  4257      "matchRuleFormat": "1.0",
  4258      "matchRules": [
  4259          {
  4260              "type": "albMatchRule",
  4261              "end": 2,
  4262              "forwardSettings": {
  4263                  "originId": "alb_test_krk_dc1_only"
  4264              },
  4265              "id": 10,
  4266              "matchURL": null,
  4267              "matches": [
  4268                  {
  4269                      "caseSensitive": false,
  4270                      "matchOperator": "equals",
  4271                      "matchType": "protocol",
  4272                      "matchValue": "https",
  4273                      "negate": false
  4274                  }
  4275              ],
  4276              "name": "Rule3",
  4277              "start": 1
  4278          },
  4279          {
  4280              "type": "albMatchRule",
  4281              "end": 0,
  4282              "forwardSettings": {
  4283                  "originId": "alb_test_krk_0_100"
  4284              },
  4285              "id": 0,
  4286              "matchURL": null,
  4287              "matches": [
  4288                  {
  4289                      "caseSensitive": false,
  4290                      "matchOperator": "equals",
  4291                      "matchType": "protocol",
  4292                      "matchValue": "http",
  4293                      "negate": false
  4294                  }
  4295              ],
  4296              "name": "Rule1",
  4297              "start": 0
  4298          }
  4299      ],
  4300      "policyId": 279628,
  4301      "revisionId": 4815971,
  4302      "rulesLocked": false,
  4303      "version": 2,
  4304      "warnings": [
  4305          {
  4306              "detail": "Start time is very old, possibly invalid: 1 (1970-01-01T00:00:01Z)",
  4307              "title": "Invalid Result Value",
  4308              "type": "/cloudlets/error-types/invalid-result-value",
  4309              "jsonPointer": "/matchRules/0"
  4310          },
  4311          {
  4312              "detail": "End time is very old, possibly invalid: 2 (1970-01-01T00:00:02Z)",
  4313              "title": "Invalid Result Value",
  4314              "type": "/cloudlets/error-types/invalid-result-value",
  4315              "jsonPointer": "/matchRules/0"
  4316          }
  4317      ]
  4318  }
  4319  `,
  4320  			expectedPath: "/cloudlets/api/v2/policies/276858/versions/5",
  4321  			expectedResponse: &PolicyVersion{
  4322  				Activations:      []PolicyActivation{},
  4323  				CreateDate:       1629981546401,
  4324  				CreatedBy:        "jsmith",
  4325  				Deleted:          false,
  4326  				Description:      "Updated description",
  4327  				LastModifiedBy:   "jsmith",
  4328  				LastModifiedDate: 1630414029735,
  4329  				Location:         "/cloudlets/api/v2/policies/279628/versions/2",
  4330  				MatchRuleFormat:  "1.0",
  4331  				MatchRules: MatchRules{
  4332  					&MatchRuleALB{
  4333  						Type: "albMatchRule",
  4334  						End:  2,
  4335  						ForwardSettings: ForwardSettingsALB{
  4336  							OriginID: "alb_test_krk_dc1_only",
  4337  						},
  4338  						ID:       10,
  4339  						MatchURL: "",
  4340  						Matches: []MatchCriteriaALB{
  4341  							{
  4342  								CaseSensitive: false,
  4343  								MatchOperator: "equals",
  4344  								MatchType:     "protocol",
  4345  								MatchValue:    "https",
  4346  								Negate:        false,
  4347  							},
  4348  						},
  4349  						Name:  "Rule3",
  4350  						Start: 1,
  4351  					},
  4352  					&MatchRuleALB{
  4353  						Type: "albMatchRule",
  4354  						End:  0,
  4355  						ForwardSettings: ForwardSettingsALB{
  4356  							OriginID: "alb_test_krk_0_100",
  4357  						},
  4358  						ID:       0,
  4359  						MatchURL: "",
  4360  						Matches: []MatchCriteriaALB{
  4361  							{
  4362  								CaseSensitive: false,
  4363  								MatchOperator: "equals",
  4364  								MatchType:     "protocol",
  4365  								MatchValue:    "http",
  4366  								Negate:        false,
  4367  							},
  4368  						},
  4369  						Name:  "Rule1",
  4370  						Start: 0,
  4371  					},
  4372  				},
  4373  				PolicyID:    279628,
  4374  				RevisionID:  4815971,
  4375  				RulesLocked: false,
  4376  				Version:     2,
  4377  				Warnings: []Warning{
  4378  					{
  4379  						Detail:      "Start time is very old, possibly invalid: 1 (1970-01-01T00:00:01Z)",
  4380  						Title:       "Invalid Result Value",
  4381  						Type:        "/cloudlets/error-types/invalid-result-value",
  4382  						JSONPointer: "/matchRules/0",
  4383  					},
  4384  					{
  4385  						Detail:      "End time is very old, possibly invalid: 2 (1970-01-01T00:00:02Z)",
  4386  						Title:       "Invalid Result Value",
  4387  						Type:        "/cloudlets/error-types/invalid-result-value",
  4388  						JSONPointer: "/matchRules/0",
  4389  					},
  4390  				},
  4391  			},
  4392  		},
  4393  
  4394  		"500 internal server error": {
  4395  			request: UpdatePolicyVersionRequest{
  4396  				PolicyID: 276858,
  4397  				Version:  3,
  4398  			},
  4399  			responseStatus: http.StatusInternalServerError,
  4400  			responseBody: `
  4401  {
  4402    "type": "internal_error",
  4403    "title": "Internal Server Error",
  4404    "detail": "Error creating enrollment",
  4405    "status": 500
  4406  }`,
  4407  			expectedPath: "/cloudlets/api/v2/policies/276858/versions/3",
  4408  			withError: &Error{
  4409  				Type:       "internal_error",
  4410  				Title:      "Internal Server Error",
  4411  				Detail:     "Error creating enrollment",
  4412  				StatusCode: http.StatusInternalServerError,
  4413  			},
  4414  		},
  4415  		"validation error": {
  4416  			expectedPath: "/cloudlets/api/v2/policies/0",
  4417  			request: UpdatePolicyVersionRequest{
  4418  				UpdatePolicyVersion: UpdatePolicyVersion{
  4419  					Description: strings.Repeat("A", 256),
  4420  				},
  4421  			},
  4422  			withError: ErrStructValidation,
  4423  		},
  4424  	}
  4425  
  4426  	for name, test := range tests {
  4427  		t.Run(name, func(t *testing.T) {
  4428  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  4429  				assert.Equal(t, test.expectedPath, r.URL.String())
  4430  				assert.Equal(t, http.MethodPut, r.Method)
  4431  				w.WriteHeader(test.responseStatus)
  4432  				_, err := w.Write([]byte(test.responseBody))
  4433  				assert.NoError(t, err)
  4434  			}))
  4435  			client := mockAPIClient(t, mockServer)
  4436  			result, err := client.UpdatePolicyVersion(context.Background(), test.request)
  4437  			if test.withError != nil {
  4438  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
  4439  				return
  4440  			}
  4441  			require.NoError(t, err)
  4442  			assert.Equal(t, test.expectedResponse, result)
  4443  		})
  4444  	}
  4445  }