github.com/akamai/AkamaiOPEN-edgegrid-golang/v2@v2.17.0/pkg/appsec/rule_test.go (about)

     1  package appsec
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"errors"
     7  	"net/http"
     8  	"net/http/httptest"
     9  	"testing"
    10  
    11  	"github.com/akamai/AkamaiOPEN-edgegrid-golang/v2/pkg/session"
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  func TestAppSec_ListRule(t *testing.T) {
    17  
    18  	result := GetRulesResponse{}
    19  
    20  	respData := compactJSON(loadFixtureBytes("testdata/TestRule/Rules.json"))
    21  	json.Unmarshal([]byte(respData), &result)
    22  
    23  	tests := map[string]struct {
    24  		params           GetRulesRequest
    25  		responseStatus   int
    26  		responseBody     string
    27  		expectedPath     string
    28  		expectedResponse *GetRulesResponse
    29  		withError        error
    30  		headers          http.Header
    31  	}{
    32  		"200 OK": {
    33  			params: GetRulesRequest{
    34  				ConfigID: 43253,
    35  				Version:  15,
    36  				PolicyID: "AAAA_81230",
    37  			},
    38  			headers: http.Header{
    39  				"Content-Type": []string{"application/json"},
    40  			},
    41  			responseStatus:   http.StatusOK,
    42  			responseBody:     string(respData),
    43  			expectedPath:     "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/rules?includeConditionException=true",
    44  			expectedResponse: &result,
    45  		},
    46  		"500 internal server error": {
    47  			params: GetRulesRequest{
    48  				ConfigID: 43253,
    49  				Version:  15,
    50  				PolicyID: "AAAA_81230",
    51  			},
    52  			headers:        http.Header{},
    53  			responseStatus: http.StatusInternalServerError,
    54  			responseBody: `
    55  {
    56      "type": "internal_error",
    57      "title": "Internal Server Error",
    58      "detail": "Error fetching propertys",
    59      "status": 500
    60  }`,
    61  			expectedPath: "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/rules?includeConditionException=true",
    62  			withError: &Error{
    63  				Type:       "internal_error",
    64  				Title:      "Internal Server Error",
    65  				Detail:     "Error fetching propertys",
    66  				StatusCode: http.StatusInternalServerError,
    67  			},
    68  		},
    69  	}
    70  
    71  	for name, test := range tests {
    72  		t.Run(name, func(t *testing.T) {
    73  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    74  				assert.Equal(t, test.expectedPath, r.URL.String())
    75  				assert.Equal(t, http.MethodGet, r.Method)
    76  				w.WriteHeader(test.responseStatus)
    77  				_, err := w.Write([]byte(test.responseBody))
    78  				assert.NoError(t, err)
    79  			}))
    80  			client := mockAPIClient(t, mockServer)
    81  			result, err := client.GetRules(
    82  				session.ContextWithOptions(
    83  					context.Background(),
    84  					session.WithContextHeaders(test.headers),
    85  				),
    86  				test.params)
    87  			if test.withError != nil {
    88  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
    89  				return
    90  			}
    91  			require.NoError(t, err)
    92  			assert.Equal(t, test.expectedResponse, result)
    93  		})
    94  	}
    95  }
    96  
    97  // Test Rule
    98  func TestAppSec_GetRule(t *testing.T) {
    99  
   100  	result := GetRuleResponse{}
   101  
   102  	respData := compactJSON(loadFixtureBytes("testdata/TestRule/Rule.json"))
   103  	json.Unmarshal([]byte(respData), &result)
   104  
   105  	tests := map[string]struct {
   106  		params           GetRuleRequest
   107  		responseStatus   int
   108  		responseBody     string
   109  		expectedPath     string
   110  		expectedResponse *GetRuleResponse
   111  		withError        error
   112  	}{
   113  		"200 OK": {
   114  			params: GetRuleRequest{
   115  				ConfigID: 43253,
   116  				Version:  15,
   117  				PolicyID: "AAAA_81230",
   118  				RuleID:   12345,
   119  			},
   120  			responseStatus:   http.StatusOK,
   121  			responseBody:     respData,
   122  			expectedPath:     "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/rules/12345?includeConditionException=true",
   123  			expectedResponse: &result,
   124  		},
   125  		"500 internal server error": {
   126  			params: GetRuleRequest{
   127  				ConfigID: 43253,
   128  				Version:  15,
   129  				PolicyID: "AAAA_81230",
   130  				RuleID:   12345,
   131  			},
   132  			responseStatus: http.StatusInternalServerError,
   133  			responseBody: (`
   134  {
   135      "type": "internal_error",
   136      "title": "Internal Server Error",
   137      "detail": "Error fetching match target"
   138  }`),
   139  			expectedPath: "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/rules/12345?includeConditionException=true",
   140  			withError: &Error{
   141  				Type:       "internal_error",
   142  				Title:      "Internal Server Error",
   143  				Detail:     "Error fetching match target",
   144  				StatusCode: http.StatusInternalServerError,
   145  			},
   146  		},
   147  	}
   148  
   149  	for name, test := range tests {
   150  		t.Run(name, func(t *testing.T) {
   151  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   152  				assert.Equal(t, test.expectedPath, r.URL.String())
   153  				assert.Equal(t, http.MethodGet, r.Method)
   154  				w.WriteHeader(test.responseStatus)
   155  				_, err := w.Write([]byte(test.responseBody))
   156  				assert.NoError(t, err)
   157  			}))
   158  			client := mockAPIClient(t, mockServer)
   159  			result, err := client.GetRule(context.Background(), test.params)
   160  			if test.withError != nil {
   161  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
   162  				return
   163  			}
   164  			require.NoError(t, err)
   165  			assert.Equal(t, test.expectedResponse, result)
   166  		})
   167  	}
   168  }
   169  
   170  // Test Update Rule.
   171  func TestAppSec_UpdateRule(t *testing.T) {
   172  	result := UpdateRuleResponse{}
   173  
   174  	respData := compactJSON(loadFixtureBytes("testdata/TestRule/Rule.json"))
   175  	json.Unmarshal([]byte(respData), &result)
   176  
   177  	tests := map[string]struct {
   178  		params           UpdateRuleRequest
   179  		responseStatus   int
   180  		responseBody     string
   181  		expectedPath     string
   182  		expectedResponse *UpdateRuleResponse
   183  		withError        error
   184  		headers          http.Header
   185  	}{
   186  		"200 Success": {
   187  			params: UpdateRuleRequest{
   188  				ConfigID: 43253,
   189  				Version:  15,
   190  				PolicyID: "AAAA_81230",
   191  				RuleID:   12345,
   192  			},
   193  			headers: http.Header{
   194  				"Content-Type": []string{"application/json;charset=UTF-8"},
   195  			},
   196  			responseStatus:   http.StatusCreated,
   197  			responseBody:     respData,
   198  			expectedResponse: &result,
   199  			expectedPath:     "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/rules/12345/action-condition-exception"},
   200  		"500 internal server error": {
   201  			params: UpdateRuleRequest{
   202  				ConfigID: 43253,
   203  				Version:  15,
   204  				PolicyID: "AAAA_81230",
   205  				RuleID:   12345,
   206  			},
   207  			responseStatus: http.StatusInternalServerError,
   208  			responseBody: (`
   209  {
   210      "type": "internal_error",
   211      "title": "Internal Server Error",
   212      "detail": "Error creating zone"
   213  }`),
   214  			expectedPath: "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/rules",
   215  			withError: &Error{
   216  				Type:       "internal_error",
   217  				Title:      "Internal Server Error",
   218  				Detail:     "Error creating zone",
   219  				StatusCode: http.StatusInternalServerError,
   220  			},
   221  		},
   222  	}
   223  
   224  	for name, test := range tests {
   225  		t.Run(name, func(t *testing.T) {
   226  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   227  				assert.Equal(t, http.MethodPut, r.Method)
   228  				w.WriteHeader(test.responseStatus)
   229  				if len(test.responseBody) > 0 {
   230  					_, err := w.Write([]byte(test.responseBody))
   231  					assert.NoError(t, err)
   232  				}
   233  			}))
   234  			client := mockAPIClient(t, mockServer)
   235  			result, err := client.UpdateRule(
   236  				session.ContextWithOptions(
   237  					context.Background(),
   238  					session.WithContextHeaders(test.headers)), test.params)
   239  			if test.withError != nil {
   240  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
   241  				return
   242  			}
   243  			require.NoError(t, err)
   244  			assert.Equal(t, test.expectedResponse, result)
   245  		})
   246  	}
   247  }
   248  
   249  // Test Update Rule.
   250  func TestAppSec_UpdateRuleConditionException(t *testing.T) {
   251  	result := UpdateConditionExceptionResponse{}
   252  
   253  	respData := compactJSON(loadFixtureBytes("testdata/TestRule/RuleConditionException.json"))
   254  	json.Unmarshal([]byte(respData), &result)
   255  
   256  	tests := map[string]struct {
   257  		params           UpdateConditionExceptionRequest
   258  		responseStatus   int
   259  		responseBody     string
   260  		expectedPath     string
   261  		expectedResponse *UpdateConditionExceptionResponse
   262  		withError        error
   263  		headers          http.Header
   264  	}{
   265  		"200 Success": {
   266  			params: UpdateConditionExceptionRequest{
   267  				ConfigID: 43253,
   268  				Version:  15,
   269  				PolicyID: "AAAA_81230",
   270  				RuleID:   12345,
   271  			},
   272  			headers: http.Header{
   273  				"Content-Type": []string{"application/json;charset=UTF-8"},
   274  			},
   275  			responseStatus:   http.StatusCreated,
   276  			responseBody:     respData,
   277  			expectedResponse: &result,
   278  			expectedPath:     "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/rules/12345/condition-exception"},
   279  		"500 internal server error": {
   280  			params: UpdateConditionExceptionRequest{
   281  				ConfigID: 43253,
   282  				Version:  15,
   283  				PolicyID: "AAAA_81230",
   284  				RuleID:   12345,
   285  			},
   286  			responseStatus: http.StatusInternalServerError,
   287  			responseBody: (`
   288  {
   289      "type": "internal_error",
   290      "title": "Internal Server Error",
   291      "detail": "Error creating zone"
   292  }`),
   293  			expectedPath: "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/rules",
   294  			withError: &Error{
   295  				Type:       "internal_error",
   296  				Title:      "Internal Server Error",
   297  				Detail:     "Error creating zone",
   298  				StatusCode: http.StatusInternalServerError,
   299  			},
   300  		},
   301  	}
   302  
   303  	for name, test := range tests {
   304  		t.Run(name, func(t *testing.T) {
   305  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   306  				assert.Equal(t, http.MethodPut, r.Method)
   307  				w.WriteHeader(test.responseStatus)
   308  				if len(test.responseBody) > 0 {
   309  					_, err := w.Write([]byte(test.responseBody))
   310  					assert.NoError(t, err)
   311  				}
   312  			}))
   313  			client := mockAPIClient(t, mockServer)
   314  			result, err := client.UpdateRuleConditionException(
   315  				session.ContextWithOptions(
   316  					context.Background(),
   317  					session.WithContextHeaders(test.headers)), test.params)
   318  			if test.withError != nil {
   319  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
   320  				return
   321  			}
   322  			require.NoError(t, err)
   323  			assert.Equal(t, test.expectedResponse, result)
   324  		})
   325  	}
   326  }
   327  
   328  // Test Update ASE Rule.
   329  func TestAppSec_UpdateRuleAdvancedConditionException(t *testing.T) {
   330  	result := UpdateConditionExceptionResponse{}
   331  
   332  	respData := compactJSON(loadFixtureBytes("testdata/TestRule/AdvancedException.json"))
   333  	json.Unmarshal([]byte(respData), &result)
   334  
   335  	tests := map[string]struct {
   336  		params           UpdateConditionExceptionRequest
   337  		responseStatus   int
   338  		responseBody     string
   339  		expectedPath     string
   340  		expectedResponse *UpdateConditionExceptionResponse
   341  		withError        error
   342  		headers          http.Header
   343  	}{
   344  		"200 Success": {
   345  			params: UpdateConditionExceptionRequest{
   346  				ConfigID: 43253,
   347  				Version:  15,
   348  				PolicyID: "AAAA_81230",
   349  				RuleID:   12345,
   350  			},
   351  			headers: http.Header{
   352  				"Content-Type": []string{"application/json;charset=UTF-8"},
   353  			},
   354  			responseStatus:   http.StatusCreated,
   355  			responseBody:     respData,
   356  			expectedResponse: &result,
   357  			expectedPath:     "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/rules/12345/condition-exception"},
   358  		"500 internal server error": {
   359  			params: UpdateConditionExceptionRequest{
   360  				ConfigID: 43253,
   361  				Version:  15,
   362  				PolicyID: "AAAA_81230",
   363  				RuleID:   12345,
   364  			},
   365  			responseStatus: http.StatusInternalServerError,
   366  			responseBody: (`
   367  {
   368      "type": "internal_error",
   369      "title": "Internal Server Error",
   370      "detail": "Error creating zone"
   371  }`),
   372  			expectedPath: "/appsec/v1/configs/43253/versions/15/security-policies/AAAA_81230/rules",
   373  			withError: &Error{
   374  				Type:       "internal_error",
   375  				Title:      "Internal Server Error",
   376  				Detail:     "Error creating zone",
   377  				StatusCode: http.StatusInternalServerError,
   378  			},
   379  		},
   380  	}
   381  
   382  	for name, test := range tests {
   383  		t.Run(name, func(t *testing.T) {
   384  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   385  				assert.Equal(t, http.MethodPut, r.Method)
   386  				w.WriteHeader(test.responseStatus)
   387  				if len(test.responseBody) > 0 {
   388  					_, err := w.Write([]byte(test.responseBody))
   389  					assert.NoError(t, err)
   390  				}
   391  			}))
   392  			client := mockAPIClient(t, mockServer)
   393  			result, err := client.UpdateRuleConditionException(
   394  				session.ContextWithOptions(
   395  					context.Background(),
   396  					session.WithContextHeaders(test.headers)), test.params)
   397  			if test.withError != nil {
   398  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
   399  				return
   400  			}
   401  			require.NoError(t, err)
   402  			assert.Equal(t, test.expectedResponse, result)
   403  		})
   404  	}
   405  }