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

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