Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1ade009

Browse files
committed
feat(coderd/httpapi): add QueryParamParser.JSONStringMap
1 parent a69961b commit 1ade009

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

coderd/httpapi/queryparams.go

+18
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package httpapi
22

33
import (
44
"database/sql"
5+
"encoding/json"
56
"errors"
67
"fmt"
78
"net/url"
@@ -257,6 +258,23 @@ func (p *QueryParamParser) Strings(vals url.Values, def []string, queryParam str
257258
})
258259
}
259260

261+
func (p *QueryParamParser) JSONStringMap(vals url.Values, def map[string]string, queryParam string) map[string]string {
262+
v, err := parseQueryParam(p, vals, func(v string) (map[string]string, error) {
263+
var m map[string]string
264+
if err := json.NewDecoder(strings.NewReader(v)).Decode(&m); err != nil {
265+
return nil, err
266+
}
267+
return m, nil
268+
}, def, queryParam)
269+
if err != nil {
270+
p.Errors = append(p.Errors, codersdk.ValidationError{
271+
Field: queryParam,
272+
Detail: fmt.Sprintf("Query param %q must be a valid JSON object: %s", queryParam, err.Error()),
273+
})
274+
}
275+
return v
276+
}
277+
260278
// ValidEnum represents an enum that can be parsed and validated.
261279
type ValidEnum interface {
262280
// Add more types as needed (avoid importing large dependency trees).

coderd/httpapi/queryparams_test.go

+64
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,70 @@ func TestParseQueryParams(t *testing.T) {
473473
testQueryParams(t, expParams, parser, parser.UUIDs)
474474
})
475475

476+
t.Run("JSONStringMap", func(t *testing.T) {
477+
t.Parallel()
478+
479+
expParams := []queryParamTestCase[map[string]string]{
480+
{
481+
QueryParam: "valid_map",
482+
Value: `{"key1": "value1", "key2": "value2"}`,
483+
Expected: map[string]string{
484+
"key1": "value1",
485+
"key2": "value2",
486+
},
487+
},
488+
{
489+
QueryParam: "empty",
490+
Value: "{}",
491+
Default: map[string]string{},
492+
Expected: map[string]string{},
493+
},
494+
{
495+
QueryParam: "no_value",
496+
NoSet: true,
497+
Default: map[string]string{},
498+
Expected: map[string]string{},
499+
},
500+
{
501+
QueryParam: "default",
502+
NoSet: true,
503+
Default: map[string]string{"key": "value"},
504+
Expected: map[string]string{"key": "value"},
505+
},
506+
{
507+
QueryParam: "null",
508+
Value: "null",
509+
Expected: map[string]string(nil),
510+
},
511+
{
512+
QueryParam: "undefined",
513+
Value: "undefined",
514+
Expected: map[string]string(nil),
515+
},
516+
{
517+
QueryParam: "invalid_map",
518+
Value: `{"key1": "value1", "key2": "value2"`, // missing closing brace
519+
Expected: map[string]string(nil),
520+
Default: map[string]string{},
521+
ExpectedErrorContains: `Query param "invalid_map" must be a valid JSON object: unexpected EOF`,
522+
},
523+
{
524+
QueryParam: "incorrect_type",
525+
Value: `{"key1": 1, "key2": true}`,
526+
Expected: map[string]string(nil),
527+
ExpectedErrorContains: `Query param "incorrect_type" must be a valid JSON object: json: cannot unmarshal number into Go value of type string`,
528+
},
529+
{
530+
QueryParam: "multiple_keys",
531+
Values: []string{`{"key1": "value1"}`, `{"key2": "value2"}`},
532+
Expected: map[string]string(nil),
533+
ExpectedErrorContains: `Query param "multiple_keys" provided more than once, found 2 times.`,
534+
},
535+
}
536+
parser := httpapi.NewQueryParamParser()
537+
testQueryParams(t, expParams, parser, parser.JSONStringMap)
538+
})
539+
476540
t.Run("Required", func(t *testing.T) {
477541
t.Parallel()
478542

0 commit comments

Comments
 (0)