github.com/artisanhe/tools@v1.0.1-0.20210607022958-19a8fef2eb04/httplib/context/context.go (about)

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