315 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			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)
 | 
						|
}
 |