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

     1  package edgeworkers
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"reflect"
     9  	"regexp"
    10  	"testing"
    11  
    12  	validation "github.com/go-ozzo/ozzo-validation/v4"
    13  
    14  	"github.com/stretchr/testify/assert"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  func TestListDeactivations(t *testing.T) {
    19  	tests := map[string]struct {
    20  		params         ListDeactivationsRequest
    21  		withError      error
    22  		expectedPath   string
    23  		responseStatus int
    24  		responseBody   string
    25  		expectedResult []Deactivation
    26  	}{
    27  		"400 bad request": {
    28  			params:    ListDeactivationsRequest{},
    29  			withError: ErrStructValidation,
    30  		},
    31  		"500 internal server error": {
    32  			params:         ListDeactivationsRequest{EdgeWorkerID: 5},
    33  			expectedPath:   "/edgeworkers/v1/ids/5/deactivations",
    34  			responseStatus: http.StatusInternalServerError,
    35  			responseBody: `{
    36  			  "detail": "An error occurred while fetching the activation",
    37  			  "instance": "/edgeworkers/error-instances/8b95c971-f6b3-4479-a393-202be75e43e1",
    38  			  "status": 500,
    39  			  "title": "An unexpected error has occurred.",
    40  			  "type": "/edgeworkers/error-types/edgeworkers-server-error",
    41  			  "errorCode": "EW4303"
    42  			}`,
    43  			withError: &Error{
    44  				Detail:    "An error occurred while fetching the activation",
    45  				Instance:  "/edgeworkers/error-instances/8b95c971-f6b3-4479-a393-202be75e43e1",
    46  				Status:    http.StatusInternalServerError,
    47  				Title:     "An unexpected error has occurred.",
    48  				Type:      "/edgeworkers/error-types/edgeworkers-server-error",
    49  				ErrorCode: "EW4303",
    50  			},
    51  		},
    52  		"200 OK": {
    53  			responseBody: `{
    54  					"deactivations":[
    55  						{
    56  							"edgeWorkerId":42,
    57  							"version":"2",
    58  							"deactivationId":3,
    59  							"accountId":"1-AB2CD34",
    60  							"status":"PENDING",
    61  							"network":"PRODUCTION",
    62  							"note":"EdgeWorker ID 42 is no longer used in production.",
    63  							"createdBy":"jdoe",
    64  							"createdTime":"2020-07-09T09:03:28Z",
    65  							"lastModifiedTime":"2020-07-09T09:04:42Z"
    66  						},
    67  						{
    68  							"edgeWorkerId":42,
    69  							"version":"1",
    70  							"deactivationId":1,
    71  							"accountId":"1-AB2CD34",
    72  							"status":"IN_PROGRESS",
    73  							"network":"STAGING",
    74  							"createdBy":"jsmith",
    75  							"createdTime":"2020-07-09T08:13:54Z",
    76  							"lastModifiedTime":"2020-07-09T08:35:02Z"
    77  						},
    78  						{
    79  							"edgeWorkerId":42,
    80  							"version":"2",
    81  							"deactivationId":2,
    82  							"accountId":"1-AB2CD34",
    83  							"status":"COMPLETE",
    84  							"network":"PRODUCTION",
    85  							"createdBy":"asmith",
    86  							"createdTime":"2020-07-10T14:23:42Z",
    87  							"lastModifiedTime":"2020-07-10T14:53:25Z"
    88  						}
    89  					]
    90  				}`,
    91  			expectedPath:   "/edgeworkers/v1/ids/42/deactivations",
    92  			responseStatus: http.StatusOK,
    93  			expectedResult: []Deactivation{
    94  				{
    95  					EdgeWorkerID:     42,
    96  					Version:          "2",
    97  					DeactivationID:   3,
    98  					AccountID:        "1-AB2CD34",
    99  					Status:           "PENDING",
   100  					Network:          ActivationNetworkProduction,
   101  					Note:             "EdgeWorker ID 42 is no longer used in production.",
   102  					CreatedBy:        "jdoe",
   103  					CreatedTime:      "2020-07-09T09:03:28Z",
   104  					LastModifiedTime: "2020-07-09T09:04:42Z",
   105  				},
   106  				{
   107  					EdgeWorkerID:     42,
   108  					Version:          "1",
   109  					DeactivationID:   1,
   110  					AccountID:        "1-AB2CD34",
   111  					Status:           "IN_PROGRESS",
   112  					Network:          ActivationNetworkStaging,
   113  					CreatedBy:        "jsmith",
   114  					CreatedTime:      "2020-07-09T08:13:54Z",
   115  					LastModifiedTime: "2020-07-09T08:35:02Z",
   116  				},
   117  				{
   118  					EdgeWorkerID:     42,
   119  					Version:          "2",
   120  					DeactivationID:   2,
   121  					AccountID:        "1-AB2CD34",
   122  					Status:           "COMPLETE",
   123  					Network:          ActivationNetworkProduction,
   124  					CreatedBy:        "asmith",
   125  					CreatedTime:      "2020-07-10T14:23:42Z",
   126  					LastModifiedTime: "2020-07-10T14:53:25Z",
   127  				},
   128  			},
   129  			params: ListDeactivationsRequest{EdgeWorkerID: 42},
   130  		},
   131  		"200 OK with version": {
   132  			responseBody: `{
   133  					"deactivations":[
   134  						{
   135  							"edgeWorkerId":41,
   136  							"version":"2",
   137  							"deactivationId":3,
   138  							"accountId":"1-AB2CD34",
   139  							"status":"PENDING",
   140  							"network":"PRODUCTION",
   141  							"note":"EdgeWorker ID 41 is no longer used in production.",
   142  							"createdBy":"jdoe",
   143  							"createdTime":"2020-07-09T09:03:28Z",
   144  							"lastModifiedTime":"2020-07-09T09:04:42Z"
   145  						},
   146  						{
   147  							"edgeWorkerId":41,
   148  							"version":"2",
   149  							"deactivationId":2,
   150  							"accountId":"1-AB2CD34",
   151  							"status":"COMPLETE",
   152  							"network":"PRODUCTION",
   153  							"createdBy":"asmith",
   154  							"createdTime":"2020-07-10T14:23:42Z",
   155  							"lastModifiedTime":"2020-07-10T14:53:25Z"
   156  						}
   157  					]
   158  				}`,
   159  			expectedPath:   "/edgeworkers/v1/ids/42/deactivations?version=2",
   160  			responseStatus: http.StatusOK,
   161  			expectedResult: []Deactivation{
   162  				{
   163  					EdgeWorkerID:     41,
   164  					Version:          "2",
   165  					DeactivationID:   3,
   166  					AccountID:        "1-AB2CD34",
   167  					Status:           "PENDING",
   168  					Network:          ActivationNetworkProduction,
   169  					Note:             "EdgeWorker ID 41 is no longer used in production.",
   170  					CreatedBy:        "jdoe",
   171  					CreatedTime:      "2020-07-09T09:03:28Z",
   172  					LastModifiedTime: "2020-07-09T09:04:42Z",
   173  				},
   174  				{
   175  					EdgeWorkerID:     41,
   176  					Version:          "2",
   177  					DeactivationID:   2,
   178  					AccountID:        "1-AB2CD34",
   179  					Status:           "COMPLETE",
   180  					Network:          ActivationNetworkProduction,
   181  					CreatedBy:        "asmith",
   182  					CreatedTime:      "2020-07-10T14:23:42Z",
   183  					LastModifiedTime: "2020-07-10T14:53:25Z",
   184  				},
   185  			},
   186  			params: ListDeactivationsRequest{
   187  				EdgeWorkerID: 42,
   188  				Version:      "2",
   189  			},
   190  		},
   191  	}
   192  	for name, test := range tests {
   193  		t.Run(name, func(t *testing.T) {
   194  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   195  				assert.Equal(t, test.expectedPath, r.URL.String())
   196  				assert.Equal(t, http.MethodGet, r.Method)
   197  				w.WriteHeader(test.responseStatus)
   198  				_, err := w.Write([]byte(test.responseBody))
   199  				assert.NoError(t, err)
   200  			}))
   201  			client := mockAPIClient(t, mockServer)
   202  
   203  			result, err := client.ListDeactivations(context.Background(), test.params)
   204  			if test.withError != nil {
   205  				require.Error(t, err)
   206  				assert.True(t, errors.Is(err, test.withError))
   207  				return
   208  			}
   209  
   210  			require.NoError(t, err)
   211  			assert.True(t, reflect.DeepEqual(result.Deactivations, test.expectedResult))
   212  		})
   213  	}
   214  }
   215  
   216  func TestListDeactivationsRequest_Validate(t *testing.T) {
   217  	tests := map[string]struct {
   218  		params ListDeactivationsRequest
   219  		errors validation.Errors
   220  	}{
   221  		"no EW ID": {
   222  			params: ListDeactivationsRequest{},
   223  			errors: validation.Errors{
   224  				"EdgeWorkerID": validation.ErrorObject{}.SetCode("validation_required").SetMessage("cannot be blank"),
   225  			},
   226  		},
   227  		"EW ID": {
   228  			params: ListDeactivationsRequest{EdgeWorkerID: 1},
   229  		},
   230  	}
   231  	for name, test := range tests {
   232  		t.Run(name, func(t *testing.T) {
   233  			err := test.params.Validate()
   234  			if len(test.errors) != 0 {
   235  				require.Error(t, err)
   236  				assert.Equal(t, test.errors, err)
   237  				return
   238  			}
   239  			require.NoError(t, err)
   240  		})
   241  	}
   242  }
   243  
   244  func TestEdgeWorkerDeactivateVersionRequest_Validate(t *testing.T) {
   245  	tests := map[string]struct {
   246  		params DeactivateVersionRequest
   247  		errors *regexp.Regexp
   248  	}{
   249  		"no EW ID": {
   250  			params: DeactivateVersionRequest{
   251  				DeactivateVersion: DeactivateVersion{
   252  					Version: "--",
   253  					Network: ActivationNetworkProduction,
   254  				},
   255  			},
   256  			errors: regexp.MustCompile(`EdgeWorkerID.+cannot be blank.+`),
   257  		},
   258  		"no version": {
   259  			params: DeactivateVersionRequest{
   260  				EdgeWorkerID: 1,
   261  				DeactivateVersion: DeactivateVersion{
   262  					Network: ActivationNetworkProduction,
   263  				},
   264  			},
   265  			errors: regexp.MustCompile(`DeactivateVersion:.+Version:.+cannot be blank.+`),
   266  		},
   267  		"bad network": {
   268  			params: DeactivateVersionRequest{
   269  				EdgeWorkerID: 1,
   270  				DeactivateVersion: DeactivateVersion{
   271  					Network: "-asdfa",
   272  					Version: "a",
   273  				},
   274  			},
   275  			errors: regexp.MustCompile(`DeactivateVersion:.+Network:.+value '-asdfa' is invalid. Must be one of: 'STAGING' or 'PRODUCTION'.+`),
   276  		},
   277  		"no network": {
   278  			params: DeactivateVersionRequest{
   279  				EdgeWorkerID: 1,
   280  				DeactivateVersion: DeactivateVersion{
   281  					Version: "a",
   282  				},
   283  			},
   284  			errors: regexp.MustCompile(`DeactivateVersion:.+Network:.+cannot be blank.+`),
   285  		},
   286  		"ok": {
   287  			params: DeactivateVersionRequest{
   288  				EdgeWorkerID: 1,
   289  				DeactivateVersion: DeactivateVersion{
   290  					Version: "asdf",
   291  					Network: ActivationNetworkStaging,
   292  				},
   293  			},
   294  		},
   295  	}
   296  	for name, test := range tests {
   297  		t.Run(name, func(t *testing.T) {
   298  			err := test.params.Validate()
   299  			if test.errors != nil {
   300  				require.Error(t, err)
   301  				assert.Regexp(t, test.errors, err.Error())
   302  				return
   303  			}
   304  			require.NoError(t, err)
   305  		})
   306  	}
   307  }
   308  
   309  func TestEdgeworkers_DeactivateVersion(t *testing.T) {
   310  	tests := map[string]struct {
   311  		params           DeactivateVersionRequest
   312  		withError        error
   313  		expectedPath     string
   314  		responseStatus   int
   315  		responseBody     string
   316  		expectedResponse Deactivation
   317  	}{
   318  		"400 bad request": {
   319  			params:    DeactivateVersionRequest{},
   320  			withError: ErrStructValidation,
   321  		},
   322  		"201 created": {
   323  			params: DeactivateVersionRequest{
   324  				EdgeWorkerID: 1,
   325  				DeactivateVersion: DeactivateVersion{
   326  					Version: "123",
   327  					Network: ActivationNetworkProduction,
   328  					Note:    "not used",
   329  				},
   330  			},
   331  			expectedPath: "/edgeworkers/v1/ids/1/deactivations",
   332  			responseBody: `{
   333  				"edgeWorkerId": 1,
   334  				"version": "123",
   335  				"deactivationId": 1,
   336  				"accountId": "B-3-WNKA6P",
   337  				"status": "PRESUBMIT",
   338  				"network": "PRODUCTION",
   339  				"note": "not used",
   340  				"createdBy": "agrebenk",
   341  				"createdTime": "2021-12-17T10:07:35Z",
   342  				"lastModifiedTime": "2021-12-17T10:07:35Z"
   343  			}`,
   344  			responseStatus: http.StatusCreated,
   345  			expectedResponse: Deactivation{
   346  				EdgeWorkerID:     1,
   347  				Version:          "123",
   348  				DeactivationID:   1,
   349  				AccountID:        "B-3-WNKA6P",
   350  				Status:           "PRESUBMIT",
   351  				Network:          ActivationNetworkProduction,
   352  				Note:             "not used",
   353  				CreatedBy:        "agrebenk",
   354  				CreatedTime:      "2021-12-17T10:07:35Z",
   355  				LastModifiedTime: "2021-12-17T10:07:35Z",
   356  			},
   357  		},
   358  		"500 server error": {
   359  			params: DeactivateVersionRequest{
   360  				EdgeWorkerID: 1,
   361  				DeactivateVersion: DeactivateVersion{
   362  					Version: "123",
   363  					Network: ActivationNetworkProduction,
   364  					Note:    "not used",
   365  				},
   366  			},
   367  			expectedPath:   "/edgeworkers/v1/ids/1/deactivations",
   368  			responseStatus: http.StatusInternalServerError,
   369  			responseBody: `{
   370  			  "detail": "An error occurred while fetching the activation",
   371  			  "instance": "/edgeworkers/error-instances/8b95c971-f6b3-4479-a393-202be75e43e1",
   372  			  "status": 500,
   373  			  "title": "An unexpected error has occurred.",
   374  			  "type": "/edgeworkers/error-types/edgeworkers-server-error",
   375  			  "errorCode": "EW4303"
   376  			}`,
   377  			withError: &Error{
   378  				Type:      "/edgeworkers/error-types/edgeworkers-server-error",
   379  				Title:     "An unexpected error has occurred.",
   380  				Detail:    "An error occurred while fetching the activation",
   381  				Instance:  "/edgeworkers/error-instances/8b95c971-f6b3-4479-a393-202be75e43e1",
   382  				Status:    http.StatusInternalServerError,
   383  				ErrorCode: "EW4303",
   384  			},
   385  		},
   386  	}
   387  	for name, test := range tests {
   388  		t.Run(name, func(t *testing.T) {
   389  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   390  				assert.Equal(t, test.expectedPath, r.URL.String())
   391  				assert.Equal(t, http.MethodPost, r.Method)
   392  				w.WriteHeader(test.responseStatus)
   393  				_, err := w.Write([]byte(test.responseBody))
   394  				assert.NoError(t, err)
   395  			}))
   396  			client := mockAPIClient(t, mockServer)
   397  
   398  			response, err := client.DeactivateVersion(context.Background(), test.params)
   399  			if test.withError != nil {
   400  				require.Error(t, err)
   401  				assert.True(t, errors.Is(err, test.withError))
   402  				return
   403  			}
   404  			require.NoError(t, err)
   405  
   406  			assert.True(t, reflect.DeepEqual(test.expectedResponse, *response))
   407  		})
   408  	}
   409  }
   410  
   411  func TestEdgeWorkerGetDeactivationRequest_Validate(t *testing.T) {
   412  	tests := map[string]struct {
   413  		request GetDeactivationRequest
   414  		errors  validation.Errors
   415  	}{
   416  		"no EW ID": {
   417  			request: GetDeactivationRequest{DeactivationID: 1},
   418  			errors: map[string]error{
   419  				"EdgeWorkerID": validation.ErrorObject{}.SetCode("validation_required").SetMessage("cannot be blank"),
   420  			},
   421  		},
   422  		"no Deactivation ID": {
   423  			request: GetDeactivationRequest{EdgeWorkerID: 1},
   424  			errors: map[string]error{
   425  				"DeactivationID": validation.ErrorObject{}.SetCode("validation_required").SetMessage("cannot be blank"),
   426  			},
   427  		},
   428  	}
   429  	for name, test := range tests {
   430  		t.Run(name, func(t *testing.T) {
   431  			err := test.request.Validate()
   432  			if len(test.errors) != 0 {
   433  				require.Error(t, err)
   434  				assert.Equal(t, test.errors, err)
   435  				return
   436  			}
   437  			assert.True(t, false)
   438  		})
   439  	}
   440  }
   441  
   442  func TestEdgeworkers_GetDeactivation(t *testing.T) {
   443  	tests := map[string]struct {
   444  		request              GetDeactivationRequest
   445  		expectedDeactivation Deactivation
   446  		withError            error
   447  		expectedPath         string
   448  		responseStatus       int
   449  		responseBody         string
   450  	}{
   451  		"request validation error": {
   452  			request:   GetDeactivationRequest{},
   453  			withError: ErrStructValidation,
   454  		},
   455  		"404 deactivation not found": {
   456  			request: GetDeactivationRequest{
   457  				EdgeWorkerID:   1,
   458  				DeactivationID: 2,
   459  			},
   460  			responseStatus: http.StatusNotFound,
   461  			responseBody: `{
   462  			  "detail": "Unable to find the requested EdgeWorker ID",
   463  			  "errorCode": "EW2002",
   464  			  "instance": "/edgeworkers/error-instances/76b1595d-08e5-46a8-8bc6-72d01e621303",
   465  			  "status": 404,
   466  			  "title": "The given resource could not be found.",
   467  			  "type": "/edgeworkers/error-types/edgeworkers-bad-request"
   468  			}`,
   469  			withError: &Error{
   470  				Type:      "/edgeworkers/error-types/edgeworkers-bad-request",
   471  				Title:     "The given resource could not be found.",
   472  				Detail:    "Unable to find the requested EdgeWorker ID",
   473  				Instance:  "/edgeworkers/error-instances/76b1595d-08e5-46a8-8bc6-72d01e621303",
   474  				Status:    http.StatusNotFound,
   475  				ErrorCode: "EW2002",
   476  			},
   477  			expectedPath: "/edgeworkers/v1/ids/1/deactivations/2",
   478  		},
   479  		"200 ok": {
   480  			request: GetDeactivationRequest{
   481  				EdgeWorkerID:   1,
   482  				DeactivationID: 2,
   483  			},
   484  			responseStatus: http.StatusOK,
   485  			expectedPath:   "/edgeworkers/v1/ids/1/deactivations/2",
   486  			responseBody: `{
   487  				"edgeWorkerId": 1,
   488  				"version": "1.0aSDA",
   489  				"deactivationId": 2,
   490  				"accountId": "B-3-WNKA6P",
   491  				"status": "COMPLETE",
   492  				"network": "PRODUCTION",
   493  				"note": "not used",
   494  				"createdBy": "agrebenk",
   495  				"createdTime": "2021-12-17T10:07:35Z",
   496  				"lastModifiedTime": "2021-12-17T10:24:02Z"
   497  			}`,
   498  			expectedDeactivation: Deactivation{
   499  				EdgeWorkerID:     1,
   500  				Version:          "1.0aSDA",
   501  				DeactivationID:   2,
   502  				AccountID:        "B-3-WNKA6P",
   503  				Status:           "COMPLETE",
   504  				Network:          ActivationNetworkProduction,
   505  				Note:             "not used",
   506  				CreatedBy:        "agrebenk",
   507  				CreatedTime:      "2021-12-17T10:07:35Z",
   508  				LastModifiedTime: "2021-12-17T10:24:02Z",
   509  			},
   510  		},
   511  	}
   512  	for name, test := range tests {
   513  		t.Run(name, func(t *testing.T) {
   514  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   515  				assert.Equal(t, test.expectedPath, r.URL.String())
   516  				assert.Equal(t, http.MethodGet, r.Method)
   517  				w.WriteHeader(test.responseStatus)
   518  				_, err := w.Write([]byte(test.responseBody))
   519  				assert.NoError(t, err)
   520  			}))
   521  			client := mockAPIClient(t, mockServer)
   522  
   523  			response, err := client.GetDeactivation(context.Background(), test.request)
   524  			if test.withError != nil {
   525  				require.Error(t, err)
   526  				assert.True(t, errors.Is(err, test.withError))
   527  				return
   528  			}
   529  			require.NoError(t, err)
   530  			assert.True(t, reflect.DeepEqual(test.expectedDeactivation, *response))
   531  		})
   532  	}
   533  }