go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/sdk/r2/request_test.go (about) 1 /* 2 3 Copyright (c) 2023 - Present. Will Charczuk. All rights reserved. 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository. 5 6 */ 7 8 package r2 9 10 import ( 11 "bytes" 12 "context" 13 "encoding/gob" 14 "errors" 15 "fmt" 16 "net/http" 17 "net/http/httptest" 18 "testing" 19 "time" 20 21 . "go.charczuk.com/sdk/assert" 22 ) 23 24 func Test_New(t *testing.T) { 25 r := New("https://foo.com/bar?buzz=fuzz") 26 ItsNotNil(t, r) 27 ItsNil(t, r.err) 28 ItsEqual(t, http.MethodGet, r.req.Method) 29 ItsNotNil(t, r.req.URL) 30 ItsEqual(t, "https://foo.com/bar?buzz=fuzz", r.req.URL.String()) 31 32 rErr := New("\n") 33 ItsNotNil(t, rErr) 34 ItsNotNil(t, rErr.err) 35 } 36 37 func Test_Request_WithContext(t *testing.T) { 38 r := New("https://foo.com/bar?buzz=fuzz") 39 type valueKey struct{} 40 const value = "hello!" 41 r = r.WithContext(context.WithValue(context.Background(), valueKey{}, value)) 42 ItsNotNil(t, r.req.Context()) 43 ItsEqual(t, value, r.req.Context().Value(valueKey{})) 44 } 45 46 func Test_Request_Do(t *testing.T) { 47 server := mockServerOK() 48 defer server.Close() 49 50 res, err := New(server.URL).Do() 51 ItsNil(t, err) 52 ItsEqual(t, http.StatusOK, res.StatusCode) 53 } 54 55 func Test_Request_Do_earlyAbortsOnError(t *testing.T) { 56 var didCallServer bool 57 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 58 didCallServer = true 59 w.WriteHeader(http.StatusOK) 60 fmt.Fprintf(w, "OK!\n") 61 })) 62 defer server.Close() 63 64 r := New(server.URL) 65 r.err = errors.New("this is only a test") 66 _, err := r.Do() 67 ItsNotNil(t, err) 68 ItsEqual(t, "this is only a test", err.Error()) 69 ItsEqual(t, false, didCallServer) 70 } 71 72 func Test_Request_Do_headers(t *testing.T) { 73 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 74 if value := r.Header.Get("foo"); value != "bar" { 75 w.WriteHeader(http.StatusBadRequest) 76 fmt.Fprintf(w, "bad value for header foo: %v\n", value) 77 return 78 } 79 w.WriteHeader(http.StatusOK) 80 fmt.Fprintf(w, "OK!\n") 81 })) 82 defer server.Close() 83 84 res, err := New(server.URL, OptHeader("foo", "bar")).Do() 85 ItsNil(t, err) 86 ItsEqual(t, http.StatusOK, res.StatusCode) 87 } 88 89 func Test_Request_Do_query(t *testing.T) { 90 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 91 if value := r.URL.Query().Get("foo"); value != "bar" { 92 w.WriteHeader(http.StatusBadRequest) 93 fmt.Fprintf(w, "bad value for query string key foo: %v\n", value) 94 return 95 } 96 w.WriteHeader(http.StatusOK) 97 fmt.Fprintf(w, "OK!\n") 98 })) 99 defer server.Close() 100 101 res, err := New(server.URL, OptQuery("foo", "bar")).Do() 102 ItsNil(t, err) 103 ItsEqual(t, http.StatusOK, res.StatusCode) 104 } 105 106 func Test_Request_Discard(t *testing.T) { 107 server := mockServerOK() 108 defer server.Close() 109 res, err := New(server.URL).Discard() 110 ItsNil(t, err) 111 ItsNotNil(t, res) 112 } 113 114 func Test_Request_CopyTo(t *testing.T) { 115 server := mockServerOK() 116 defer server.Close() 117 buf := new(bytes.Buffer) 118 _, err := New(server.URL).CopyTo(buf) 119 ItsNil(t, err) 120 ItsEqual(t, "OK!\n", buf.String()) 121 } 122 123 func Test_Request_Bytes(t *testing.T) { 124 server := mockServerOK() 125 defer server.Close() 126 contents, meta, err := New(server.URL).Bytes() 127 ItsNil(t, err) 128 ItsEqual(t, http.StatusOK, meta.StatusCode) 129 ItsEqual(t, "OK!\n", contents) 130 } 131 132 func Test_Request_JSON(t *testing.T) { 133 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 134 w.WriteHeader(http.StatusOK) 135 fmt.Fprintf(w, "{\"status\":\"ok!\"}\n") 136 })) 137 defer server.Close() 138 139 var deserialized map[string]interface{} 140 res, err := New(server.URL).JSON(&deserialized) 141 ItsNil(t, err) 142 ItsEqual(t, http.StatusOK, res.StatusCode) 143 ItsEqual(t, "ok!", deserialized["status"]) 144 } 145 146 func Test_Request_JSON_noContent(t *testing.T) { 147 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 148 w.WriteHeader(http.StatusNoContent) 149 })) 150 defer server.Close() 151 152 var deserialized map[string]interface{} 153 res, err := New(server.URL).JSON(&deserialized) 154 ItsEqual(t, true, errors.Is(err, ErrNoContentJSON)) 155 ItsEqual(t, http.StatusNoContent, res.StatusCode) 156 } 157 158 func Test_Request_Gob(t *testing.T) { 159 160 type gobValue struct { 161 Foo string 162 Bar string 163 } 164 165 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 166 w.WriteHeader(http.StatusOK) 167 _ = gob.NewEncoder(w).Encode(gobValue{"FooValue", "BarValue"}) 168 })) 169 defer server.Close() 170 171 var deserialized gobValue 172 res, err := New(server.URL).Gob(&deserialized) 173 ItsNil(t, err) 174 ItsEqual(t, http.StatusOK, res.StatusCode) 175 ItsEqual(t, "FooValue", deserialized.Foo) 176 ItsEqual(t, "BarValue", deserialized.Bar) 177 } 178 179 func Test_Request_listeners(t *testing.T) { 180 server := mockServerOK() 181 defer server.Close() 182 183 var didCallRequest1, didCallRequest2, didCallResponse1, didCallResponse2 bool 184 _, err := New(server.URL, 185 OptOnRequest(func(_ *http.Request) error { 186 didCallRequest1 = true 187 return nil 188 }), 189 OptOnRequest(func(_ *http.Request) error { 190 didCallRequest2 = true 191 return nil 192 }), 193 OptOnResponse(func(_ *http.Request, _ *http.Response, _ time.Time, _ error) error { 194 didCallResponse1 = true 195 return nil 196 }), 197 OptOnResponse(func(_ *http.Request, _ *http.Response, _ time.Time, _ error) error { 198 didCallResponse2 = true 199 return nil 200 }), 201 ).Discard() 202 ItsNil(t, err) 203 ItsEqual(t, true, didCallRequest1) 204 ItsEqual(t, true, didCallRequest2) 205 ItsEqual(t, true, didCallResponse1) 206 ItsEqual(t, true, didCallResponse2) 207 }