github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/gtm/domain_test.go (about) 1 package gtm 2 3 import ( 4 "bytes" 5 "context" 6 "encoding/gob" 7 "encoding/json" 8 "errors" 9 "net/http" 10 "net/http/httptest" 11 "testing" 12 13 "github.com/akamai/AkamaiOPEN-edgegrid-golang/v8/pkg/session" 14 "github.com/stretchr/testify/assert" 15 "github.com/stretchr/testify/require" 16 ) 17 18 func TestGTM_ListDomains(t *testing.T) { 19 tests := map[string]struct { 20 responseStatus int 21 responseBody string 22 expectedPath string 23 expectedResponse []*DomainItem 24 withError error 25 headers http.Header 26 }{ 27 "200 OK": { 28 headers: http.Header{ 29 "Content-Type": []string{"application/vnd.config-gtm.v1.4+json;charset=UTF-8"}, 30 }, 31 responseStatus: http.StatusOK, 32 responseBody: `{ 33 "items":[{ 34 "acgId": "1-2345", 35 "lastModified": "2014-03-03T16:02:45.000+0000", 36 "name": "example.akadns.net", 37 "status": "2014-02-20 22:56 GMT: Current configuration has been propagated to all GTM name servers", 38 "lastModifiedBy": "test-user", 39 "changeId": "abf5b76f-f9de-4404-bb2c-9d15e7b9ff5d", 40 "activationState": "COMPLETE", 41 "modificationComments": "terraform test gtm domain", 42 "signAndServe": false, 43 "signAndServeAlgorithm": null, 44 "deleteRequestId": null, 45 "links": [{ 46 "href": "/config-gtm/v1/domains/example.akadns.net", 47 "rel": "self" 48 }] 49 }, 50 { 51 "acgId": "1-2345", 52 "lastModified": "2013-11-09T12:04:45.000+0000", 53 "name": "demo.akadns.net", 54 "status": "2014-02-20 22:56 GMT: Current configuration has been propagated to all GTM name servers", 55 "lastModifiedBy": "test-user", 56 "changeId": "abf5b76f-f9de-4404-bb2c-9d15e7b9ff5d", 57 "activationState": "COMPLETE", 58 "modificationComments": "terraform test gtm domain", 59 "signAndServe": false, 60 "signAndServeAlgorithm": null, 61 "deleteRequestId": null, 62 "links": [{ 63 "href": "/config-gtm/v1/domains/example.akadns.net", 64 "rel": "self" 65 }] 66 }]}`, 67 expectedPath: "/config-gtm/v1/domains", 68 expectedResponse: []*DomainItem{{ 69 AcgID: "1-2345", 70 LastModified: "2014-03-03T16:02:45.000+0000", 71 Name: "example.akadns.net", 72 Status: "2014-02-20 22:56 GMT: Current configuration has been propagated to all GTM name servers", 73 LastModifiedBy: "test-user", 74 ChangeID: "abf5b76f-f9de-4404-bb2c-9d15e7b9ff5d", 75 ActivationState: "COMPLETE", 76 ModificationComments: "terraform test gtm domain", 77 SignAndServe: false, 78 SignAndServeAlgorithm: "", 79 DeleteRequestID: "", 80 Links: []*Link{{ 81 Rel: "self", 82 Href: "/config-gtm/v1/domains/example.akadns.net", 83 }}, 84 }, 85 { 86 AcgID: "1-2345", 87 LastModified: "2013-11-09T12:04:45.000+0000", 88 Name: "demo.akadns.net", 89 Status: "2014-02-20 22:56 GMT: Current configuration has been propagated to all GTM name servers", 90 LastModifiedBy: "test-user", 91 ChangeID: "abf5b76f-f9de-4404-bb2c-9d15e7b9ff5d", 92 ActivationState: "COMPLETE", 93 ModificationComments: "terraform test gtm domain", 94 SignAndServe: false, 95 SignAndServeAlgorithm: "", 96 DeleteRequestID: "", 97 Links: []*Link{{ 98 Rel: "self", 99 Href: "/config-gtm/v1/domains/example.akadns.net", 100 }}, 101 }}, 102 }, 103 "500 internal server error": { 104 headers: http.Header{}, 105 responseStatus: http.StatusInternalServerError, 106 responseBody: `{ 107 "type": "internal_error", 108 "title": "Internal Server Error", 109 "detail": "Error fetching domains", 110 "status": 500 111 }`, 112 expectedPath: "/config-gtm/v1/domains", 113 withError: &Error{ 114 Type: "internal_error", 115 Title: "Internal Server Error", 116 Detail: "Error fetching domains", 117 StatusCode: http.StatusInternalServerError, 118 }, 119 }, 120 "Service Unavailable plain text response": { 121 headers: http.Header{}, 122 responseStatus: http.StatusServiceUnavailable, 123 responseBody: `Your request did not succeed as this operation has reached the limit for your account. Please try after 2024-01-16T15:20:55.945Z`, 124 expectedPath: "/config-gtm/v1/domains", 125 withError: &Error{ 126 Type: "", 127 Title: "Failed to unmarshal error body. GTM API failed. Check details for more information.", 128 Detail: "Your request did not succeed as this operation has reached the limit for your account. Please try after 2024-01-16T15:20:55.945Z", 129 StatusCode: http.StatusServiceUnavailable, 130 }, 131 }, 132 "Service Unavailable html response": { 133 headers: http.Header{}, 134 responseStatus: http.StatusServiceUnavailable, 135 responseBody: `<HTML><HEAD>...</HEAD><BODY>...</BODY></HTML>`, 136 expectedPath: "/config-gtm/v1/domains", 137 withError: &Error{ 138 Type: "", 139 Title: "Failed to unmarshal error body. GTM API failed. Check details for more information.", 140 Detail: "<HTML><HEAD>...</HEAD><BODY>...</BODY></HTML>", 141 StatusCode: http.StatusServiceUnavailable, 142 }, 143 }, 144 "Service Unavailable xml response": { 145 headers: http.Header{}, 146 responseStatus: http.StatusServiceUnavailable, 147 responseBody: `<?xml version="1.0" encoding="UTF-8"?><root><item><id>1</id><name>Item 1</name></item><item><id>2</id><name>Item 2</name></item></root>`, 148 expectedPath: "/config-gtm/v1/domains", 149 withError: &Error{ 150 Type: "", 151 Title: "Failed to unmarshal error body. GTM API failed. Check details for more information.", 152 Detail: "<?xml version=\"1.0\" encoding=\"UTF-8\"?><root><item><id>1</id><name>Item 1</name></item><item><id>2</id><name>Item 2</name></item></root>", 153 StatusCode: http.StatusServiceUnavailable, 154 }, 155 }, 156 } 157 158 for name, test := range tests { 159 t.Run(name, func(t *testing.T) { 160 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 161 assert.Equal(t, test.expectedPath, r.URL.String()) 162 assert.Equal(t, http.MethodGet, r.Method) 163 w.WriteHeader(test.responseStatus) 164 _, err := w.Write([]byte(test.responseBody)) 165 assert.NoError(t, err) 166 })) 167 client := mockAPIClient(t, mockServer) 168 result, err := client.ListDomains( 169 session.ContextWithOptions( 170 context.Background(), 171 session.WithContextHeaders(test.headers))) 172 if test.withError != nil { 173 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 174 return 175 } 176 require.NoError(t, err) 177 assert.Equal(t, test.expectedResponse, result) 178 }) 179 } 180 } 181 182 func TestGTM_NullFieldMap(t *testing.T) { 183 var result NullFieldMapStruct 184 185 gob.Register(map[string]NullPerObjectAttributeStruct{}) 186 187 respData, err := loadTestData("TestGTM_NullFieldMap.resp.json") 188 if err != nil { 189 t.Fatal(err) 190 } 191 192 resultData, err := loadTestData("TestGTM_NullFieldMap.result.gob") 193 if err != nil { 194 t.Fatal(err) 195 } 196 197 if err := gob.NewDecoder(bytes.NewBuffer(resultData)).Decode(&result); err != nil { 198 t.Fatal(err) 199 } 200 201 tests := map[string]struct { 202 arg *Domain 203 responseStatus int 204 responseBody []byte 205 expectedPath string 206 expectedResponse *NullFieldMapStruct 207 withError error 208 }{ 209 "200 OK": { 210 arg: &Domain{ 211 Name: "example.akadns.net", 212 Type: "primary", 213 }, 214 responseStatus: http.StatusOK, 215 responseBody: respData, 216 expectedPath: "/config-gtm/v1/domains/example.akadns.net", 217 expectedResponse: &result, 218 }, 219 "500 internal server error": { 220 arg: &Domain{ 221 Name: "example.akadns.net", 222 Type: "primary", 223 }, 224 responseStatus: http.StatusInternalServerError, 225 responseBody: []byte(` 226 { 227 "type": "internal_error", 228 "title": "Internal Server Error", 229 "detail": "Error fetching null field map", 230 "status": 500 231 }`), 232 expectedPath: "/config-gtm/v1/domains/example.akadns.net", 233 withError: &Error{ 234 Type: "internal_error", 235 Title: "Internal Server Error", 236 Detail: "Error fetching null field map", 237 StatusCode: http.StatusInternalServerError, 238 }, 239 }, 240 } 241 242 for name, test := range tests { 243 t.Run(name, func(t *testing.T) { 244 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 245 assert.Equal(t, test.expectedPath, r.URL.String()) 246 assert.Equal(t, http.MethodGet, r.Method) 247 w.WriteHeader(test.responseStatus) 248 _, err := w.Write(test.responseBody) 249 assert.NoError(t, err) 250 })) 251 client := mockAPIClient(t, mockServer) 252 result, err := client.NullFieldMap(context.Background(), test.arg) 253 if test.withError != nil { 254 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 255 return 256 } 257 require.NoError(t, err) 258 assert.Equal(t, test.expectedResponse, result) 259 }) 260 } 261 } 262 263 func TestGTM_GetDomain(t *testing.T) { 264 var result Domain 265 266 respData, err := loadTestData("TestGTM_GetDomain.resp.json") 267 if err != nil { 268 t.Fatal(err) 269 } 270 271 if err := json.NewDecoder(bytes.NewBuffer(respData)).Decode(&result); err != nil { 272 t.Fatal(err) 273 } 274 275 tests := map[string]struct { 276 domain string 277 responseStatus int 278 responseBody []byte 279 expectedPath string 280 expectedResponse *Domain 281 withError error 282 }{ 283 "200 OK": { 284 domain: "example.akadns.net", 285 responseStatus: http.StatusOK, 286 responseBody: respData, 287 expectedPath: "/config-gtm/v1/domains/example.akadns.net", 288 expectedResponse: &result, 289 }, 290 "500 internal server error": { 291 domain: "example.akadns.net", 292 responseStatus: http.StatusInternalServerError, 293 responseBody: []byte(` 294 { 295 "type": "internal_error", 296 "title": "Internal Server Error", 297 "detail": "Error fetching domain" 298 }`), 299 expectedPath: "/config-gtm/v1/domains/example.akadns.net", 300 withError: &Error{ 301 Type: "internal_error", 302 Title: "Internal Server Error", 303 Detail: "Error fetching domain", 304 StatusCode: http.StatusInternalServerError, 305 }, 306 }, 307 } 308 309 for name, test := range tests { 310 t.Run(name, func(t *testing.T) { 311 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 312 assert.Equal(t, test.expectedPath, r.URL.String()) 313 assert.Equal(t, http.MethodGet, r.Method) 314 w.WriteHeader(test.responseStatus) 315 _, err := w.Write(test.responseBody) 316 assert.NoError(t, err) 317 })) 318 client := mockAPIClient(t, mockServer) 319 result, err := client.GetDomain(context.Background(), test.domain) 320 if test.withError != nil { 321 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 322 return 323 } 324 require.NoError(t, err) 325 assert.Equal(t, test.expectedResponse, result) 326 }) 327 } 328 } 329 330 func TestGTM_CreateDomain(t *testing.T) { 331 var result DomainResponse 332 333 respData, err := loadTestData("TestGTM_GetDomain.resp.json") 334 if err != nil { 335 t.Fatal(err) 336 } 337 338 if err := json.NewDecoder(bytes.NewBuffer(respData)).Decode(&result); err != nil { 339 t.Fatal(err) 340 } 341 342 tests := map[string]struct { 343 domain Domain 344 query map[string]string 345 responseStatus int 346 responseBody []byte 347 expectedPath string 348 expectedResponse *DomainResponse 349 withError error 350 headers http.Header 351 }{ 352 "201 Created": { 353 domain: Domain{ 354 Name: "gtmdomtest.akadns.net", 355 Type: "basic", 356 }, 357 query: map[string]string{"contractId": "1-2ABCDE"}, 358 headers: http.Header{ 359 "Content-Type": []string{"application/vnd.config-gtm.v1.4+json;charset=UTF-8"}, 360 }, 361 responseStatus: http.StatusCreated, 362 responseBody: respData, 363 expectedResponse: &result, 364 expectedPath: "/config-gtm/v1/domains?contractId=1-2ABCDE", 365 }, 366 "500 internal server error": { 367 domain: Domain{ 368 Name: "gtmdomtest.akadns.net", 369 Type: "basic", 370 }, 371 query: map[string]string{"contractId": "1-2ABCDE"}, 372 responseStatus: http.StatusInternalServerError, 373 responseBody: []byte(` 374 { 375 "type": "internal_error", 376 "title": "Internal Server Error", 377 "detail": "Error creating domain" 378 }`), 379 expectedPath: "/config-gtm/v1/domains?contractId=1-2ABCDE", 380 withError: &Error{ 381 Type: "internal_error", 382 Title: "Internal Server Error", 383 Detail: "Error creating domain", 384 StatusCode: http.StatusInternalServerError, 385 }, 386 }, 387 } 388 389 for name, test := range tests { 390 t.Run(name, func(t *testing.T) { 391 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 392 assert.Equal(t, http.MethodPost, r.Method) 393 w.WriteHeader(test.responseStatus) 394 if len(test.responseBody) > 0 { 395 _, err := w.Write(test.responseBody) 396 assert.NoError(t, err) 397 } 398 })) 399 client := mockAPIClient(t, mockServer) 400 result, err := client.CreateDomain( 401 session.ContextWithOptions( 402 context.Background(), 403 session.WithContextHeaders(test.headers)), &test.domain, test.query) 404 if test.withError != nil { 405 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 406 return 407 } 408 require.NoError(t, err) 409 assert.Equal(t, test.expectedResponse, result) 410 }) 411 } 412 } 413 414 func TestGTM_UpdateDomain(t *testing.T) { 415 var result DomainResponse 416 417 respData, err := loadTestData("TestGTM_UpdateDomain.resp.json") 418 if err != nil { 419 t.Fatal(err) 420 } 421 422 if err := json.NewDecoder(bytes.NewBuffer(respData)).Decode(&result); err != nil { 423 t.Fatal(err) 424 } 425 426 tests := map[string]struct { 427 domain Domain 428 query map[string]string 429 responseStatus int 430 responseBody []byte 431 expectedPath string 432 expectedResponse *ResponseStatus 433 withError error 434 headers http.Header 435 }{ 436 "200 Success": { 437 domain: Domain{ 438 EndUserMappingEnabled: false, 439 Name: "gtmdomtest.akadns.net", 440 Type: "basic", 441 }, 442 query: map[string]string{"contractId": "1-2ABCDE"}, 443 headers: http.Header{ 444 "Content-Type": []string{"application/vnd.config-gtm.v1.4+json;charset=UTF-8"}, 445 }, 446 responseStatus: http.StatusCreated, 447 responseBody: respData, 448 expectedResponse: result.Status, 449 expectedPath: "/config-gtm/v1/domains?contractId=1-2ABCDE", 450 }, 451 "500 internal server error": { 452 domain: Domain{ 453 Name: "gtmdomtest.akadns.net", 454 Type: "basic", 455 }, 456 query: map[string]string{"contractId": "1-2ABCDE"}, 457 responseStatus: http.StatusInternalServerError, 458 responseBody: []byte(` 459 { 460 "type": "internal_error", 461 "title": "Internal Server Error", 462 "detail": "Error creating zone" 463 }`), 464 expectedPath: "/config-gtm/v1/domains?contractId=1-2ABCDE", 465 withError: &Error{ 466 Type: "internal_error", 467 Title: "Internal Server Error", 468 Detail: "Error creating zone", 469 StatusCode: http.StatusInternalServerError, 470 }, 471 }, 472 } 473 474 for name, test := range tests { 475 t.Run(name, func(t *testing.T) { 476 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 477 assert.Equal(t, http.MethodPut, r.Method) 478 w.WriteHeader(test.responseStatus) 479 if len(test.responseBody) > 0 { 480 _, err := w.Write(test.responseBody) 481 assert.NoError(t, err) 482 } 483 })) 484 client := mockAPIClient(t, mockServer) 485 result, err := client.UpdateDomain( 486 session.ContextWithOptions( 487 context.Background(), 488 session.WithContextHeaders(test.headers)), &test.domain, test.query) 489 if test.withError != nil { 490 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 491 return 492 } 493 require.NoError(t, err) 494 assert.Equal(t, test.expectedResponse, result) 495 }) 496 } 497 }