gorush/vendor/gopkg.in/appleboy/gofight.v2/gofight.go

315 lines
6.0 KiB
Go

// Package gofight offers simple API http handler testing for Golang framework.
//
// Details about the gofight project are found in github page:
//
// https://github.com/appleboy/gofight
//
// Installation:
//
// $ go get -u github.com/appleboy/gofight
//
// Set Header: You can add custom header via SetHeader func.
//
// SetHeader(gofight.H{
// "X-Version": version,
// })
//
// Set Cookie: You can add custom cookie via SetCookie func.
//
// SetCookie(gofight.H{
// "foo": "bar",
// })
//
// Set query string: Using SetQuery to generate query string data.
//
// SetQuery(gofight.H{
// "a": "1",
// "b": "2",
// })
//
// POST FORM Data: Using SetForm to generate form data.
//
// SetForm(gofight.H{
// "a": "1",
// "b": "2",
// })
//
// POST JSON Data: Using SetJSON to generate json data.
//
// SetJSON(gofight.H{
// "a": "1",
// "b": "2",
// })
//
// POST RAW Data: Using SetBody to generate raw data.
//
// SetBody("a=1&b=1")
//
// For more details, see the documentation and example.
//
package gofight
import (
"bytes"
"crypto/tls"
"encoding/json"
"io/ioutil"
"log"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
// "github.com/labstack/echo"
"github.com/stretchr/testify/assert"
)
// Media types
const (
Version = "1.0"
UserAgent = "User-Agent"
ContentType = "Content-Type"
ApplicationJSON = "application/json"
ApplicationForm = "application/x-www-form-urlencoded"
)
// HTTPResponse is basic HTTP response type
type HTTPResponse *httptest.ResponseRecorder
// HTTPRequest is basic HTTP request type
type HTTPRequest *http.Request
// ResponseFunc response handling func type
type ResponseFunc func(HTTPResponse, HTTPRequest)
// H is HTTP Header Type
type H map[string]string
// D is HTTP Data Type
type D map[string]interface{}
// RequestConfig provide user input request structure
type RequestConfig struct {
Method string
Path string
Body string
Headers H
Cookies H
Debug bool
}
// TestRequest is testing url string if server is running
func TestRequest(t *testing.T, url string) {
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}
resp, err := client.Get(url)
defer resp.Body.Close()
assert.NoError(t, err)
_, ioerr := ioutil.ReadAll(resp.Body)
assert.NoError(t, ioerr)
assert.Equal(t, "200 OK", resp.Status, "should get a 200")
}
// New supply initial structure
func New() *RequestConfig {
return &RequestConfig{}
}
// SetDebug supply enable debug mode.
func (rc *RequestConfig) SetDebug(enable bool) *RequestConfig {
rc.Debug = enable
return rc
}
// GET is request method.
func (rc *RequestConfig) GET(path string) *RequestConfig {
rc.Path = path
rc.Method = "GET"
return rc
}
// POST is request method.
func (rc *RequestConfig) POST(path string) *RequestConfig {
rc.Path = path
rc.Method = "POST"
return rc
}
// PUT is request method.
func (rc *RequestConfig) PUT(path string) *RequestConfig {
rc.Path = path
rc.Method = "PUT"
return rc
}
// DELETE is request method.
func (rc *RequestConfig) DELETE(path string) *RequestConfig {
rc.Path = path
rc.Method = "DELETE"
return rc
}
// PATCH is request method.
func (rc *RequestConfig) PATCH(path string) *RequestConfig {
rc.Path = path
rc.Method = "PATCH"
return rc
}
// HEAD is request method.
func (rc *RequestConfig) HEAD(path string) *RequestConfig {
rc.Path = path
rc.Method = "HEAD"
return rc
}
// OPTIONS is request method.
func (rc *RequestConfig) OPTIONS(path string) *RequestConfig {
rc.Path = path
rc.Method = "OPTIONS"
return rc
}
// SetHeader supply http header what you defined.
func (rc *RequestConfig) SetHeader(headers H) *RequestConfig {
if len(headers) > 0 {
rc.Headers = headers
}
return rc
}
// SetJSON supply JSON body.
func (rc *RequestConfig) SetJSON(body D) *RequestConfig {
if b, err := json.Marshal(body); err == nil {
rc.Body = string(b)
}
return rc
}
// SetForm supply form body.
func (rc *RequestConfig) SetForm(body H) *RequestConfig {
f := make(url.Values)
for k, v := range body {
f.Set(k, v)
}
rc.Body = f.Encode()
return rc
}
// SetQuery supply query string.
func (rc *RequestConfig) SetQuery(query H) *RequestConfig {
f := make(url.Values)
for k, v := range query {
f.Set(k, v)
}
if strings.Contains(rc.Path, "?") {
rc.Path = rc.Path + "&" + f.Encode()
} else {
rc.Path = rc.Path + "?" + f.Encode()
}
return rc
}
// SetBody supply raw body.
func (rc *RequestConfig) SetBody(body string) *RequestConfig {
if len(body) > 0 {
rc.Body = body
}
return rc
}
// SetCookie supply cookies what you defined.
func (rc *RequestConfig) SetCookie(cookies H) *RequestConfig {
if len(cookies) > 0 {
rc.Cookies = cookies
}
return rc
}
func (rc *RequestConfig) initTest() (*http.Request, *httptest.ResponseRecorder) {
qs := ""
if strings.Contains(rc.Path, "?") {
ss := strings.Split(rc.Path, "?")
rc.Path = ss[0]
qs = ss[1]
}
body := bytes.NewBufferString(rc.Body)
req, _ := http.NewRequest(rc.Method, rc.Path, body)
if len(qs) > 0 {
req.URL.RawQuery = qs
}
// Auto add user agent
req.Header.Set(UserAgent, "Gofight-client/"+Version)
if rc.Method == "POST" || rc.Method == "PUT" {
if strings.HasPrefix(rc.Body, "{") {
req.Header.Set(ContentType, ApplicationJSON)
} else {
req.Header.Set(ContentType, ApplicationForm)
}
}
if len(rc.Headers) > 0 {
for k, v := range rc.Headers {
req.Header.Set(k, v)
}
}
if len(rc.Cookies) > 0 {
for k, v := range rc.Cookies {
req.AddCookie(&http.Cookie{Name: k, Value: v})
}
}
if rc.Debug {
log.Printf("Request Method: %s", rc.Method)
log.Printf("Request Path: %s", rc.Path)
log.Printf("Request Body: %s", rc.Body)
log.Printf("Request Headers: %s", rc.Headers)
log.Printf("Request Cookies: %s", rc.Cookies)
log.Printf("Request Header: %s", req.Header)
}
w := httptest.NewRecorder()
return req, w
}
// Run execute http request
func (rc *RequestConfig) Run(r http.Handler, response ResponseFunc) {
req, w := rc.initTest()
r.ServeHTTP(w, req)
response(w, req)
}