goyave.dev/goyave/v4@v4.4.11/request_test.go (about) 1 package goyave 2 3 import ( 4 "net" 5 "net/http" 6 "net/http/httptest" 7 "net/url" 8 "strings" 9 "testing" 10 "time" 11 12 "goyave.dev/goyave/v4/cors" 13 "goyave.dev/goyave/v4/util/fsutil" 14 15 "github.com/google/uuid" 16 "github.com/stretchr/testify/assert" 17 "goyave.dev/goyave/v4/validation" 18 ) 19 20 func createTestRequest(rawRequest *http.Request) *Request { 21 return &Request{ 22 httpRequest: rawRequest, 23 Rules: &validation.Rules{}, 24 Params: map[string]string{}, 25 } 26 } 27 func TestRequestContentLength(t *testing.T) { 28 rawRequest := httptest.NewRequest("GET", "/test-route", strings.NewReader("body")) 29 request := createTestRequest(rawRequest) 30 assert.Equal(t, int64(4), request.ContentLength()) 31 } 32 33 func TestRequestMethod(t *testing.T) { 34 rawRequest := httptest.NewRequest("GET", "/test-route", strings.NewReader("body")) 35 request := createTestRequest(rawRequest) 36 assert.Equal(t, "GET", request.Method()) 37 38 rawRequest = httptest.NewRequest("POST", "/test-route", strings.NewReader("body")) 39 request = createTestRequest(rawRequest) 40 assert.Equal(t, "POST", request.Method()) 41 } 42 43 func TestRequestRemoteAddress(t *testing.T) { 44 rawRequest := httptest.NewRequest("GET", "/test-route", strings.NewReader("body")) 45 request := createTestRequest(rawRequest) 46 assert.Equal(t, "192.0.2.1:1234", request.RemoteAddress()) 47 } 48 49 func TestRequestProtocol(t *testing.T) { 50 rawRequest := httptest.NewRequest("GET", "/test-route", strings.NewReader("body")) 51 request := createTestRequest(rawRequest) 52 assert.Equal(t, "HTTP/1.1", request.Protocol()) 53 } 54 55 func TestRequestURL(t *testing.T) { 56 rawRequest := httptest.NewRequest("GET", "/test-route", strings.NewReader("body")) 57 request := createTestRequest(rawRequest) 58 assert.Equal(t, "/test-route", request.URI().Path) 59 } 60 61 func TestRequestReferrer(t *testing.T) { 62 rawRequest := httptest.NewRequest("GET", "/test-route", strings.NewReader("body")) 63 rawRequest.Header.Set("Referer", "https://www.google.com") 64 request := createTestRequest(rawRequest) 65 assert.Equal(t, "https://www.google.com", request.Referrer()) 66 } 67 68 func TestRequestUserAgent(t *testing.T) { 69 rawRequest := httptest.NewRequest("GET", "/test-route", strings.NewReader("body")) 70 rawRequest.Header.Set("User-Agent", "goyave/version") 71 request := createTestRequest(rawRequest) 72 assert.Equal(t, "goyave/version", request.UserAgent()) 73 } 74 75 func TestRequestCookies(t *testing.T) { 76 rawRequest := httptest.NewRequest("GET", "/test-route", strings.NewReader("body")) 77 rawRequest.AddCookie(&http.Cookie{ 78 Name: "cookie-name", 79 Value: "test", 80 }) 81 request := createTestRequest(rawRequest) 82 cookies := request.Cookies() 83 assert.Equal(t, 1, len(cookies)) 84 assert.Equal(t, "cookie-name", cookies[0].Name) 85 assert.Equal(t, "test", cookies[0].Value) 86 } 87 88 func TestRequestValidate(t *testing.T) { 89 rawRequest := httptest.NewRequest("POST", "/test-route", strings.NewReader("string=hello%20world&number=42")) 90 rawRequest.Header.Set("Content-Type", "application/json") 91 request := createTestRequest(rawRequest) 92 93 validation.AddRule("test_extra_request", &validation.RuleDefinition{ 94 Function: func(ctx *validation.Context) bool { 95 r, ok := ctx.Extra["request"].(*Request) 96 assert.True(t, ok) 97 assert.Equal(t, request, r) 98 return true 99 }, 100 }) 101 102 request.Data = map[string]interface{}{ 103 "string": "hello world", 104 "number": 42, 105 } 106 request.Rules = validation.RuleSet{ 107 "string": validation.List{"required", "string", "test_extra_request"}, 108 "number": validation.List{"required", "numeric", "min:10"}, 109 }.AsRules() 110 errors := request.validate() 111 assert.Nil(t, errors) 112 113 rawRequest = httptest.NewRequest("POST", "/test-route", strings.NewReader("string=hello%20world")) 114 rawRequest.Header.Set("Content-Type", "application/json") 115 request = createTestRequest(rawRequest) 116 request.Data = map[string]interface{}{ 117 "string": "hello world", 118 } 119 120 request.Rules = &validation.Rules{ 121 Fields: validation.FieldMap{ 122 "string": &validation.Field{ 123 Rules: []*validation.Rule{ 124 {Name: "required"}, 125 {Name: "string"}, 126 }, 127 }, 128 "number": &validation.Field{ 129 Rules: []*validation.Rule{ 130 {Name: "required"}, 131 {Name: "numeric"}, 132 {Name: "min", Params: []string{"50"}}, 133 }, 134 }, 135 }, 136 } 137 errors = request.validate() 138 assert.NotNil(t, errors) 139 assert.Equal(t, 2, len(errors["number"].Errors)) 140 141 rawRequest = httptest.NewRequest("POST", "/test-route", strings.NewReader("string=hello%20world&number=42")) 142 rawRequest.Header.Set("Content-Type", "application/json") 143 request = createTestRequest(rawRequest) 144 request.Rules = nil 145 errors = request.validate() 146 assert.Nil(t, errors) 147 } 148 149 func TestRequestAccessors(t *testing.T) { 150 loc, err := time.LoadLocation("America/New_York") 151 if err != nil { 152 panic(err) 153 } 154 155 uid, err := uuid.Parse("3bbcee75-cecc-5b56-8031-b6641c1ed1f1") 156 if err != nil { 157 panic(err) 158 } 159 160 date, err := time.Parse("2006-01-02", "2019-11-21") 161 if err != nil { 162 panic(err) 163 } 164 165 url, err := url.ParseRequestURI("https://google.com") 166 if err != nil { 167 panic(err) 168 } 169 170 rawRequest := httptest.NewRequest("POST", "/test-route", nil) 171 request := createTestRequest(rawRequest) 172 request.Data = map[string]interface{}{ 173 "string": "hello world", 174 "integer": 42, 175 "numeric": 42.3, 176 "bool": true, 177 "file": []fsutil.File{{MIMEType: "image/png"}}, 178 "timezone": loc, 179 "ip": net.ParseIP("127.0.0.1"), 180 "uuid": uid, 181 "date": date, 182 "url": url, 183 "object": map[string]interface{}{ 184 "hello": "world", 185 }, 186 } 187 188 assert.Equal(t, "hello world", request.String("string")) 189 assert.Equal(t, 42, request.Integer("integer")) 190 assert.Equal(t, 42.3, request.Numeric("numeric")) 191 assert.Equal(t, rawRequest, request.Request()) 192 assert.True(t, request.Bool("bool")) 193 194 files := request.File("file") 195 assert.Len(t, files, 1) 196 assert.Equal(t, "image/png", files[0].MIMEType) 197 198 assert.Equal(t, "America/New_York", request.Timezone("timezone").String()) 199 assert.Equal(t, "127.0.0.1", request.IP("ip").String()) 200 assert.Equal(t, "3bbcee75-cecc-5b56-8031-b6641c1ed1f1", request.UUID("uuid").String()) 201 assert.Equal(t, "2019-11-21 00:00:00 +0000 UTC", request.Date("date").String()) 202 assert.Equal(t, "https://google.com", request.URL("url").String()) 203 assert.Equal(t, request.Data["object"], request.Object("object")) 204 205 assert.Panics(t, func() { request.String("integer") }) 206 assert.Panics(t, func() { request.Integer("string") }) 207 assert.Panics(t, func() { request.Numeric("string") }) 208 assert.Panics(t, func() { request.Bool("string") }) 209 assert.Panics(t, func() { request.File("string") }) 210 assert.Panics(t, func() { request.Timezone("string") }) 211 assert.Panics(t, func() { request.IP("string") }) 212 assert.Panics(t, func() { request.UUID("string") }) 213 assert.Panics(t, func() { request.Date("string") }) 214 assert.Panics(t, func() { request.URL("string") }) 215 assert.Panics(t, func() { request.String("doesn't exist") }) 216 assert.Panics(t, func() { request.Object("doesn't exist") }) 217 } 218 219 func TestRequestHas(t *testing.T) { 220 request := createTestRequest(httptest.NewRequest("POST", "/test-route", nil)) 221 request.Data = map[string]interface{}{ 222 "string": "hello world", 223 } 224 225 assert.True(t, request.Has("string")) 226 assert.False(t, request.Has("not_in_request")) 227 } 228 229 func TestRequestCors(t *testing.T) { 230 request := createTestRequest(httptest.NewRequest("POST", "/test-route", nil)) 231 232 assert.Nil(t, request.CORSOptions()) 233 234 request.corsOptions = cors.Default() 235 options := request.CORSOptions() 236 assert.NotNil(t, options) 237 238 // Check cannot alter config 239 options.MaxAge = time.Second 240 assert.NotEqual(t, request.corsOptions.MaxAge, options.MaxAge) 241 } 242 243 func TestGetBearerToken(t *testing.T) { 244 request := createTestRequest(httptest.NewRequest("POST", "/test-route", nil)) 245 request.Header().Set("Authorization", "NotBearer 123456789") 246 token, ok := request.BearerToken() 247 assert.Empty(t, token) 248 assert.False(t, ok) 249 250 request.Header().Set("Authorization", "Bearer123456789") 251 token, ok = request.BearerToken() 252 assert.Empty(t, token) 253 assert.False(t, ok) 254 255 request.Header().Set("Authorization", "Bearer 123456789") 256 token, ok = request.BearerToken() 257 assert.Equal(t, "123456789", token) 258 assert.True(t, ok) 259 } 260 261 func TestToStruct(t *testing.T) { 262 type UserInsertRequest struct { 263 Username string 264 Email string 265 } 266 267 request := createTestRequest(httptest.NewRequest("POST", "/test-route", nil)) 268 request.Data = map[string]interface{}{ 269 "username": "johndoe", 270 "email": "johndoe@example.org", 271 } 272 273 userInsertRequest := UserInsertRequest{} 274 275 if err := request.ToStruct(&userInsertRequest); err != nil { 276 assert.FailNow(t, err.Error()) 277 } 278 279 assert.Equal(t, "johndoe", userInsertRequest.Username) 280 assert.Equal(t, "johndoe@example.org", userInsertRequest.Email) 281 }