1// Copyright (c) 2015-2019 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
2// resty source code and usage is governed by a MIT style
3// license that can be found in the LICENSE file.
4
5package resty
6
7import (
8	"bytes"
9	"crypto/tls"
10	"io"
11	"io/ioutil"
12	"net"
13	"net/http"
14	"net/url"
15	"os"
16	"path/filepath"
17	"strconv"
18	"strings"
19	"testing"
20	"time"
21)
22
23type AuthSuccess struct {
24	ID, Message string
25}
26
27type AuthError struct {
28	ID, Message string
29}
30
31func TestGet(t *testing.T) {
32	ts := createGetServer(t)
33	defer ts.Close()
34
35	resp, err := R().
36		SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
37		Get(ts.URL + "/")
38
39	assertError(t, err)
40	assertEqual(t, http.StatusOK, resp.StatusCode())
41	assertEqual(t, "200 OK", resp.Status())
42	assertNotNil(t, resp.Body())
43	assertEqual(t, "TestGet: text response", resp.String())
44
45	logResponse(t, resp)
46}
47
48func TestGetCustomUserAgent(t *testing.T) {
49	ts := createGetServer(t)
50	defer ts.Close()
51
52	resp, err := dcr().
53		SetHeader(hdrUserAgentKey, "Test Custom User agent").
54		SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
55		Get(ts.URL + "/")
56
57	assertError(t, err)
58	assertEqual(t, http.StatusOK, resp.StatusCode())
59	assertEqual(t, "200 OK", resp.Status())
60	assertEqual(t, "TestGet: text response", resp.String())
61
62	logResponse(t, resp)
63}
64
65func TestGetClientParamRequestParam(t *testing.T) {
66	ts := createGetServer(t)
67	defer ts.Close()
68
69	c := dc()
70	c.SetQueryParam("client_param", "true").
71		SetQueryParams(map[string]string{"req_1": "jeeva", "req_3": "jeeva3"}).
72		SetDebug(true).
73		SetLogger(ioutil.Discard)
74
75	resp, err := c.R().
76		SetQueryParams(map[string]string{"req_1": "req 1 value", "req_2": "req 2 value"}).
77		SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
78		SetHeader(hdrUserAgentKey, "Test Custom User agent").
79		Get(ts.URL + "/")
80
81	assertError(t, err)
82	assertEqual(t, http.StatusOK, resp.StatusCode())
83	assertEqual(t, "200 OK", resp.Status())
84	assertEqual(t, "TestGet: text response", resp.String())
85
86	logResponse(t, resp)
87}
88
89func TestGetRelativePath(t *testing.T) {
90	ts := createGetServer(t)
91	defer ts.Close()
92
93	c := dc()
94	c.SetHostURL(ts.URL)
95
96	resp, err := c.R().Get("mypage2")
97
98	assertError(t, err)
99	assertEqual(t, http.StatusOK, resp.StatusCode())
100	assertEqual(t, "TestGet: text response from mypage2", resp.String())
101
102	logResponse(t, resp)
103}
104
105func TestGet400Error(t *testing.T) {
106	ts := createGetServer(t)
107	defer ts.Close()
108
109	resp, err := dcr().Get(ts.URL + "/mypage")
110
111	assertError(t, err)
112	assertEqual(t, http.StatusBadRequest, resp.StatusCode())
113	assertEqual(t, "", resp.String())
114
115	logResponse(t, resp)
116}
117
118func TestPostJSONStringSuccess(t *testing.T) {
119	ts := createPostServer(t)
120	defer ts.Close()
121
122	c := dc()
123	c.SetHeader(hdrContentTypeKey, jsonContentType).
124		SetHeaders(map[string]string{hdrUserAgentKey: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) go-resty v0.1", hdrAcceptKey: jsonContentType})
125
126	resp, err := c.R().
127		SetBody(`{"username":"testuser", "password":"testpass"}`).
128		Post(ts.URL + "/login")
129
130	assertError(t, err)
131	assertEqual(t, http.StatusOK, resp.StatusCode())
132
133	logResponse(t, resp)
134
135	// PostJSONStringError
136	resp, err = c.R().
137		SetBody(`{"username":"testuser" "password":"testpass"}`).
138		Post(ts.URL + "/login")
139
140	assertError(t, err)
141	assertEqual(t, http.StatusBadRequest, resp.StatusCode())
142
143	logResponse(t, resp)
144}
145
146func TestPostJSONBytesSuccess(t *testing.T) {
147	ts := createPostServer(t)
148	defer ts.Close()
149
150	c := dc()
151	c.SetHeader(hdrContentTypeKey, jsonContentType).
152		SetHeaders(map[string]string{hdrUserAgentKey: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) go-resty v0.7", hdrAcceptKey: jsonContentType})
153
154	resp, err := c.R().
155		SetBody([]byte(`{"username":"testuser", "password":"testpass"}`)).
156		Post(ts.URL + "/login")
157
158	assertError(t, err)
159	assertEqual(t, http.StatusOK, resp.StatusCode())
160
161	logResponse(t, resp)
162}
163
164func TestPostJSONBytesIoReader(t *testing.T) {
165	ts := createPostServer(t)
166	defer ts.Close()
167
168	c := dc()
169	c.SetHeader(hdrContentTypeKey, jsonContentType)
170
171	bodyBytes := []byte(`{"username":"testuser", "password":"testpass"}`)
172
173	resp, err := c.R().
174		SetBody(bytes.NewReader(bodyBytes)).
175		Post(ts.URL + "/login")
176
177	assertError(t, err)
178	assertEqual(t, http.StatusOK, resp.StatusCode())
179
180	logResponse(t, resp)
181}
182
183func TestPostJSONStructSuccess(t *testing.T) {
184	ts := createPostServer(t)
185	defer ts.Close()
186
187	user := &User{Username: "testuser", Password: "testpass"}
188
189	c := dc().SetJSONEscapeHTML(false)
190	resp, err := c.R().
191		SetHeader(hdrContentTypeKey, jsonContentType).
192		SetBody(user).
193		SetResult(&AuthSuccess{}).
194		Post(ts.URL + "/login")
195
196	assertError(t, err)
197	assertEqual(t, http.StatusOK, resp.StatusCode())
198
199	t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
200
201	logResponse(t, resp)
202}
203
204func TestPostJSONRPCStructSuccess(t *testing.T) {
205	ts := createPostServer(t)
206	defer ts.Close()
207
208	user := &User{Username: "testuser", Password: "testpass"}
209
210	c := dc().SetJSONEscapeHTML(false)
211	resp, err := c.R().
212		SetHeader(hdrContentTypeKey, "application/json-rpc").
213		SetBody(user).
214		SetResult(&AuthSuccess{}).
215		SetQueryParam("ct", "rpc").
216		Post(ts.URL + "/login")
217
218	assertError(t, err)
219	assertEqual(t, http.StatusOK, resp.StatusCode())
220
221	t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
222
223	logResponse(t, resp)
224}
225
226func TestPostJSONStructInvalidLogin(t *testing.T) {
227	ts := createPostServer(t)
228	defer ts.Close()
229
230	c := dc()
231	c.SetDebug(false)
232
233	resp, err := c.R().
234		SetHeader(hdrContentTypeKey, jsonContentType).
235		SetBody(User{Username: "testuser", Password: "testpass1"}).
236		SetError(AuthError{}).
237		SetJSONEscapeHTML(false).
238		Post(ts.URL + "/login")
239
240	assertError(t, err)
241	assertEqual(t, http.StatusUnauthorized, resp.StatusCode())
242
243	authError := resp.Error().(*AuthError)
244	assertEqual(t, "unauthorized", authError.ID)
245	assertEqual(t, "Invalid credentials", authError.Message)
246	t.Logf("Result Error: %q", resp.Error().(*AuthError))
247
248	logResponse(t, resp)
249}
250
251func TestPostJSONErrorRFC7807(t *testing.T) {
252	ts := createPostServer(t)
253	defer ts.Close()
254
255	c := dc()
256	resp, err := c.R().
257		SetHeader(hdrContentTypeKey, jsonContentType).
258		SetBody(User{Username: "testuser", Password: "testpass1"}).
259		SetError(AuthError{}).
260		Post(ts.URL + "/login?ct=problem")
261
262	assertError(t, err)
263	assertEqual(t, http.StatusUnauthorized, resp.StatusCode())
264
265	authError := resp.Error().(*AuthError)
266	assertEqual(t, "unauthorized", authError.ID)
267	assertEqual(t, "Invalid credentials", authError.Message)
268	t.Logf("Result Error: %q", resp.Error().(*AuthError))
269
270	logResponse(t, resp)
271}
272
273func TestPostJSONMapSuccess(t *testing.T) {
274	ts := createPostServer(t)
275	defer ts.Close()
276
277	c := dc()
278	c.SetDebug(false)
279
280	resp, err := c.R().
281		SetBody(map[string]interface{}{"username": "testuser", "password": "testpass"}).
282		SetResult(AuthSuccess{}).
283		Post(ts.URL + "/login")
284
285	assertError(t, err)
286	assertEqual(t, http.StatusOK, resp.StatusCode())
287
288	t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
289
290	logResponse(t, resp)
291}
292
293func TestPostJSONMapInvalidResponseJson(t *testing.T) {
294	ts := createPostServer(t)
295	defer ts.Close()
296
297	resp, err := dclr().
298		SetBody(map[string]interface{}{"username": "testuser", "password": "invalidjson"}).
299		SetResult(&AuthSuccess{}).
300		Post(ts.URL + "/login")
301
302	assertEqual(t, "invalid character '}' looking for beginning of object key string", err.Error())
303	assertEqual(t, http.StatusOK, resp.StatusCode())
304
305	authSuccess := resp.Result().(*AuthSuccess)
306	assertEqual(t, "", authSuccess.ID)
307	assertEqual(t, "", authSuccess.Message)
308
309	t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
310
311	logResponse(t, resp)
312}
313
314func TestPostXMLStringSuccess(t *testing.T) {
315	ts := createPostServer(t)
316	defer ts.Close()
317
318	c := dc()
319	c.SetDebug(false)
320
321	resp, err := c.R().
322		SetHeader(hdrContentTypeKey, "application/xml").
323		SetBody(`<?xml version="1.0" encoding="UTF-8"?><User><Username>testuser</Username><Password>testpass</Password></User>`).
324		SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
325		Post(ts.URL + "/login")
326
327	assertError(t, err)
328	assertEqual(t, http.StatusOK, resp.StatusCode())
329
330	logResponse(t, resp)
331}
332
333func TestPostXMLStringError(t *testing.T) {
334	ts := createPostServer(t)
335	defer ts.Close()
336
337	resp, err := dclr().
338		SetHeader(hdrContentTypeKey, "application/xml").
339		SetBody(`<?xml version="1.0" encoding="UTF-8"?><User><Username>testuser</Username>testpass</Password></User>`).
340		Post(ts.URL + "/login")
341
342	assertError(t, err)
343	assertEqual(t, http.StatusBadRequest, resp.StatusCode())
344	assertEqual(t, `<?xml version="1.0" encoding="UTF-8"?><AuthError><Id>bad_request</Id><Message>Unable to read user info</Message></AuthError>`, resp.String())
345
346	logResponse(t, resp)
347}
348
349func TestPostXMLBytesSuccess(t *testing.T) {
350	ts := createPostServer(t)
351	defer ts.Close()
352
353	c := dc()
354	c.SetDebug(false)
355
356	resp, err := c.R().
357		SetHeader(hdrContentTypeKey, "application/xml").
358		SetBody([]byte(`<?xml version="1.0" encoding="UTF-8"?><User><Username>testuser</Username><Password>testpass</Password></User>`)).
359		SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
360		SetContentLength(true).
361		Post(ts.URL + "/login")
362
363	assertError(t, err)
364	assertEqual(t, http.StatusOK, resp.StatusCode())
365
366	logResponse(t, resp)
367}
368
369func TestPostXMLStructSuccess(t *testing.T) {
370	ts := createPostServer(t)
371	defer ts.Close()
372
373	resp, err := dclr().
374		SetHeader(hdrContentTypeKey, "application/xml").
375		SetBody(User{Username: "testuser", Password: "testpass"}).
376		SetContentLength(true).
377		SetResult(&AuthSuccess{}).
378		Post(ts.URL + "/login")
379
380	assertError(t, err)
381	assertEqual(t, http.StatusOK, resp.StatusCode())
382
383	t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
384
385	logResponse(t, resp)
386}
387
388func TestPostXMLStructInvalidLogin(t *testing.T) {
389	ts := createPostServer(t)
390	defer ts.Close()
391
392	c := dc()
393	c.SetError(&AuthError{})
394
395	resp, err := c.R().
396		SetHeader(hdrContentTypeKey, "application/xml").
397		SetBody(User{Username: "testuser", Password: "testpass1"}).
398		Post(ts.URL + "/login")
399
400	assertError(t, err)
401	assertEqual(t, http.StatusUnauthorized, resp.StatusCode())
402	assertEqual(t, resp.Header().Get("Www-Authenticate"), "Protected Realm")
403
404	t.Logf("Result Error: %q", resp.Error().(*AuthError))
405
406	logResponse(t, resp)
407}
408
409func TestPostXMLStructInvalidResponseXml(t *testing.T) {
410	ts := createPostServer(t)
411	defer ts.Close()
412
413	resp, err := dclr().
414		SetHeader(hdrContentTypeKey, "application/xml").
415		SetBody(User{Username: "testuser", Password: "invalidxml"}).
416		SetResult(&AuthSuccess{}).
417		Post(ts.URL + "/login")
418
419	assertEqual(t, "XML syntax error on line 1: element <Message> closed by </AuthSuccess>", err.Error())
420	assertEqual(t, http.StatusOK, resp.StatusCode())
421
422	t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
423
424	logResponse(t, resp)
425}
426
427func TestPostXMLMapNotSupported(t *testing.T) {
428	ts := createPostServer(t)
429	defer ts.Close()
430
431	_, err := dclr().
432		SetHeader(hdrContentTypeKey, "application/xml").
433		SetBody(map[string]interface{}{"Username": "testuser", "Password": "testpass"}).
434		Post(ts.URL + "/login")
435
436	assertEqual(t, "unsupported 'Body' type/value", err.Error())
437}
438
439func TestRequestBasicAuth(t *testing.T) {
440	ts := createAuthServer(t)
441	defer ts.Close()
442
443	c := dc()
444	c.SetHostURL(ts.URL).
445		SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
446
447	resp, err := c.R().
448		SetBasicAuth("myuser", "basicauth").
449		SetResult(&AuthSuccess{}).
450		Post("/login")
451
452	assertError(t, err)
453	assertEqual(t, http.StatusOK, resp.StatusCode())
454
455	t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
456	logResponse(t, resp)
457}
458
459func TestRequestBasicAuthFail(t *testing.T) {
460	ts := createAuthServer(t)
461	defer ts.Close()
462
463	c := dc()
464	c.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}).
465		SetError(AuthError{})
466
467	resp, err := c.R().
468		SetBasicAuth("myuser", "basicauth1").
469		Post(ts.URL + "/login")
470
471	assertError(t, err)
472	assertEqual(t, http.StatusUnauthorized, resp.StatusCode())
473
474	t.Logf("Result Error: %q", resp.Error().(*AuthError))
475	logResponse(t, resp)
476}
477
478func TestRequestAuthToken(t *testing.T) {
479	ts := createAuthServer(t)
480	defer ts.Close()
481
482	c := dc()
483	c.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}).
484		SetAuthToken("004DDB79-6801-4587-B976-F093E6AC44FF")
485
486	resp, err := c.R().
487		SetAuthToken("004DDB79-6801-4587-B976-F093E6AC44FF-Request").
488		Get(ts.URL + "/profile")
489
490	assertError(t, err)
491	assertEqual(t, http.StatusOK, resp.StatusCode())
492}
493
494func TestFormData(t *testing.T) {
495	ts := createFormPostServer(t)
496	defer ts.Close()
497
498	c := dc()
499	c.SetFormData(map[string]string{"zip_code": "00000", "city": "Los Angeles"}).
500		SetContentLength(true).
501		SetDebug(true).
502		SetLogger(ioutil.Discard)
503
504	resp, err := c.R().
505		SetFormData(map[string]string{"first_name": "Jeevanandam", "last_name": "M", "zip_code": "00001"}).
506		SetBasicAuth("myuser", "mypass").
507		Post(ts.URL + "/profile")
508
509	assertError(t, err)
510	assertEqual(t, http.StatusOK, resp.StatusCode())
511	assertEqual(t, "Success", resp.String())
512}
513
514func TestMultiValueFormData(t *testing.T) {
515	ts := createFormPostServer(t)
516	defer ts.Close()
517
518	v := url.Values{
519		"search_criteria": []string{"book", "glass", "pencil"},
520	}
521
522	c := dc()
523	c.SetContentLength(true).
524		SetDebug(true).
525		SetLogger(ioutil.Discard)
526
527	resp, err := c.R().
528		SetMultiValueFormData(v).
529		Post(ts.URL + "/search")
530
531	assertError(t, err)
532	assertEqual(t, http.StatusOK, resp.StatusCode())
533	assertEqual(t, "Success", resp.String())
534}
535
536func TestFormDataDisableWarn(t *testing.T) {
537	ts := createFormPostServer(t)
538	defer ts.Close()
539
540	c := dc()
541	c.SetFormData(map[string]string{"zip_code": "00000", "city": "Los Angeles"}).
542		SetContentLength(true).
543		SetDebug(true).
544		SetLogger(ioutil.Discard).
545		SetDisableWarn(true)
546
547	resp, err := c.R().
548		SetFormData(map[string]string{"first_name": "Jeevanandam", "last_name": "M", "zip_code": "00001"}).
549		SetBasicAuth("myuser", "mypass").
550		Post(ts.URL + "/profile")
551
552	assertError(t, err)
553	assertEqual(t, http.StatusOK, resp.StatusCode())
554	assertEqual(t, "Success", resp.String())
555}
556
557func TestMultiPartUploadFile(t *testing.T) {
558	ts := createFormPostServer(t)
559	defer ts.Close()
560	defer cleanupFiles(".testdata/upload")
561
562	basePath := getTestDataPath()
563
564	c := dc()
565	c.SetFormData(map[string]string{"zip_code": "00001", "city": "Los Angeles"})
566
567	resp, err := c.R().
568		SetFile("profile_img", filepath.Join(basePath, "test-img.png")).
569		SetContentLength(true).
570		Post(ts.URL + "/upload")
571
572	assertError(t, err)
573	assertEqual(t, http.StatusOK, resp.StatusCode())
574}
575
576func TestMultiPartUploadFileError(t *testing.T) {
577	ts := createFormPostServer(t)
578	defer ts.Close()
579	defer cleanupFiles(".testdata/upload")
580
581	basePath := getTestDataPath()
582
583	c := dc()
584	c.SetFormData(map[string]string{"zip_code": "00001", "city": "Los Angeles"})
585
586	resp, err := c.R().
587		SetFile("profile_img", filepath.Join(basePath, "test-img-not-exists.png")).
588		Post(ts.URL + "/upload")
589
590	if err == nil {
591		t.Errorf("Expected [%v], got [%v]", nil, err)
592	}
593	if resp != nil {
594		t.Errorf("Expected [%v], got [%v]", nil, resp)
595	}
596}
597
598func TestMultiPartUploadFiles(t *testing.T) {
599	ts := createFormPostServer(t)
600	defer ts.Close()
601	defer cleanupFiles(".testdata/upload")
602
603	basePath := getTestDataPath()
604
605	resp, err := dclr().
606		SetFormData(map[string]string{"first_name": "Jeevanandam", "last_name": "M"}).
607		SetFiles(map[string]string{"profile_img": filepath.Join(basePath, "test-img.png"), "notes": filepath.Join(basePath, "text-file.txt")}).
608		Post(ts.URL + "/upload")
609
610	responseStr := resp.String()
611
612	assertError(t, err)
613	assertEqual(t, http.StatusOK, resp.StatusCode())
614	assertEqual(t, true, strings.Contains(responseStr, "test-img.png"))
615	assertEqual(t, true, strings.Contains(responseStr, "text-file.txt"))
616}
617
618func TestMultiPartIoReaderFiles(t *testing.T) {
619	ts := createFormPostServer(t)
620	defer ts.Close()
621	defer cleanupFiles(".testdata/upload")
622
623	basePath := getTestDataPath()
624	profileImgBytes, _ := ioutil.ReadFile(filepath.Join(basePath, "test-img.png"))
625	notesBytes, _ := ioutil.ReadFile(filepath.Join(basePath, "text-file.txt"))
626
627	// Just info values
628	file := File{
629		Name:      "test_file_name.jpg",
630		ParamName: "test_param",
631		Reader:    bytes.NewBuffer([]byte("test bytes")),
632	}
633	t.Logf("File Info: %v", file.String())
634
635	resp, err := dclr().
636		SetFormData(map[string]string{"first_name": "Jeevanandam", "last_name": "M"}).
637		SetFileReader("profile_img", "test-img.png", bytes.NewReader(profileImgBytes)).
638		SetFileReader("notes", "text-file.txt", bytes.NewReader(notesBytes)).
639		Post(ts.URL + "/upload")
640
641	responseStr := resp.String()
642
643	assertError(t, err)
644	assertEqual(t, http.StatusOK, resp.StatusCode())
645	assertEqual(t, true, strings.Contains(responseStr, "test-img.png"))
646	assertEqual(t, true, strings.Contains(responseStr, "text-file.txt"))
647}
648
649func TestMultiPartUploadFileNotOnGetOrDelete(t *testing.T) {
650	ts := createFormPostServer(t)
651	defer ts.Close()
652	defer cleanupFiles(".testdata/upload")
653
654	basePath := getTestDataPath()
655
656	_, err := dclr().
657		SetFile("profile_img", filepath.Join(basePath, "test-img.png")).
658		Get(ts.URL + "/upload")
659
660	assertEqual(t, "multipart content is not allowed in HTTP verb [GET]", err.Error())
661
662	_, err = dclr().
663		SetFile("profile_img", filepath.Join(basePath, "test-img.png")).
664		Delete(ts.URL + "/upload")
665
666	assertEqual(t, "multipart content is not allowed in HTTP verb [DELETE]", err.Error())
667}
668
669func TestMultiPartMultipartField(t *testing.T) {
670	ts := createFormPostServer(t)
671	defer ts.Close()
672	defer cleanupFiles(".testdata/upload")
673
674	jsonBytes := []byte(`{"input": {"name": "Uploaded document", "_filename" : ["file.txt"]}}`)
675
676	resp, err := dclr().
677		SetFormData(map[string]string{"first_name": "Jeevanandam", "last_name": "M"}).
678		SetMultipartField("uploadManifest", "upload-file.json", "application/json", bytes.NewReader(jsonBytes)).
679		Post(ts.URL + "/upload")
680
681	responseStr := resp.String()
682
683	assertError(t, err)
684	assertEqual(t, http.StatusOK, resp.StatusCode())
685	assertEqual(t, true, strings.Contains(responseStr, "upload-file.json"))
686}
687
688func TestMultiPartMultipartFields(t *testing.T) {
689	ts := createFormPostServer(t)
690	defer ts.Close()
691	defer cleanupFiles(".testdata/upload")
692
693	jsonStr1 := `{"input": {"name": "Uploaded document 1", "_filename" : ["file1.txt"]}}`
694	jsonStr2 := `{"input": {"name": "Uploaded document 2", "_filename" : ["file2.txt"]}}`
695
696	fields := []*MultipartField{
697		&MultipartField{
698			Param:       "uploadManifest1",
699			FileName:    "upload-file-1.json",
700			ContentType: "application/json",
701			Reader:      strings.NewReader(jsonStr1),
702		},
703		&MultipartField{
704			Param:       "uploadManifest2",
705			FileName:    "upload-file-2.json",
706			ContentType: "application/json",
707			Reader:      strings.NewReader(jsonStr2),
708		},
709	}
710
711	resp, err := dclr().
712		SetFormData(map[string]string{"first_name": "Jeevanandam", "last_name": "M"}).
713		SetMultipartFields(fields...).
714		Post(ts.URL + "/upload")
715
716	responseStr := resp.String()
717
718	assertError(t, err)
719	assertEqual(t, http.StatusOK, resp.StatusCode())
720	assertEqual(t, true, strings.Contains(responseStr, "upload-file-1.json"))
721	assertEqual(t, true, strings.Contains(responseStr, "upload-file-2.json"))
722}
723
724func TestGetWithCookie(t *testing.T) {
725	ts := createGetServer(t)
726	defer ts.Close()
727
728	c := dc()
729	c.SetHostURL(ts.URL)
730	c.SetCookie(&http.Cookie{
731		Name:     "go-resty-1",
732		Value:    "This is cookie 1 value",
733		Path:     "/",
734		Domain:   "localhost",
735		MaxAge:   36000,
736		HttpOnly: true,
737		Secure:   false,
738	})
739
740	resp, err := c.R().Get("mypage2")
741
742	assertError(t, err)
743	assertEqual(t, http.StatusOK, resp.StatusCode())
744	assertEqual(t, "TestGet: text response from mypage2", resp.String())
745
746	logResponse(t, resp)
747}
748
749func TestGetWithCookies(t *testing.T) {
750	ts := createGetServer(t)
751	defer ts.Close()
752
753	var cookies []*http.Cookie
754
755	cookies = append(cookies, &http.Cookie{
756		Name:     "go-resty-1",
757		Value:    "This is cookie 1 value",
758		Path:     "/",
759		Domain:   "sample.com",
760		MaxAge:   36000,
761		HttpOnly: true,
762		Secure:   false,
763	})
764
765	cookies = append(cookies, &http.Cookie{
766		Name:     "go-resty-2",
767		Value:    "This is cookie 2 value",
768		Path:     "/",
769		Domain:   "sample.com",
770		MaxAge:   36000,
771		HttpOnly: true,
772		Secure:   false,
773	})
774
775	c := dc()
776	c.SetHostURL(ts.URL).
777		SetCookies(cookies)
778
779	resp, err := c.R().Get("mypage2")
780
781	assertError(t, err)
782	assertEqual(t, http.StatusOK, resp.StatusCode())
783	assertEqual(t, "TestGet: text response from mypage2", resp.String())
784
785	logResponse(t, resp)
786}
787
788func TestPutPlainString(t *testing.T) {
789	ts := createGenServer(t)
790	defer ts.Close()
791
792	resp, err := R().
793		SetBody("This is plain text body to server").
794		Put(ts.URL + "/plaintext")
795
796	assertError(t, err)
797	assertEqual(t, http.StatusOK, resp.StatusCode())
798	assertEqual(t, "TestPut: plain text response", resp.String())
799}
800
801func TestPutJSONString(t *testing.T) {
802	ts := createGenServer(t)
803	defer ts.Close()
804
805	DefaultClient.OnBeforeRequest(func(c *Client, r *Request) error {
806		r.SetHeader("X-Custom-Request-Middleware", "OnBeforeRequest middleware")
807		return nil
808	})
809	DefaultClient.OnBeforeRequest(func(c *Client, r *Request) error {
810		c.SetContentLength(true)
811		r.SetHeader("X-ContentLength", "OnBeforeRequest ContentLength set")
812		return nil
813	})
814
815	DefaultClient.SetDebug(true).SetLogger(ioutil.Discard)
816
817	resp, err := R().
818		SetHeaders(map[string]string{hdrContentTypeKey: jsonContentType, hdrAcceptKey: jsonContentType}).
819		SetBody(`{"content":"json content sending to server"}`).
820		Put(ts.URL + "/json")
821
822	assertError(t, err)
823	assertEqual(t, http.StatusOK, resp.StatusCode())
824	assertEqual(t, `{"response":"json response"}`, resp.String())
825}
826
827func TestPutXMLString(t *testing.T) {
828	ts := createGenServer(t)
829	defer ts.Close()
830
831	resp, err := R().
832		SetHeaders(map[string]string{hdrContentTypeKey: "application/xml", hdrAcceptKey: "application/xml"}).
833		SetBody(`<?xml version="1.0" encoding="UTF-8"?><Request>XML Content sending to server</Request>`).
834		Put(ts.URL + "/xml")
835
836	assertError(t, err)
837	assertEqual(t, http.StatusOK, resp.StatusCode())
838	assertEqual(t, `<?xml version="1.0" encoding="UTF-8"?><Response>XML response</Response>`, resp.String())
839}
840
841func TestOnBeforeMiddleware(t *testing.T) {
842	ts := createGenServer(t)
843	defer ts.Close()
844
845	c := dc()
846	c.OnBeforeRequest(func(c *Client, r *Request) error {
847		r.SetHeader("X-Custom-Request-Middleware", "OnBeforeRequest middleware")
848		return nil
849	})
850	c.OnBeforeRequest(func(c *Client, r *Request) error {
851		c.SetContentLength(true)
852		r.SetHeader("X-ContentLength", "OnBeforeRequest ContentLength set")
853		return nil
854	})
855
856	resp, err := c.R().
857		SetBody("OnBeforeRequest: This is plain text body to server").
858		Put(ts.URL + "/plaintext")
859
860	assertError(t, err)
861	assertEqual(t, http.StatusOK, resp.StatusCode())
862	assertEqual(t, "TestPut: plain text response", resp.String())
863}
864
865func TestNoAutoRedirect(t *testing.T) {
866	ts := createRedirectServer(t)
867	defer ts.Close()
868
869	_, err := R().Get(ts.URL + "/redirect-1")
870
871	assertEqual(t, "Get /redirect-2: auto redirect is disabled", err.Error())
872}
873
874func TestHTTPAutoRedirectUpTo10(t *testing.T) {
875	ts := createRedirectServer(t)
876	defer ts.Close()
877
878	c := dc()
879	c.SetHTTPMode()
880	_, err := c.R().Get(ts.URL + "/redirect-1")
881
882	assertEqual(t, "Get /redirect-11: stopped after 10 redirects", err.Error())
883}
884
885func TestHostCheckRedirectPolicy(t *testing.T) {
886	ts := createRedirectServer(t)
887	defer ts.Close()
888
889	c := dc().
890		SetRedirectPolicy(DomainCheckRedirectPolicy("127.0.0.1"))
891
892	_, err := c.R().Get(ts.URL + "/redirect-host-check-1")
893
894	assertNotNil(t, err)
895	assertEqual(t, true, strings.Contains(err.Error(), "redirect is not allowed as per DomainCheckRedirectPolicy"))
896}
897
898func TestHeadMethod(t *testing.T) {
899	ts := createGetServer(t)
900	defer ts.Close()
901
902	resp, err := dclr().Head(ts.URL + "/")
903
904	assertError(t, err)
905	assertEqual(t, http.StatusOK, resp.StatusCode())
906}
907
908func TestOptionsMethod(t *testing.T) {
909	ts := createGenServer(t)
910	defer ts.Close()
911
912	resp, err := dclr().Options(ts.URL + "/options")
913
914	assertError(t, err)
915	assertEqual(t, http.StatusOK, resp.StatusCode())
916	assertEqual(t, resp.Header().Get("Access-Control-Expose-Headers"), "x-go-resty-id")
917}
918
919func TestPatchMethod(t *testing.T) {
920	ts := createGenServer(t)
921	defer ts.Close()
922
923	resp, err := dclr().Patch(ts.URL + "/patch")
924
925	assertError(t, err)
926	assertEqual(t, http.StatusOK, resp.StatusCode())
927
928	resp.body = nil
929	assertEqual(t, "", resp.String())
930}
931
932func TestRawFileUploadByBody(t *testing.T) {
933	ts := createFormPostServer(t)
934	defer ts.Close()
935
936	file, err := os.Open(filepath.Join(getTestDataPath(), "test-img.png"))
937	assertNil(t, err)
938	fileBytes, err := ioutil.ReadAll(file)
939	assertNil(t, err)
940
941	resp, err := dclr().
942		SetBody(fileBytes).
943		SetContentLength(true).
944		SetAuthToken("004DDB79-6801-4587-B976-F093E6AC44FF").
945		Put(ts.URL + "/raw-upload")
946
947	assertError(t, err)
948	assertEqual(t, http.StatusOK, resp.StatusCode())
949	assertEqual(t, "image/png", resp.Request.Header.Get(hdrContentTypeKey))
950}
951
952func TestProxySetting(t *testing.T) {
953	c := dc()
954
955	transport, err := c.getTransport()
956
957	assertNil(t, err)
958
959	assertEqual(t, false, c.IsProxySet())
960	assertNil(t, transport.Proxy)
961
962	c.SetProxy("http://sampleproxy:8888")
963	assertEqual(t, true, c.IsProxySet())
964	assertNotNil(t, transport.Proxy)
965
966	c.SetProxy("//not.a.user@%66%6f%6f.com:8888")
967	assertEqual(t, false, c.IsProxySet())
968	assertNil(t, transport.Proxy)
969
970	SetProxy("http://sampleproxy:8888")
971	assertEqual(t, true, IsProxySet())
972	RemoveProxy()
973	assertNil(t, DefaultClient.proxyURL)
974	assertNil(t, transport.Proxy)
975}
976
977func TestGetClient(t *testing.T) {
978	client := GetClient()
979	custom := New()
980	customClient := custom.GetClient()
981
982	assertNotNil(t, client)
983	assertNotNil(t, customClient)
984
985	assertNotEqual(t, client, http.DefaultClient)
986	assertNotEqual(t, customClient, http.DefaultClient)
987	assertNotEqual(t, client, customClient)
988
989	assertEqual(t, DefaultClient.httpClient, client)
990}
991
992func TestIncorrectURL(t *testing.T) {
993	_, err := R().Get("//not.a.user@%66%6f%6f.com/just/a/path/also")
994	assertEqual(t, true, strings.Contains(err.Error(), "parse //not.a.user@%66%6f%6f.com/just/a/path/also"))
995
996	c := dc()
997	c.SetHostURL("//not.a.user@%66%6f%6f.com")
998	_, err1 := c.R().Get("/just/a/path/also")
999	assertEqual(t, true, strings.Contains(err1.Error(), "parse //not.a.user@%66%6f%6f.com/just/a/path/also"))
1000}
1001
1002func TestDetectContentTypeForPointer(t *testing.T) {
1003	ts := createPostServer(t)
1004	defer ts.Close()
1005
1006	user := &User{Username: "testuser", Password: "testpass"}
1007
1008	resp, err := dclr().
1009		SetBody(user).
1010		SetResult(AuthSuccess{}).
1011		Post(ts.URL + "/login")
1012
1013	assertError(t, err)
1014	assertEqual(t, http.StatusOK, resp.StatusCode())
1015
1016	t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
1017
1018	logResponse(t, resp)
1019}
1020
1021type ExampleUser struct {
1022	FirstName string `json:"frist_name"`
1023	LastName  string `json:"last_name"`
1024	ZipCode   string `json:"zip_code"`
1025}
1026
1027func TestDetectContentTypeForPointerWithSlice(t *testing.T) {
1028	ts := createPostServer(t)
1029	defer ts.Close()
1030
1031	users := &[]ExampleUser{
1032		{FirstName: "firstname1", LastName: "lastname1", ZipCode: "10001"},
1033		{FirstName: "firstname2", LastName: "lastname3", ZipCode: "10002"},
1034		{FirstName: "firstname3", LastName: "lastname3", ZipCode: "10003"},
1035	}
1036
1037	resp, err := dclr().
1038		SetBody(users).
1039		Post(ts.URL + "/users")
1040
1041	assertError(t, err)
1042	assertEqual(t, http.StatusAccepted, resp.StatusCode())
1043
1044	t.Logf("Result Success: %q", resp)
1045
1046	logResponse(t, resp)
1047}
1048
1049func TestDetectContentTypeForPointerWithSliceMap(t *testing.T) {
1050	ts := createPostServer(t)
1051	defer ts.Close()
1052
1053	usersmap := map[string]interface{}{
1054		"user1": ExampleUser{FirstName: "firstname1", LastName: "lastname1", ZipCode: "10001"},
1055		"user2": &ExampleUser{FirstName: "firstname2", LastName: "lastname3", ZipCode: "10002"},
1056		"user3": ExampleUser{FirstName: "firstname3", LastName: "lastname3", ZipCode: "10003"},
1057	}
1058
1059	var users []map[string]interface{}
1060	users = append(users, usersmap)
1061
1062	resp, err := dclr().
1063		SetBody(&users).
1064		Post(ts.URL + "/usersmap")
1065
1066	assertError(t, err)
1067	assertEqual(t, http.StatusAccepted, resp.StatusCode())
1068
1069	t.Logf("Result Success: %q", resp)
1070
1071	logResponse(t, resp)
1072}
1073
1074func TestDetectContentTypeForSlice(t *testing.T) {
1075	ts := createPostServer(t)
1076	defer ts.Close()
1077
1078	users := []ExampleUser{
1079		{FirstName: "firstname1", LastName: "lastname1", ZipCode: "10001"},
1080		{FirstName: "firstname2", LastName: "lastname3", ZipCode: "10002"},
1081		{FirstName: "firstname3", LastName: "lastname3", ZipCode: "10003"},
1082	}
1083
1084	resp, err := dclr().
1085		SetBody(users).
1086		Post(ts.URL + "/users")
1087
1088	assertError(t, err)
1089	assertEqual(t, http.StatusAccepted, resp.StatusCode())
1090
1091	t.Logf("Result Success: %q", resp)
1092
1093	logResponse(t, resp)
1094}
1095
1096func TestMultiParamsQueryString(t *testing.T) {
1097	ts1 := createGetServer(t)
1098	defer ts1.Close()
1099
1100	client := dc()
1101	req1 := client.R()
1102
1103	client.SetQueryParam("status", "open")
1104
1105	_, _ = req1.SetQueryParam("status", "pending").
1106		Get(ts1.URL)
1107
1108	assertEqual(t, true, strings.Contains(req1.URL, "status=pending"))
1109	// pending overrides open
1110	assertEqual(t, false, strings.Contains(req1.URL, "status=open"))
1111
1112	_, _ = req1.SetQueryParam("status", "approved").
1113		Get(ts1.URL)
1114
1115	assertEqual(t, true, strings.Contains(req1.URL, "status=approved"))
1116	// approved overrides pending
1117	assertEqual(t, false, strings.Contains(req1.URL, "status=pending"))
1118
1119	ts2 := createGetServer(t)
1120	defer ts2.Close()
1121
1122	req2 := client.R()
1123
1124	v := url.Values{
1125		"status": []string{"pending", "approved", "reject"},
1126	}
1127
1128	_, _ = req2.SetMultiValueQueryParams(v).Get(ts2.URL)
1129
1130	assertEqual(t, true, strings.Contains(req2.URL, "status=pending"))
1131	assertEqual(t, true, strings.Contains(req2.URL, "status=approved"))
1132	assertEqual(t, true, strings.Contains(req2.URL, "status=reject"))
1133
1134	// because it's removed by key
1135	assertEqual(t, false, strings.Contains(req2.URL, "status=open"))
1136}
1137
1138func TestSetQueryStringTypical(t *testing.T) {
1139	ts := createGetServer(t)
1140	defer ts.Close()
1141
1142	resp, err := dclr().
1143		SetQueryString("productId=232&template=fresh-sample&cat=resty&source=google&kw=buy a lot more").
1144		Get(ts.URL)
1145
1146	assertError(t, err)
1147	assertEqual(t, http.StatusOK, resp.StatusCode())
1148	assertEqual(t, "200 OK", resp.Status())
1149	assertEqual(t, "TestGet: text response", resp.String())
1150
1151	resp, err = dclr().
1152		SetQueryString("&%%amp;").
1153		Get(ts.URL)
1154
1155	assertError(t, err)
1156	assertEqual(t, http.StatusOK, resp.StatusCode())
1157	assertEqual(t, "200 OK", resp.Status())
1158	assertEqual(t, "TestGet: text response", resp.String())
1159}
1160
1161func TestOutputFileWithBaseDirAndRelativePath(t *testing.T) {
1162	ts := createGetServer(t)
1163	defer ts.Close()
1164	defer cleanupFiles(".testdata/dir-sample")
1165
1166	DefaultClient = dc()
1167	SetRedirectPolicy(FlexibleRedirectPolicy(10))
1168	SetOutputDirectory(filepath.Join(getTestDataPath(), "dir-sample"))
1169	SetDebug(true)
1170	SetLogger(ioutil.Discard)
1171
1172	resp, err := R().
1173		SetOutput("go-resty/test-img-success.png").
1174		Get(ts.URL + "/my-image.png")
1175
1176	assertError(t, err)
1177	assertEqual(t, true, resp.Size() != 0)
1178}
1179
1180func TestOutputFileWithBaseDirError(t *testing.T) {
1181	c := dc().SetRedirectPolicy(FlexibleRedirectPolicy(10)).
1182		SetOutputDirectory(filepath.Join(getTestDataPath(), `go-resty\0`))
1183
1184	_ = c
1185}
1186
1187func TestOutputPathDirNotExists(t *testing.T) {
1188	ts := createGetServer(t)
1189	defer ts.Close()
1190	defer cleanupFiles(filepath.Join(".testdata", "not-exists-dir"))
1191
1192	DefaultClient = dc()
1193	SetRedirectPolicy(FlexibleRedirectPolicy(10))
1194	SetOutputDirectory(filepath.Join(getTestDataPath(), "not-exists-dir"))
1195
1196	resp, err := R().
1197		SetOutput("test-img-success.png").
1198		Get(ts.URL + "/my-image.png")
1199
1200	assertError(t, err)
1201	assertEqual(t, true, resp.Size() != 0)
1202}
1203
1204func TestOutputFileAbsPath(t *testing.T) {
1205	ts := createGetServer(t)
1206	defer ts.Close()
1207	defer cleanupFiles(filepath.Join(".testdata", "go-resty"))
1208
1209	_, err := dcr().
1210		SetOutput(filepath.Join(getTestDataPath(), "go-resty", "test-img-success-2.png")).
1211		Get(ts.URL + "/my-image.png")
1212
1213	assertError(t, err)
1214}
1215
1216func TestContextInternal(t *testing.T) {
1217	ts := createGetServer(t)
1218	defer ts.Close()
1219
1220	r := R().
1221		SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10))
1222
1223	if r.isContextCancelledIfAvailable() {
1224		t.Error("isContextCancelledIfAvailable != false for vanilla R()")
1225	}
1226	r.addContextIfAvailable()
1227
1228	resp, err := r.Get(ts.URL + "/")
1229
1230	assertError(t, err)
1231	assertEqual(t, http.StatusOK, resp.StatusCode())
1232}
1233
1234func TestSRV(t *testing.T) {
1235	c := dc().
1236		SetRedirectPolicy(FlexibleRedirectPolicy(20)).
1237		SetScheme("http")
1238
1239	r := c.R().
1240		SetSRV(&SRVRecord{"xmpp-server", "google.com"})
1241
1242	assertEqual(t, "xmpp-server", r.SRV.Service)
1243	assertEqual(t, "google.com", r.SRV.Domain)
1244
1245	resp, err := r.Get("/")
1246	if err == nil {
1247		assertError(t, err)
1248		assertNotNil(t, resp)
1249		assertEqual(t, http.StatusOK, resp.StatusCode())
1250	}
1251}
1252
1253func TestSRVInvalidService(t *testing.T) {
1254	_, err := R().
1255		SetSRV(&SRVRecord{"nonexistantservice", "sampledomain"}).
1256		Get("/")
1257
1258	assertNotNil(t, err)
1259	assertType(t, net.DNSError{}, err)
1260}
1261
1262func TestDeprecatedCodeCoverage(t *testing.T) {
1263	var user1 User
1264	err := Unmarshal("application/json",
1265		[]byte(`{"username":"testuser", "password":"testpass"}`), &user1)
1266	assertError(t, err)
1267	assertEqual(t, "testuser", user1.Username)
1268	assertEqual(t, "testpass", user1.Password)
1269
1270	var user2 User
1271	err = Unmarshal("application/xml",
1272		[]byte(`<?xml version="1.0" encoding="UTF-8"?><User><Username>testuser</Username><Password>testpass</Password></User>`),
1273		&user2)
1274	assertError(t, err)
1275	assertEqual(t, "testuser", user1.Username)
1276	assertEqual(t, "testpass", user1.Password)
1277}
1278
1279func TestRequestDoNotParseResponse(t *testing.T) {
1280	ts := createGetServer(t)
1281	defer ts.Close()
1282
1283	resp, err := dc().R().
1284		SetDoNotParseResponse(true).
1285		SetQueryParam("request_no", strconv.FormatInt(time.Now().Unix(), 10)).
1286		Get(ts.URL + "/")
1287
1288	assertError(t, err)
1289
1290	buf := acquireBuffer()
1291	defer releaseBuffer(buf)
1292	_, _ = io.Copy(buf, resp.RawBody())
1293
1294	assertEqual(t, "TestGet: text response", buf.String())
1295	_ = resp.RawBody().Close()
1296
1297	// Manually setting RawResponse as nil
1298	resp, err = dc().R().
1299		SetDoNotParseResponse(true).
1300		Get(ts.URL + "/")
1301
1302	assertError(t, err)
1303
1304	resp.RawResponse = nil
1305	assertNil(t, resp.RawBody())
1306
1307	// just set test part
1308	SetDoNotParseResponse(true)
1309	assertEqual(t, true, DefaultClient.notParseResponse)
1310	SetDoNotParseResponse(false)
1311}
1312
1313type noCtTest struct {
1314	Response string `json:"response"`
1315}
1316
1317func TestRequestExpectContentTypeTest(t *testing.T) {
1318	ts := createGenServer(t)
1319	defer ts.Close()
1320
1321	c := dc()
1322	resp, err := c.R().
1323		SetResult(noCtTest{}).
1324		ExpectContentType("application/json").
1325		Get(ts.URL + "/json-no-set")
1326
1327	assertError(t, err)
1328	assertEqual(t, http.StatusOK, resp.StatusCode())
1329	assertNotNil(t, resp.Result())
1330	assertEqual(t, "json response no content type set", resp.Result().(*noCtTest).Response)
1331
1332	assertEqual(t, "", firstNonEmpty("", ""))
1333}
1334
1335func TestGetPathParams(t *testing.T) {
1336	ts := createGetServer(t)
1337	defer ts.Close()
1338
1339	c := dc()
1340	c.SetHostURL(ts.URL).
1341		SetPathParams(map[string]string{
1342			"userId": "sample@sample.com",
1343		})
1344
1345	resp, err := c.R().SetPathParams(map[string]string{
1346		"subAccountId": "100002",
1347	}).
1348		Get("/v1/users/{userId}/{subAccountId}/details")
1349
1350	assertError(t, err)
1351	assertEqual(t, http.StatusOK, resp.StatusCode())
1352	assertEqual(t, true, strings.Contains(resp.String(), "TestGetPathParams: text response"))
1353	assertEqual(t, true, strings.Contains(resp.String(), "/v1/users/sample@sample.com/100002/details"))
1354
1355	logResponse(t, resp)
1356
1357	SetPathParams(map[string]string{
1358		"userId": "sample@sample.com",
1359	})
1360}
1361
1362func TestReportMethodSupportsPayload(t *testing.T) {
1363	ts := createGenServer(t)
1364	defer ts.Close()
1365
1366	c := dc()
1367	resp, err := c.R().
1368		SetBody("body").
1369		Execute("REPORT", ts.URL+"/report")
1370
1371	assertError(t, err)
1372	assertEqual(t, http.StatusOK, resp.StatusCode())
1373
1374}
1375
1376func TestRequestQueryStringOrder(t *testing.T) {
1377	ts := createGetServer(t)
1378	defer ts.Close()
1379
1380	resp, err := New().R().
1381		SetQueryString("productId=232&template=fresh-sample&cat=resty&source=google&kw=buy a lot more").
1382		Get(ts.URL + "/?UniqueId=ead1d0ed-XXX-XXX-XXX-abb7612b3146&Translate=false&tempauth=eyJ0eXAiOiJKV1QiLC...HZEhwVnJ1d0NSUGVLaUpSaVNLRG5scz0&ApiVersion=2.0")
1383
1384	assertError(t, err)
1385	assertEqual(t, http.StatusOK, resp.StatusCode())
1386	assertEqual(t, "200 OK", resp.Status())
1387	assertNotNil(t, resp.Body())
1388	assertEqual(t, "TestGet: text response", resp.String())
1389
1390	logResponse(t, resp)
1391}
1392
1393func TestRequestOverridesClientAuthorizationHeader(t *testing.T) {
1394	ts := createAuthServer(t)
1395	defer ts.Close()
1396
1397	c := dc()
1398	c.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}).
1399		SetHeader("Authorization", "some token")
1400	SetHostURL(ts.URL + "/")
1401
1402	resp, err := c.R().
1403		SetHeader("Authorization", "Bearer 004DDB79-6801-4587-B976-F093E6AC44FF").
1404		Get("/profile")
1405
1406	assertError(t, err)
1407	assertEqual(t, http.StatusOK, resp.StatusCode())
1408}
1409
1410func TestRequestFileUploadAsReader(t *testing.T) {
1411	ts := createFilePostServer(t)
1412	defer ts.Close()
1413
1414	file, _ := os.Open(filepath.Join(getTestDataPath(), "test-img.png"))
1415	defer file.Close()
1416
1417	resp, err := dclr().
1418		SetBody(file).
1419		SetHeader("Content-Type", "image/png").
1420		Post(ts.URL + "/upload")
1421
1422	assertError(t, err)
1423	assertEqual(t, http.StatusOK, resp.StatusCode())
1424	assertEqual(t, true, strings.Contains(resp.String(), "File Uploaded successfully"))
1425
1426	file, _ = os.Open(filepath.Join(getTestDataPath(), "test-img.png"))
1427	defer file.Close()
1428
1429	resp, err = dclr().
1430		SetBody(file).
1431		SetHeader("Content-Type", "image/png").
1432		SetContentLength(true).
1433		Post(ts.URL + "/upload")
1434
1435	assertError(t, err)
1436	assertEqual(t, http.StatusOK, resp.StatusCode())
1437	assertEqual(t, true, strings.Contains(resp.String(), "File Uploaded successfully"))
1438}
1439
1440func TestHostHeaderOverride(t *testing.T) {
1441	ts := createGetServer(t)
1442	defer ts.Close()
1443
1444	resp, err := R().
1445		SetHeader("Host", "myhostname").
1446		Get(ts.URL + "/host-header")
1447
1448	assertError(t, err)
1449	assertEqual(t, http.StatusOK, resp.StatusCode())
1450	assertEqual(t, "200 OK", resp.Status())
1451	assertNotNil(t, resp.Body())
1452	assertEqual(t, "myhostname", resp.String())
1453
1454	logResponse(t, resp)
1455}
1456
1457func TestPathParamURLInput(t *testing.T) {
1458	ts := createGetServer(t)
1459	defer ts.Close()
1460
1461	c := dc().SetDebug(true).SetLogger(ioutil.Discard)
1462	c.SetHostURL(ts.URL).
1463		SetPathParams(map[string]string{
1464			"userId": "sample@sample.com",
1465		})
1466
1467	resp, err := c.R().
1468		SetPathParams(map[string]string{
1469			"subAccountId": "100002",
1470			"website":      "https://example.com",
1471		}).Get("/v1/users/{userId}/{subAccountId}/{website}")
1472
1473	assertError(t, err)
1474	assertEqual(t, http.StatusOK, resp.StatusCode())
1475	assertEqual(t, true, strings.Contains(resp.String(), "TestPathParamURLInput: text response"))
1476	assertEqual(t, true, strings.Contains(resp.String(), "/v1/users/sample@sample.com/100002/https:%2F%2Fexample.com"))
1477
1478	logResponse(t, resp)
1479}
1480