forked from pocketbase/pocketbase
-
Notifications
You must be signed in to change notification settings - Fork 0
/
multi_binder_test.go
149 lines (126 loc) · 3.55 KB
/
multi_binder_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package rest_test
import (
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"github.com/labstack/echo/v5"
"github.com/pocketbase/pocketbase/tools/rest"
)
func TestMultiBinderBind(t *testing.T) {
binder := rest.MultiBinder{}
req := httptest.NewRequest(http.MethodGet, "/test?query=123", strings.NewReader(`{"body":"456"}`))
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
rec := httptest.NewRecorder()
e := echo.New()
e.Any("/:name", func(c echo.Context) error {
// bind twice to ensure that the json body reader copy is invoked
for i := 0; i < 2; i++ {
data := struct {
Name string `param:"name"`
Query string `query:"query"`
Body string `form:"body"`
}{}
if err := binder.Bind(c, &data); err != nil {
t.Fatal(err)
}
if data.Name != "test" {
t.Fatalf("Expected Name %q, got %q", "test", data.Name)
}
if data.Query != "123" {
t.Fatalf("Expected Query %q, got %q", "123", data.Query)
}
if data.Body != "456" {
t.Fatalf("Expected Body %q, got %q", "456", data.Body)
}
}
return nil
})
e.ServeHTTP(rec, req)
}
func TestBindBody(t *testing.T) {
scenarios := []struct {
body io.Reader
contentType string
expectBody string
expectError bool
}{
{
strings.NewReader(""),
echo.MIMEApplicationJSON,
`{}`,
false,
},
{
strings.NewReader(`{"test":"invalid`),
echo.MIMEApplicationJSON,
`{}`,
true,
},
{
strings.NewReader(`{"test":123}`),
echo.MIMEApplicationJSON,
`{"test":123}`,
false,
},
{
strings.NewReader(
url.Values{
"string": []string{"str"},
"stings": []string{"str1", "str2", ""},
"number": []string{"-123"},
"numbers": []string{"123", "456.789"},
"bool": []string{"true"},
"bools": []string{"true", "false"},
rest.MultipartJsonKey: []string{`invalid`, `{"a":123}`, `{"b":456}`},
}.Encode(),
),
echo.MIMEApplicationForm,
`{"a":123,"b":456,"bool":true,"bools":[true,false],"number":-123,"numbers":[123,456.789],"stings":["str1","str2",""],"string":"str"}`,
false,
},
}
for i, scenario := range scenarios {
e := echo.New()
req := httptest.NewRequest(http.MethodPost, "/", scenario.body)
req.Header.Set(echo.HeaderContentType, scenario.contentType)
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)
data := map[string]any{}
err := rest.BindBody(c, &data)
hasErr := err != nil
if hasErr != scenario.expectError {
t.Errorf("[%d] Expected hasErr %v, got %v", i, scenario.expectError, hasErr)
}
rawBody, err := json.Marshal(data)
if err != nil {
t.Errorf("[%d] Failed to marshal binded body: %v", i, err)
}
if scenario.expectBody != string(rawBody) {
t.Errorf("[%d] Expected body \n%s, \ngot \n%s", i, scenario.expectBody, rawBody)
}
}
}
func TestCopyJsonBody(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/", strings.NewReader(`{"test":"test123"}`))
// simulate multiple reads from the same request
result1 := map[string]string{}
rest.CopyJsonBody(req, &result1)
result2 := map[string]string{}
rest.CopyJsonBody(req, &result2)
if len(result1) == 0 {
t.Error("Expected result1 to be filled")
}
if len(result2) == 0 {
t.Error("Expected result2 to be filled")
}
if v, ok := result1["test"]; !ok || v != "test123" {
t.Errorf("Expected result1.test to be %q, got %q", "test123", v)
}
if v, ok := result2["test"]; !ok || v != "test123" {
t.Errorf("Expected result2.test to be %q, got %q", "test123", v)
}
}