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  }