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 }