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 }