Skip to content

Commit

Permalink
Merge pull request #44 from danielgtaylor/query-params
Browse files Browse the repository at this point in the history
Huma now accepts naked boolean queryparams
  • Loading branch information
deo986 authored Apr 22, 2022
2 parents 49db25b + 2a2fc53 commit c194251
Show file tree
Hide file tree
Showing 2 changed files with 189 additions and 0 deletions.
3 changes: 3 additions & 0 deletions resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,9 @@ func setFields(ctx *hcontext, req *http.Request, input reflect.Value, t reflect.
location = locationQuery
if v := req.URL.Query().Get(name); v != "" {
pv = v
} else if req.URL.Query().Has(name) && f.Type.Kind() == reflect.Bool {
// name has no associated value, but exists in the map of QueryParams. This is a boolean value
pv = "true"
}
}

Expand Down
186 changes: 186 additions & 0 deletions resolver_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package huma

import (
"encoding/json"
"net/http"
"net/http/httptest"
"strings"
Expand Down Expand Up @@ -141,3 +142,188 @@ func TestInvalidJSON(t *testing.T) {

assert.Equal(t, http.StatusBadRequest, w.Result().StatusCode)
}

type QueryParamTestModel struct {
BooleanParam bool `query:"b"`
OtherParam string `query:"s"`
}

func TestBooleanQueryParamNoVal(t *testing.T) {
app := newTestRouter()

app.Resource("/").Get("test", "Test",
NewResponse(http.StatusOK, "desc"),
).Run(func(ctx Context, input QueryParamTestModel) {
out := &QueryParamTestModel{
BooleanParam: input.BooleanParam,
OtherParam: input.OtherParam,
}
j, err := json.Marshal(out)
if err == nil {
ctx.Write(j)
} else {
ctx.WriteError(http.StatusBadRequest, "error marshaling to json", err)
}

})

w := httptest.NewRecorder()
r, _ := http.NewRequest(http.MethodGet, "/?s=test&b", nil)
app.ServeHTTP(w, r)

assert.Equal(t, http.StatusOK, w.Result().StatusCode)
decoder := json.NewDecoder(w.Body)
var o QueryParamTestModel

err := decoder.Decode(&o)
if err != nil {
assert.Fail(t, "Unable to decode json response")
}

assert.Equal(t, o.BooleanParam, true)
assert.Equal(t, o.OtherParam, "test")
}

func TestBooleanQueryParamTrailingEqual(t *testing.T) {
app := newTestRouter()

app.Resource("/").Get("test", "Test",
NewResponse(http.StatusOK, "desc"),
).Run(func(ctx Context, input QueryParamTestModel) {
out := &QueryParamTestModel{
BooleanParam: input.BooleanParam,
OtherParam: input.OtherParam,
}
j, err := json.Marshal(out)
if err == nil {
ctx.Write(j)
} else {
ctx.WriteError(http.StatusBadRequest, "error marshaling to json", err)
}

})

w := httptest.NewRecorder()
r, _ := http.NewRequest(http.MethodGet, "/?s=test&b=", nil)
app.ServeHTTP(w, r)

assert.Equal(t, http.StatusOK, w.Result().StatusCode)
decoder := json.NewDecoder(w.Body)
var o QueryParamTestModel

err := decoder.Decode(&o)
if err != nil {
assert.Fail(t, "Unable to decode json response")
}

assert.Equal(t, o.BooleanParam, true)
assert.Equal(t, o.OtherParam, "test")
}

func TestBooleanQueryParamExplicitSet(t *testing.T) {
app := newTestRouter()

app.Resource("/").Get("test", "Test",
NewResponse(http.StatusOK, "desc"),
).Run(func(ctx Context, input QueryParamTestModel) {
out := &QueryParamTestModel{
BooleanParam: input.BooleanParam,
OtherParam: input.OtherParam,
}
j, err := json.Marshal(out)
if err == nil {
ctx.Write(j)
} else {
ctx.WriteError(http.StatusBadRequest, "error marshaling to json", err)
}

})

w := httptest.NewRecorder()
r, _ := http.NewRequest(http.MethodGet, "/?s=test&b=true", nil)
app.ServeHTTP(w, r)

assert.Equal(t, http.StatusOK, w.Result().StatusCode)
decoder := json.NewDecoder(w.Body)
var o QueryParamTestModel

err := decoder.Decode(&o)
if err != nil {
assert.Fail(t, "Unable to decode json response")
}

assert.Equal(t, o.BooleanParam, true)
assert.Equal(t, o.OtherParam, "test")
}

func TestBooleanQueryParamNotSet(t *testing.T) {
app := newTestRouter()

app.Resource("/").Get("test", "Test",
NewResponse(http.StatusOK, "desc"),
).Run(func(ctx Context, input QueryParamTestModel) {
out := &QueryParamTestModel{
BooleanParam: input.BooleanParam,
OtherParam: input.OtherParam,
}
j, err := json.Marshal(out)
if err == nil {
ctx.Write(j)
} else {
ctx.WriteError(http.StatusBadRequest, "error marshaling to json", err)
}

})

w := httptest.NewRecorder()
r, _ := http.NewRequest(http.MethodGet, "/?s=test", nil)
app.ServeHTTP(w, r)

assert.Equal(t, http.StatusOK, w.Result().StatusCode)
decoder := json.NewDecoder(w.Body)
var o QueryParamTestModel

err := decoder.Decode(&o)
if err != nil {
assert.Fail(t, "Unable to decode json response")
}

assert.Equal(t, o.BooleanParam, false)
assert.Equal(t, o.OtherParam, "test")
}

func TestStringQueryEmpty(t *testing.T) {
app := newTestRouter()

app.Resource("/").Get("test", "Test",
NewResponse(http.StatusOK, "desc"),
).Run(func(ctx Context, input QueryParamTestModel) {
out := &QueryParamTestModel{
BooleanParam: input.BooleanParam,
OtherParam: input.OtherParam,
}
j, err := json.Marshal(out)
if err == nil {
ctx.Write(j)
} else {
ctx.WriteError(http.StatusBadRequest, "error marshaling to json", err)
}

})

w := httptest.NewRecorder()
r, _ := http.NewRequest(http.MethodGet, "/?s=&b", nil)
app.ServeHTTP(w, r)

assert.Equal(t, http.StatusOK, w.Result().StatusCode)
decoder := json.NewDecoder(w.Body)
var o QueryParamTestModel

err := decoder.Decode(&o)
if err != nil {
assert.Fail(t, "Unable to decode json response")
}

assert.Equal(t, o.BooleanParam, true)
assert.Equal(t, o.OtherParam, "")
}

0 comments on commit c194251

Please sign in to comment.