@@ -5,10 +5,14 @@ import (
5
5
"fmt"
6
6
"io"
7
7
"io/ioutil"
8
+ "mime"
8
9
"mime/multipart"
9
10
"net/http"
10
11
"net/http/cookiejar"
12
+ "net/textproto"
11
13
"net/url"
14
+ "os"
15
+ "path/filepath"
12
16
"regexp"
13
17
"strings"
14
18
@@ -62,8 +66,8 @@ func (t *TestSuite) WebSocketUrl() string {
62
66
return "ws://" + t .Host ()
63
67
}
64
68
65
- // Issue a GET request to the given path and store the result in Request and
66
- // RequestBody .
69
+ // Issue a GET request to the given path and store the result in Response and
70
+ // ResponseBody .
67
71
func (t * TestSuite ) Get (path string ) {
68
72
t .GetCustom (t .BaseUrl () + path ).Send ()
69
73
}
@@ -80,8 +84,8 @@ func (t *TestSuite) GetCustom(uri string) *TestRequest {
80
84
}
81
85
}
82
86
83
- // Issue a DELETE request to the given path and store the result in Request and
84
- // RequestBody .
87
+ // Issue a DELETE request to the given path and store the result in Response and
88
+ // ResponseBody .
85
89
func (t * TestSuite ) Delete (path string ) {
86
90
t .DeleteCustom (t .BaseUrl () + path ).Send ()
87
91
}
@@ -99,7 +103,7 @@ func (t *TestSuite) DeleteCustom(uri string) *TestRequest {
99
103
}
100
104
101
105
// Issue a POST request to the given path, sending the given Content-Type and
102
- // data, and store the result in Request and RequestBody . "data" may be nil.
106
+ // data, and store the result in Response and ResponseBody . "data" may be nil.
103
107
func (t * TestSuite ) Post (path string , contentType string , reader io.Reader ) {
104
108
t .PostCustom (t .BaseUrl ()+ path , contentType , reader ).Send ()
105
109
}
@@ -119,7 +123,7 @@ func (t *TestSuite) PostCustom(uri string, contentType string, reader io.Reader)
119
123
}
120
124
121
125
// Issue a POST request to the given path as a form post of the given key and
122
- // values, and store the result in Request and RequestBody .
126
+ // values, and store the result in Response and ResponseBody .
123
127
func (t * TestSuite ) PostForm (path string , data url.Values ) {
124
128
t .PostFormCustom (t .BaseUrl ()+ path , data ).Send ()
125
129
}
@@ -130,23 +134,34 @@ func (t *TestSuite) PostFormCustom(uri string, data url.Values) *TestRequest {
130
134
return t .PostCustom (uri , "application/x-www-form-urlencoded" , strings .NewReader (data .Encode ()))
131
135
}
132
136
133
- // Issue a multipart request for the method & fields given and read the response.
134
- // If successful, the caller may examine the Response and ResponseBody properties.
135
- func (t * TestSuite ) MakeMultipartRequest (method string , path string , fields map [string ]string ) {
136
- var b bytes.Buffer
137
- w := multipart .NewWriter (& b )
137
+ // Issue a multipart request to the given path sending given params and files,
138
+ // and store the result in Response and ResponseBody.
139
+ func (t * TestSuite ) PostFile (path string , params url.Values , filePaths url.Values ) {
140
+ t .PostFileCustom (t .BaseUrl ()+ path , params , filePaths ).Send ()
141
+ }
142
+
143
+ // Return a multipart request to the given uri in a form of its wrapper
144
+ // with the given params and files.
145
+ func (t * TestSuite ) PostFileCustom (uri string , params url.Values , filePaths url.Values ) * TestRequest {
146
+ body := & bytes.Buffer {}
147
+ writer := multipart .NewWriter (body )
138
148
139
- for key , value := range fields {
140
- w .WriteField (key , value )
149
+ for key , values := range filePaths {
150
+ for _ , value := range values {
151
+ createFormFile (writer , key , value )
152
+ }
141
153
}
142
- w .Close () //adds the terminating boundary
143
154
144
- req , err := http .NewRequest (method , t .BaseUrl ()+ path , & b )
145
- if err != nil {
146
- panic (err )
155
+ for key , values := range params {
156
+ for _ , value := range values {
157
+ err := writer .WriteField (key , value )
158
+ t .AssertEqual (nil , err )
159
+ }
147
160
}
148
- req .Header .Set ("Content-Type" , w .FormDataContentType ())
161
+ err := writer .Close ()
162
+ t .AssertEqual (nil , err )
149
163
164
+ return t .PostCustom (uri , writer .FormDataContentType (), body )
150
165
}
151
166
152
167
// Issue any request and read the response. If successful, the caller may
@@ -251,11 +266,51 @@ func (t *TestSuite) AssertNotContains(s string) {
251
266
}
252
267
}
253
268
254
- // Assert that the response matches the given regular expression.BUG
269
+ // Assert that the response matches the given regular expression.
255
270
func (t * TestSuite ) AssertContainsRegex (regex string ) {
256
271
r := regexp .MustCompile (regex )
257
272
258
273
if ! r .Match (t .ResponseBody ) {
259
274
panic (fmt .Errorf ("Assertion failed. Expected response to match regexp %s" , regex ))
260
275
}
261
276
}
277
+
278
+ func createFormFile (writer * multipart.Writer , fieldname , filename string ) {
279
+ // Try to open the file.
280
+ file , err := os .Open (filename )
281
+ if err != nil {
282
+ panic (err )
283
+ }
284
+ defer file .Close ()
285
+
286
+ // Create a new form-data header with the provided field name and file name.
287
+ // Determine Content-Type of the file by its extension.
288
+ h := textproto.MIMEHeader {}
289
+ h .Set ("Content-Disposition" , fmt .Sprintf (
290
+ `form-data; name="%s"; filename="%s"` ,
291
+ escapeQuotes (fieldname ),
292
+ escapeQuotes (filepath .Base (filename )),
293
+ ))
294
+ h .Set ("Content-Type" , "application/octet-stream" )
295
+ if ct := mime .TypeByExtension (filepath .Ext (filename )); ct != "" {
296
+ h .Set ("Content-Type" , ct )
297
+ }
298
+ part , err := writer .CreatePart (h )
299
+ if err != nil {
300
+ panic (err )
301
+ }
302
+
303
+ // Copy the content of the file we have opened not reading the whole
304
+ // file into memory.
305
+ _ , err = io .Copy (part , file )
306
+ if err != nil {
307
+ panic (err )
308
+ }
309
+ }
310
+
311
+ var quoteEscaper = strings .NewReplacer ("\\ " , "\\ \\ " , `"` , "\\ \" " )
312
+
313
+ // This function was borrowed from mime/multipart package.
314
+ func escapeQuotes (s string ) string {
315
+ return quoteEscaper .Replace (s )
316
+ }
0 commit comments