github.com/johnnyeven/libtools@v0.0.0-20191126065708-61829c1adf46/httplib/context/context.go (about)

     1  package context
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"net/http"
     7  	"reflect"
     8  
     9  	"github.com/gin-gonic/gin"
    10  
    11  	"encoding/json"
    12  )
    13  
    14  func GetTestContextBody(c *gin.Context) []byte {
    15  	if rwriter, ok := c.Writer.(*TestResponseWriter); ok {
    16  		return rwriter.Body.Bytes()
    17  	}
    18  	panic("context's writer is not TestResponseWriter")
    19  }
    20  
    21  func GetTestContextStatus(c *gin.Context) int {
    22  	return int(reflect.Indirect(reflect.ValueOf(c)).FieldByName("writermem").FieldByName("status").Int())
    23  }
    24  
    25  func UnmarshalJSONTestContextBody(c *gin.Context, resp interface{}) {
    26  	bodyBytes := GetTestContextBody(c)
    27  	err := json.Unmarshal(bodyBytes, resp)
    28  	if err != nil {
    29  		panic(fmt.Sprintf("unmashal context's body failed[err:%s]", err.Error()))
    30  	}
    31  }
    32  
    33  type RequestOpts struct {
    34  	FormData map[string]string
    35  	Query    map[string]string
    36  	Params   map[string]string
    37  	Headers  map[string]string
    38  	Context  map[string]interface{}
    39  	Body     interface{}
    40  }
    41  
    42  func (opts RequestOpts) Merge(reqOptions RequestOpts) RequestOpts {
    43  	for k, v := range reqOptions.FormData {
    44  		opts.FormData[k] = v
    45  	}
    46  	for k, v := range reqOptions.Query {
    47  		opts.Query[k] = v
    48  	}
    49  	for k, v := range reqOptions.Params {
    50  		opts.Params[k] = v
    51  	}
    52  	for k, v := range reqOptions.Headers {
    53  		opts.Headers[k] = v
    54  	}
    55  	for k, v := range reqOptions.Context {
    56  		opts.Context[k] = v
    57  	}
    58  	if reqOptions.Body != nil {
    59  		opts.Body = reqOptions.Body
    60  	}
    61  	return opts
    62  }
    63  
    64  func toRawQuery(queryMap map[string]string) string {
    65  	queryString := ""
    66  	i := 0
    67  
    68  	for k, v := range queryMap {
    69  		keyValue := k + "=" + v
    70  		if i == 0 {
    71  			queryString += "?" + keyValue
    72  		} else {
    73  			queryString += "&" + keyValue
    74  		}
    75  		i++
    76  	}
    77  
    78  	return queryString
    79  }
    80  
    81  func WithRequest(opts RequestOpts) *gin.Context {
    82  	c := gin.Context{}
    83  	rv := reflect.ValueOf(opts.Body)
    84  	var request *http.Request
    85  
    86  	if rv.Kind() == reflect.Ptr && rv.IsNil() {
    87  		request, _ = http.NewRequest("GET", "/"+toRawQuery(opts.Query), nil)
    88  	} else {
    89  		bodyBytes, _ := json.Marshal(opts.Body)
    90  		request, _ = http.NewRequest("GET", "/"+toRawQuery(opts.Query), bytes.NewBuffer(bodyBytes))
    91  	}
    92  
    93  	for k, v := range opts.Headers {
    94  		request.Header.Add(k, v)
    95  	}
    96  
    97  	for k, v := range opts.FormData {
    98  		request.PostForm.Add(k, v)
    99  	}
   100  
   101  	c.Request = request
   102  	rwriter := TestResponseWriter{}
   103  	rwriter.Body = *bytes.NewBuffer([]byte{})
   104  	c.Writer = &rwriter
   105  
   106  	params := gin.Params{}
   107  	for k, v := range opts.Params {
   108  		params = append(params, gin.Param{
   109  			Key:   k,
   110  			Value: v,
   111  		})
   112  	}
   113  	c.Params = params
   114  
   115  	for k, v := range opts.Context {
   116  		c.Set(k, v)
   117  	}
   118  
   119  	return &c
   120  }