// Copyright (c) 2015-2017 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
// resty source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.
package resty
import (
"crypto/tls"
"errors"
"io/ioutil"
"net/http"
"net/url"
"reflect"
"strconv"
"strings"
"testing"
"time"
)
func TestClientBasicAuth(t *testing.T) {
ts := createAuthServer(t)
defer ts.Close()
c := dc()
c.SetBasicAuth("myuser", "basicauth").
SetHostURL(ts.URL).
SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
resp, err := c.R().
SetResult(&AuthSuccess{}).
Post("/login")
assertError(t, err)
assertEqual(t, http.StatusOK, resp.StatusCode())
t.Logf("Result Success: %q", resp.Result().(*AuthSuccess))
logResponse(t, resp)
}
func TestClientAuthToken(t *testing.T) {
ts := createAuthServer(t)
defer ts.Close()
c := dc()
c.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}).
SetAuthToken("004DDB79-6801-4587-B976-F093E6AC44FF").
SetHostURL(ts.URL + "/")
resp, err := c.R().Get("/profile")
assertError(t, err)
assertEqual(t, http.StatusOK, resp.StatusCode())
}
func TestOnAfterMiddleware(t *testing.T) {
ts := createGenServer(t)
defer ts.Close()
c := dc()
c.OnAfterResponse(func(c *Client, res *Response) error {
t.Logf("Request sent at: %v", res.Request.Time)
t.Logf("Response Recevied at: %v", res.ReceivedAt())
return nil
})
resp, err := c.R().
SetBody("OnAfterResponse: This is plain text body to server").
Put(ts.URL + "/plaintext")
assertError(t, err)
assertEqual(t, http.StatusOK, resp.StatusCode())
assertEqual(t, "TestPut: plain text response", resp.String())
}
func TestClientRedirectPolicy(t *testing.T) {
ts := createRedirectServer(t)
defer ts.Close()
c := dc()
c.SetHTTPMode().
SetRedirectPolicy(FlexibleRedirectPolicy(20))
_, err := c.R().Get(ts.URL + "/redirect-1")
assertEqual(t, "Get /redirect-21: Stopped after 20 redirects", err.Error())
}
func TestClientTimeout(t *testing.T) {
ts := createGetServer(t)
defer ts.Close()
c := dc()
c.SetHTTPMode().
SetTimeout(time.Duration(time.Second * 3))
_, err := c.R().Get(ts.URL + "/set-timeout-test")
assertEqual(t, true, strings.Contains(strings.ToLower(err.Error()), "timeout"))
}
func TestClientTimeoutWithinThreshold(t *testing.T) {
ts := createGetServer(t)
defer ts.Close()
c := dc()
c.SetHTTPMode().
SetTimeout(time.Duration(time.Second * 3))
resp, err := c.R().Get(ts.URL + "/set-timeout-test-with-sequence")
assertError(t, err)
seq1, _ := strconv.ParseInt(resp.String(), 10, 32)
resp, err = c.R().Get(ts.URL + "/set-timeout-test-with-sequence")
assertError(t, err)
seq2, _ := strconv.ParseInt(resp.String(), 10, 32)
assertEqual(t, seq1+1, seq2)
}
func TestClientTimeoutInternalError(t *testing.T) {
c := dc()
c.SetHTTPMode()
c.SetTimeout(time.Duration(time.Second * 1))
_, _ = c.R().Get("http://localhost:9000/set-timeout-test")
}
func TestClientProxy(t *testing.T) {
ts := createGetServer(t)
defer ts.Close()
c := dc()
c.SetTimeout(1 * time.Second)
c.SetProxy("http://sampleproxy:8888")
resp, err := c.R().Get(ts.URL)
assertNotNil(t, resp)
assertNotNil(t, err)
// Error
c.SetProxy("//not.a.user@%66%6f%6f.com:8888")
resp, err = c.R().
Get(ts.URL)
assertNil(t, err)
assertNotNil(t, resp)
}
func TestClientSetCertificates(t *testing.T) {
DefaultClient = dc()
SetCertificates(tls.Certificate{})
transport, err := DefaultClient.getTransport()
assertNil(t, err)
assertEqual(t, 1, len(transport.TLSClientConfig.Certificates))
}
func TestClientSetRootCertificate(t *testing.T) {
DefaultClient = dc()
SetRootCertificate(getTestDataPath() + "/sample-root.pem")
transport, err := DefaultClient.getTransport()
assertNil(t, err)
assertNotNil(t, transport.TLSClientConfig.RootCAs)
}
func TestClientSetRootCertificateNotExists(t *testing.T) {
DefaultClient = dc()
SetRootCertificate(getTestDataPath() + "/not-exists-sample-root.pem")
transport, err := DefaultClient.getTransport()
assertNil(t, err)
assertNil(t, transport.TLSClientConfig)
}
func TestClientOnBeforeRequestModification(t *testing.T) {
tc := New()
tc.OnBeforeRequest(func(c *Client, r *Request) error {
r.SetAuthToken("This is test auth token")
return nil
})
ts := createGetServer(t)
defer ts.Close()
resp, err := tc.R().Get(ts.URL + "/")
assertError(t, err)
assertEqual(t, http.StatusOK, resp.StatusCode())
assertEqual(t, "200 OK", resp.Status())
assertNotNil(t, resp.Body())
assertEqual(t, "TestGet: text response", resp.String())
logResponse(t, resp)
}
func TestClientSetTransport(t *testing.T) {
ts := createGetServer(t)
defer ts.Close()
DefaultClient = dc()
transport := &http.Transport{
// something like Proxying to httptest.Server, etc...
Proxy: func(req *http.Request) (*url.URL, error) {
return url.Parse(ts.URL)
},
}
SetTransport(transport)
transportInUse, err := DefaultClient.getTransport()
assertNil(t, err)
assertEqual(t, true, transport == transportInUse)
}
func TestClientSetScheme(t *testing.T) {
DefaultClient = dc()
SetScheme("http")
assertEqual(t, true, DefaultClient.scheme == "http")
}
func TestClientSetCookieJar(t *testing.T) {
DefaultClient = dc()
backupJar := DefaultClient.httpClient.Jar
SetCookieJar(nil)
assertNil(t, DefaultClient.httpClient.Jar)
SetCookieJar(backupJar)
assertEqual(t, true, DefaultClient.httpClient.Jar == backupJar)
}
func TestClientOptions(t *testing.T) {
SetHTTPMode().SetContentLength(true)
assertEqual(t, Mode(), "http")
assertEqual(t, DefaultClient.setContentLength, true)
SetRESTMode()
assertEqual(t, Mode(), "rest")
SetHostURL("http://httpbin.org")
assertEqual(t, "http://httpbin.org", DefaultClient.HostURL)
SetHeader(hdrContentTypeKey, jsonContentType)
SetHeaders(map[string]string{
hdrUserAgentKey: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) go-resty v0.1",
"X-Request-Id": strconv.FormatInt(time.Now().UnixNano(), 10),
})
assertEqual(t, jsonContentType, DefaultClient.Header.Get(hdrContentTypeKey))
SetCookie(&http.Cookie{
Name: "default-cookie",
Value: "This is cookie default-cookie value",
Path: "/",
Domain: "localhost",
MaxAge: 36000,
HttpOnly: true,
Secure: false,
})
assertEqual(t, "default-cookie", DefaultClient.Cookies[0].Name)
var cookies []*http.Cookie
cookies = append(cookies, &http.Cookie{
Name: "default-cookie-1",
Value: "This is default-cookie 1 value",
Path: "/",
})
cookies = append(cookies, &http.Cookie{
Name: "default-cookie-2",
Value: "This is default-cookie 2 value",
Path: "/",
})
SetCookies(cookies)
assertEqual(t, "default-cookie-1", DefaultClient.Cookies[1].Name)
assertEqual(t, "default-cookie-2", DefaultClient.Cookies[2].Name)
SetQueryParam("test_param_1", "Param_1")
SetQueryParams(map[string]string{"test_param_2": "Param_2", "test_param_3": "Param_3"})
assertEqual(t, "Param_3", DefaultClient.QueryParam.Get("test_param_3"))
rTime := strconv.FormatInt(time.Now().UnixNano(), 10)
SetFormData(map[string]string{"r_time": rTime})
assertEqual(t, rTime, DefaultClient.FormData.Get("r_time"))
SetBasicAuth("myuser", "mypass")
assertEqual(t, "myuser", DefaultClient.UserInfo.Username)
SetAuthToken("AC75BD37F019E08FBC594900518B4F7E")
assertEqual(t, "AC75BD37F019E08FBC594900518B4F7E", DefaultClient.Token)
SetDisableWarn(true)
assertEqual(t, DefaultClient.DisableWarn, true)
SetRetryCount(3)
assertEqual(t, 3, DefaultClient.RetryCount)
rwt := time.Duration(1000) * time.Millisecond
SetRetryWaitTime(rwt)
assertEqual(t, rwt, DefaultClient.RetryWaitTime)
mrwt := time.Duration(2) * time.Second
SetRetryMaxWaitTime(mrwt)
assertEqual(t, mrwt, DefaultClient.RetryMaxWaitTime)
err := &AuthError{}
SetError(err)
if reflect.TypeOf(err) == DefaultClient.Error {
t.Error("SetError failed")
}
SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
transport, transportErr := DefaultClient.getTransport()
assertNil(t, transportErr)
assertEqual(t, true, transport.TLSClientConfig.InsecureSkipVerify)
OnBeforeRequest(func(c *Client, r *Request) error {
c.Log.Println("I'm in Request middleware")
return nil // if it success
})
OnAfterResponse(func(c *Client, r *Response) error {
c.Log.Println("I'm in Response middleware")
return nil // if it success
})
SetTimeout(time.Duration(5 * time.Second))
SetRedirectPolicy(FlexibleRedirectPolicy(10), func(req *http.Request, via []*http.Request) error {
return errors.New("sample test redirect")
})
SetContentLength(true)
SetDebug(true)
assertEqual(t, DefaultClient.Debug, true)
SetAllowGetMethodPayload(true)
assertEqual(t, DefaultClient.AllowGetMethodPayload, true)
SetScheme("http")
assertEqual(t, DefaultClient.scheme, "http")
SetCloseConnection(true)
assertEqual(t, DefaultClient.closeConnection, true)
SetLogger(ioutil.Discard)
}
func TestClientPreRequestHook(t *testing.T) {
SetPreRequestHook(func(c *Client, r *Request) error {
c.Log.Println("I'm in Pre-Request Hook")
return nil
})
SetPreRequestHook(func(c *Client, r *Request) error {
c.Log.Println("I'm Overwriting existing Pre-Request Hook")
return nil
})
}
func TestClientAllowsGetMethodPayload(t *testing.T) {
ts := createGetServer(t)
defer ts.Close()
c := dc()
c.SetAllowGetMethodPayload(true)
c.SetPreRequestHook(func(*Client, *Request) error { return nil }) // for coverage
payload := "test-payload"
resp, err := c.R().SetBody(payload).Get(ts.URL + "/get-method-payload-test")
assertError(t, err)
assertEqual(t, http.StatusOK, resp.StatusCode())
assertEqual(t, payload, resp.String())
}
func TestClientRoundTripper(t *testing.T) {
c := New()
rt := &CustomRoundTripper{}
c.SetTransport(rt)
ct, err := c.getTransport()
assertNotNil(t, err)
assertNil(t, ct)
assertEqual(t, "current transport is not an *http.Transport instance", err.Error())
c.SetTLSClientConfig(&tls.Config{})
c.SetProxy("http://localhost:9090")
c.RemoveProxy()
c.SetCertificates(tls.Certificate{})
c.SetRootCertificate(getTestDataPath() + "/sample-root.pem")
}
func TestClientNewRequest(t *testing.T) {
c := New()
request := c.NewRequest()
assertNotNil(t, request)
}
func TestNewRequest(t *testing.T) {
request := NewRequest()
assertNotNil(t, request)
}
// CustomRoundTripper just for test
type CustomRoundTripper struct {
}
// RoundTrip just for test
func (rt *CustomRoundTripper) RoundTrip(_ *http.Request) (*http.Response, error) {
return &http.Response{}, nil
}