1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package middleware
16
17 import (
18 "bytes"
19 "context"
20 "encoding/base64"
21 "encoding/json"
22 "io"
23 "mime/multipart"
24 "net/http"
25 "net/url"
26 "strings"
27 "testing"
28 "time"
29
30 "github.com/go-openapi/runtime"
31 "github.com/go-openapi/strfmt"
32 "github.com/stretchr/testify/assert"
33 "github.com/stretchr/testify/require"
34 )
35
36 func TestUntypedFormPost(t *testing.T) {
37 params := parametersForFormUpload()
38 binder := NewUntypedRequestBinder(params, nil, strfmt.Default)
39
40 req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, testURL, bytes.NewBufferString(`name=the-name&age=32`))
41 require.NoError(t, err)
42 req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
43
44 data := make(map[string]interface{})
45 require.NoError(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
46 assert.Equal(t, "the-name", data["name"])
47 assert.EqualValues(t, 32, data["age"])
48
49 req, err = http.NewRequestWithContext(context.Background(), http.MethodPost, testURL, bytes.NewBufferString(`name=%3&age=32`))
50 require.NoError(t, err)
51 req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
52
53 data = make(map[string]interface{})
54 require.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
55 }
56
57 func TestUntypedFileUpload(t *testing.T) {
58 binder := paramsForFileUpload()
59
60 body := bytes.NewBuffer(nil)
61 writer := multipart.NewWriter(body)
62 part, err := writer.CreateFormFile("file", "plain-jane.txt")
63 require.NoError(t, err)
64
65 _, err = part.Write([]byte("the file contents"))
66 require.NoError(t, err)
67 require.NoError(t, writer.WriteField("name", "the-name"))
68 require.NoError(t, writer.Close())
69
70 req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, testURL, body)
71 require.NoError(t, err)
72 req.Header.Set("Content-Type", writer.FormDataContentType())
73
74 data := make(map[string]interface{})
75 require.NoError(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
76 assert.Equal(t, "the-name", data["name"])
77 assert.NotNil(t, data["file"])
78 assert.IsType(t, runtime.File{}, data["file"])
79 file := data["file"].(runtime.File)
80 require.NotNil(t, file.Header)
81 assert.Equal(t, "plain-jane.txt", file.Header.Filename)
82
83 bb, err := io.ReadAll(file.Data)
84 require.NoError(t, err)
85 assert.Equal(t, []byte("the file contents"), bb)
86
87 req, err = http.NewRequestWithContext(context.Background(), http.MethodPost, testURL, body)
88 require.NoError(t, err)
89 req.Header.Set("Content-Type", "application/json")
90 data = make(map[string]interface{})
91 require.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
92
93 req, err = http.NewRequestWithContext(context.Background(), http.MethodPost, testURL, body)
94 require.NoError(t, err)
95 req.Header.Set("Content-Type", "application(")
96 data = make(map[string]interface{})
97 require.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
98
99 body = bytes.NewBuffer(nil)
100 writer = multipart.NewWriter(body)
101 part, err = writer.CreateFormFile("bad-name", "plain-jane.txt")
102 require.NoError(t, err)
103
104 _, err = part.Write([]byte("the file contents"))
105 require.NoError(t, err)
106 require.NoError(t, writer.WriteField("name", "the-name"))
107 require.NoError(t, writer.Close())
108 req, err = http.NewRequestWithContext(context.Background(), http.MethodPost, testURL, body)
109 require.NoError(t, err)
110 req.Header.Set("Content-Type", writer.FormDataContentType())
111
112 data = make(map[string]interface{})
113 require.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
114
115 req, err = http.NewRequestWithContext(context.Background(), http.MethodPost, testURL, body)
116 require.NoError(t, err)
117 req.Header.Set("Content-Type", writer.FormDataContentType())
118 _, err = req.MultipartReader()
119 require.NoError(t, err)
120
121 data = make(map[string]interface{})
122 require.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
123
124 writer = multipart.NewWriter(body)
125 require.NoError(t, writer.WriteField("name", "the-name"))
126 require.NoError(t, writer.Close())
127
128 req, err = http.NewRequestWithContext(context.Background(), http.MethodPost, testURL, body)
129 require.NoError(t, err)
130 req.Header.Set("Content-Type", writer.FormDataContentType())
131
132 data = make(map[string]interface{})
133 require.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
134 }
135
136 func TestUntypedOptionalFileUpload(t *testing.T) {
137 binder := paramsForOptionalFileUpload()
138
139 body := bytes.NewBuffer(nil)
140 writer := multipart.NewWriter(body)
141 require.NoError(t, writer.WriteField("name", "the-name"))
142 require.NoError(t, writer.Close())
143
144 req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, testURL, body)
145 require.NoError(t, err)
146 req.Header.Set("Content-Type", writer.FormDataContentType())
147
148 data := make(map[string]interface{})
149 require.NoError(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
150 assert.Equal(t, "the-name", data["name"])
151
152 writer = multipart.NewWriter(body)
153 part, err := writer.CreateFormFile("file", "plain-jane.txt")
154 require.NoError(t, err)
155 _, err = part.Write([]byte("the file contents"))
156 require.NoError(t, err)
157 require.NoError(t, writer.WriteField("name", "the-name"))
158 require.NoError(t, writer.Close())
159
160 req, err = http.NewRequestWithContext(context.Background(), http.MethodPost, testURL, body)
161 require.NoError(t, err)
162 req.Header.Set("Content-Type", writer.FormDataContentType())
163 require.NoError(t, writer.Close())
164
165 data = make(map[string]interface{})
166 require.NoError(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
167 assert.Equal(t, "the-name", data["name"])
168 assert.NotNil(t, data["file"])
169 assert.IsType(t, runtime.File{}, data["file"])
170 file := data["file"].(runtime.File)
171 assert.NotNil(t, file.Header)
172 assert.Equal(t, "plain-jane.txt", file.Header.Filename)
173
174 }
175
176 func TestUntypedBindingTypesForValid(t *testing.T) {
177 op2 := parametersForAllTypes("")
178 binder := NewUntypedRequestBinder(op2, nil, strfmt.Default)
179
180 confirmed := true
181 name := "thomas"
182 friend := map[string]interface{}{"name": "toby", "age": json.Number("32")}
183 id, age, score, factor := int64(7575), int32(348), float32(5.309), float64(37.403)
184 requestID := 19394858
185 tags := []string{"one", "two", "three"}
186 dt1 := time.Date(2014, 8, 9, 0, 0, 0, 0, time.UTC)
187 planned := strfmt.Date(dt1)
188 dt2 := time.Date(2014, 10, 12, 8, 5, 5, 0, time.UTC)
189 delivered := strfmt.DateTime(dt2)
190 picture := base64.URLEncoding.EncodeToString([]byte("hello"))
191 uri, err := url.Parse("http://localhost:8002/hello/7575")
192 require.NoError(t, err)
193 qs := uri.Query()
194 qs.Add("name", name)
195 qs.Add("confirmed", "true")
196 qs.Add("age", "348")
197 qs.Add("score", "5.309")
198 qs.Add("factor", "37.403")
199 qs.Add("tags", strings.Join(tags, ","))
200 qs.Add("planned", planned.String())
201 qs.Add("delivered", delivered.String())
202 qs.Add("picture", picture)
203
204 req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, uri.String()+"?"+qs.Encode(), bytes.NewBufferString(`{"name":"toby","age":32}`))
205 require.NoError(t, err)
206 req.Header.Set("Content-Type", "application/json")
207 req.Header.Set("X-Request-Id", "19394858")
208
209 data := make(map[string]interface{})
210 err = binder.Bind(req, RouteParams([]RouteParam{{"id", "7575"}}), runtime.JSONConsumer(), &data)
211 require.NoError(t, err)
212 assert.Equal(t, id, data["id"])
213 assert.Equal(t, name, data["name"])
214 assert.Equal(t, friend, data["friend"])
215 assert.EqualValues(t, requestID, data["X-Request-Id"])
216 assert.Equal(t, tags, data["tags"])
217 assert.Equal(t, planned, data["planned"])
218 assert.Equal(t, delivered, data["delivered"])
219 assert.Equal(t, confirmed, data["confirmed"])
220 assert.Equal(t, age, data["age"])
221 assert.InDelta(t, factor, data["factor"], 1e-6)
222 assert.InDelta(t, score, data["score"], 1e-6)
223 pb, err := base64.URLEncoding.DecodeString(picture)
224 require.NoError(t, err)
225 assert.EqualValues(t, pb, data["picture"].(strfmt.Base64))
226 }
227
View as plain text