github.com/akamai/AkamaiOPEN-edgegrid-golang/v2@v2.17.0/pkg/session/request_test.go (about)

     1  package session
     2  
     3  import (
     4  	"crypto/tls"
     5  	"crypto/x509"
     6  	"errors"
     7  	"net/http"
     8  	"net/http/httptest"
     9  	"net/url"
    10  	"testing"
    11  
    12  	"github.com/akamai/AkamaiOPEN-edgegrid-golang/v2/pkg/edgegrid"
    13  	"github.com/stretchr/testify/assert"
    14  	"github.com/stretchr/testify/require"
    15  )
    16  
    17  type testStruct struct {
    18  	A string `json:"a"`
    19  	B int    `json:"b"`
    20  }
    21  
    22  type testInvalid struct {
    23  	Invalid func()
    24  }
    25  
    26  func TestSession_Exec(t *testing.T) {
    27  	tests := map[string]struct {
    28  		request             *http.Request
    29  		out                 testStruct
    30  		in                  []interface{}
    31  		responseBody        string
    32  		responseStatus      int
    33  		expectedContentType string
    34  		expectedUserAgent   string
    35  		expectedMethod      string
    36  		expectedPath        string
    37  		expected            interface{}
    38  		withError           error
    39  	}{
    40  		"GET request, use default values for request": {
    41  			request: func() *http.Request {
    42  				req, err := http.NewRequest(http.MethodGet, "/test/path", nil)
    43  				require.NoError(t, err)
    44  				return req
    45  			}(),
    46  			out:            testStruct{},
    47  			responseBody:   `{"a":"text","b":1}`,
    48  			responseStatus: http.StatusOK,
    49  			expectedMethod: http.MethodGet,
    50  			expectedPath:   "/test/path",
    51  			expected: testStruct{
    52  				A: "text",
    53  				B: 1,
    54  			},
    55  		},
    56  		"GET request, escape query": {
    57  			request: func() *http.Request {
    58  				req, err := http.NewRequest(http.MethodGet, "/test/path?param1=some param", nil)
    59  				require.NoError(t, err)
    60  				return req
    61  			}(),
    62  			out:            testStruct{},
    63  			responseBody:   `{"a":"text","b":1}`,
    64  			responseStatus: http.StatusOK,
    65  			expectedMethod: http.MethodGet,
    66  			expectedPath:   "/test/path?param1=some+param",
    67  			expected: testStruct{
    68  				A: "text",
    69  				B: 1,
    70  			},
    71  		},
    72  		"GET request, custom content type and user agent": {
    73  			request: func() *http.Request {
    74  				req, err := http.NewRequest(http.MethodGet, "/test/path", nil)
    75  				require.NoError(t, err)
    76  				req.Header.Set("Content-Type", "text/plain")
    77  				req.Header.Set("User-Agent", "other user agent")
    78  				return req
    79  			}(),
    80  			out:                 testStruct{},
    81  			responseBody:        `{"a":"text","b":1}`,
    82  			responseStatus:      http.StatusOK,
    83  			expectedMethod:      http.MethodGet,
    84  			expectedPath:        "/test/path",
    85  			expectedContentType: "text/plain",
    86  			expectedUserAgent:   "other user agent",
    87  			expected: testStruct{
    88  				A: "text",
    89  				B: 1,
    90  			},
    91  		},
    92  		"POST request, custom content type and user agent": {
    93  			request: func() *http.Request {
    94  				req, err := http.NewRequest(http.MethodPost, "/test/path", nil)
    95  				require.NoError(t, err)
    96  				req.Header.Set("Content-Type", "text/plain")
    97  				req.Header.Set("User-Agent", "other user agent")
    98  				return req
    99  			}(),
   100  			in: []interface{}{&testStruct{
   101  				A: "text",
   102  				B: 1,
   103  			}},
   104  			out:                 testStruct{},
   105  			responseBody:        `{"a":"text","b":1}`,
   106  			responseStatus:      http.StatusCreated,
   107  			expectedMethod:      http.MethodPost,
   108  			expectedPath:        "/test/path",
   109  			expectedContentType: "text/plain",
   110  			expectedUserAgent:   "other user agent",
   111  			expected: testStruct{
   112  				A: "text",
   113  				B: 1,
   114  			},
   115  		},
   116  		"POST request, invalid body": {
   117  			request: func() *http.Request {
   118  				req, err := http.NewRequest(http.MethodPost, "/test/path", nil)
   119  				require.NoError(t, err)
   120  				req.Header.Set("Content-Type", "text/plain")
   121  				req.Header.Set("User-Agent", "other user agent")
   122  				return req
   123  			}(),
   124  			in:        []interface{}{&testInvalid{func() {}}},
   125  			out:       testStruct{},
   126  			withError: ErrMarshaling,
   127  		},
   128  		"POST request, unmarshaling error": {
   129  			request: func() *http.Request {
   130  				req, err := http.NewRequest(http.MethodPost, "/test/path", nil)
   131  				require.NoError(t, err)
   132  				req.Header.Set("Content-Type", "text/plain")
   133  				req.Header.Set("User-Agent", "other user agent")
   134  				return req
   135  			}(),
   136  			in: []interface{}{&testStruct{
   137  				A: "text",
   138  				B: 1,
   139  			}},
   140  			out:                 testStruct{},
   141  			responseBody:        `{"a":1,"b":1}`,
   142  			responseStatus:      http.StatusCreated,
   143  			expectedMethod:      http.MethodPost,
   144  			expectedPath:        "/test/path",
   145  			expectedContentType: "text/plain",
   146  			expectedUserAgent:   "other user agent",
   147  			withError:           ErrUnmarshaling,
   148  		},
   149  		"invalid number of input parameters": {
   150  			in:        []interface{}{testStruct{}, testStruct{}},
   151  			withError: ErrInvalidArgument,
   152  		},
   153  	}
   154  
   155  	for name, test := range tests {
   156  		t.Run(name, func(t *testing.T) {
   157  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   158  				assert.Equal(t, test.expectedPath, r.URL.String())
   159  				assert.Equal(t, test.expectedMethod, r.Method)
   160  				if test.expectedContentType == "" {
   161  					assert.Equal(t, "application/json", r.Header.Get("Content-Type"))
   162  				} else {
   163  					assert.Equal(t, test.expectedContentType, r.Header.Get("Content-Type"))
   164  				}
   165  				if test.expectedUserAgent == "" {
   166  					assert.Equal(t, "test user agent", r.Header.Get("User-Agent"))
   167  				} else {
   168  					assert.Equal(t, test.expectedUserAgent, r.Header.Get("User-Agent"))
   169  				}
   170  				w.WriteHeader(test.responseStatus)
   171  				_, err := w.Write([]byte(test.responseBody))
   172  				assert.NoError(t, err)
   173  			}))
   174  
   175  			certPool := x509.NewCertPool()
   176  			certPool.AddCert(mockServer.Certificate())
   177  			httpClient := &http.Client{
   178  				Transport: &http.Transport{
   179  					TLSClientConfig: &tls.Config{
   180  						RootCAs: certPool,
   181  					},
   182  				},
   183  			}
   184  			serverURL, err := url.Parse(mockServer.URL)
   185  			require.NoError(t, err)
   186  			s, err := New(WithSigner(&edgegrid.Config{
   187  				Host: serverURL.Host,
   188  			}), WithClient(httpClient), WithUserAgent("test user agent"), WithHTTPTracing(true))
   189  			require.NoError(t, err)
   190  
   191  			_, err = s.Exec(test.request, &test.out, test.in...)
   192  			if test.withError != nil {
   193  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
   194  				return
   195  			}
   196  			require.NoError(t, err)
   197  			assert.Equal(t, test.expected, test.out)
   198  		})
   199  	}
   200  }