github.com/lingyao2333/mo-zero@v1.4.1/rest/httpc/requests_test.go (about)

     1  package httpc
     2  
     3  import (
     4  	"context"
     5  	"net/http"
     6  	"net/http/httptest"
     7  	"net/http/httptrace"
     8  	"testing"
     9  
    10  	ztrace "github.com/lingyao2333/mo-zero/core/trace"
    11  	"github.com/lingyao2333/mo-zero/rest/httpx"
    12  	"github.com/lingyao2333/mo-zero/rest/internal/header"
    13  	"github.com/lingyao2333/mo-zero/rest/router"
    14  	"github.com/stretchr/testify/assert"
    15  	"go.opentelemetry.io/otel/trace"
    16  )
    17  
    18  func TestDoRequest(t *testing.T) {
    19  	ztrace.StartAgent(ztrace.Config{
    20  		Name:     "go-zero-test",
    21  		Endpoint: "http://localhost:14268/api/traces",
    22  		Batcher:  "jaeger",
    23  		Sampler:  1.0,
    24  	})
    25  	defer ztrace.StopAgent()
    26  
    27  	svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    28  	}))
    29  	defer svr.Close()
    30  	req, err := http.NewRequest(http.MethodGet, svr.URL, nil)
    31  	assert.Nil(t, err)
    32  	resp, err := DoRequest(req)
    33  	assert.Nil(t, err)
    34  	assert.Equal(t, http.StatusOK, resp.StatusCode)
    35  	spanContext := trace.SpanContextFromContext(resp.Request.Context())
    36  	assert.True(t, spanContext.IsValid())
    37  }
    38  
    39  func TestDoRequest_NotFound(t *testing.T) {
    40  	svr := httptest.NewServer(http.NotFoundHandler())
    41  	defer svr.Close()
    42  	req, err := http.NewRequest(http.MethodPost, svr.URL, nil)
    43  	assert.Nil(t, err)
    44  	req.Header.Set(header.ContentType, header.JsonContentType)
    45  	resp, err := DoRequest(req)
    46  	assert.Nil(t, err)
    47  	assert.Equal(t, http.StatusNotFound, resp.StatusCode)
    48  }
    49  
    50  func TestDoRequest_Moved(t *testing.T) {
    51  	svr := httptest.NewServer(http.RedirectHandler("/foo", http.StatusMovedPermanently))
    52  	defer svr.Close()
    53  	req, err := http.NewRequest(http.MethodGet, svr.URL, nil)
    54  	assert.Nil(t, err)
    55  	_, err = DoRequest(req)
    56  	// too many redirects
    57  	assert.NotNil(t, err)
    58  }
    59  
    60  func TestDo(t *testing.T) {
    61  	type Data struct {
    62  		Key    string `path:"key"`
    63  		Value  int    `form:"value"`
    64  		Header string `header:"X-Header"`
    65  		Body   string `json:"body"`
    66  	}
    67  
    68  	rt := router.NewRouter()
    69  	err := rt.Handle(http.MethodPost, "/nodes/:key",
    70  		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    71  			var req Data
    72  			assert.Nil(t, httpx.Parse(r, &req))
    73  		}))
    74  	assert.Nil(t, err)
    75  
    76  	svr := httptest.NewServer(http.HandlerFunc(rt.ServeHTTP))
    77  	defer svr.Close()
    78  
    79  	data := Data{
    80  		Key:    "foo",
    81  		Value:  10,
    82  		Header: "my-header",
    83  		Body:   "my body",
    84  	}
    85  	resp, err := Do(context.Background(), http.MethodPost, svr.URL+"/nodes/:key", data)
    86  	assert.Nil(t, err)
    87  	assert.Equal(t, http.StatusOK, resp.StatusCode)
    88  }
    89  
    90  func TestDo_Ptr(t *testing.T) {
    91  	type Data struct {
    92  		Key    string `path:"key"`
    93  		Value  int    `form:"value"`
    94  		Header string `header:"X-Header"`
    95  		Body   string `json:"body"`
    96  	}
    97  
    98  	rt := router.NewRouter()
    99  	err := rt.Handle(http.MethodPost, "/nodes/:key",
   100  		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   101  			var req Data
   102  			assert.Nil(t, httpx.Parse(r, &req))
   103  			assert.Equal(t, "foo", req.Key)
   104  			assert.Equal(t, 10, req.Value)
   105  			assert.Equal(t, "my-header", req.Header)
   106  			assert.Equal(t, "my body", req.Body)
   107  		}))
   108  	assert.Nil(t, err)
   109  
   110  	svr := httptest.NewServer(http.HandlerFunc(rt.ServeHTTP))
   111  	defer svr.Close()
   112  
   113  	data := &Data{
   114  		Key:    "foo",
   115  		Value:  10,
   116  		Header: "my-header",
   117  		Body:   "my body",
   118  	}
   119  	resp, err := Do(context.Background(), http.MethodPost, svr.URL+"/nodes/:key", data)
   120  	assert.Nil(t, err)
   121  	assert.Equal(t, http.StatusOK, resp.StatusCode)
   122  }
   123  
   124  func TestDo_BadRequest(t *testing.T) {
   125  	_, err := Do(context.Background(), http.MethodPost, ":/nodes/:key", nil)
   126  	assert.NotNil(t, err)
   127  
   128  	val1 := struct {
   129  		Value string `json:"value,options=[a,b]"`
   130  	}{
   131  		Value: "c",
   132  	}
   133  	_, err = Do(context.Background(), http.MethodPost, "/nodes/:key", val1)
   134  	assert.NotNil(t, err)
   135  
   136  	val2 := struct {
   137  		Value string `path:"val"`
   138  	}{
   139  		Value: "",
   140  	}
   141  	_, err = Do(context.Background(), http.MethodPost, "/nodes/:key", val2)
   142  	assert.NotNil(t, err)
   143  
   144  	val3 := struct {
   145  		Value string `path:"key"`
   146  		Body  string `json:"body"`
   147  	}{
   148  		Value: "foo",
   149  	}
   150  	_, err = Do(context.Background(), http.MethodGet, "/nodes/:key", val3)
   151  	assert.NotNil(t, err)
   152  
   153  	_, err = Do(context.Background(), "\n", "rtmp://nodes", nil)
   154  	assert.NotNil(t, err)
   155  
   156  	val4 := struct {
   157  		Value string `path:"val"`
   158  	}{
   159  		Value: "",
   160  	}
   161  	_, err = Do(context.Background(), http.MethodPost, "/nodes/:val", val4)
   162  	assert.NotNil(t, err)
   163  
   164  	val5 := struct {
   165  		Value   string `path:"val"`
   166  		Another int    `path:"foo"`
   167  	}{
   168  		Value:   "1",
   169  		Another: 2,
   170  	}
   171  	_, err = Do(context.Background(), http.MethodPost, "/nodes/:val", val5)
   172  	assert.NotNil(t, err)
   173  }
   174  
   175  func TestDo_Json(t *testing.T) {
   176  	type Data struct {
   177  		Key    string   `path:"key"`
   178  		Value  int      `form:"value"`
   179  		Header string   `header:"X-Header"`
   180  		Body   chan int `json:"body"`
   181  	}
   182  
   183  	rt := router.NewRouter()
   184  	err := rt.Handle(http.MethodPost, "/nodes/:key",
   185  		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   186  			var req Data
   187  			assert.Nil(t, httpx.Parse(r, &req))
   188  		}))
   189  	assert.Nil(t, err)
   190  
   191  	svr := httptest.NewServer(http.HandlerFunc(rt.ServeHTTP))
   192  	defer svr.Close()
   193  
   194  	data := Data{
   195  		Key:    "foo",
   196  		Value:  10,
   197  		Header: "my-header",
   198  		Body:   make(chan int),
   199  	}
   200  	_, err = Do(context.Background(), http.MethodPost, svr.URL+"/nodes/:key", data)
   201  	assert.NotNil(t, err)
   202  }
   203  
   204  func TestDo_WithClientHttpTrace(t *testing.T) {
   205  	svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
   206  	defer svr.Close()
   207  
   208  	_, err := Do(httptrace.WithClientTrace(context.Background(),
   209  		&httptrace.ClientTrace{
   210  			DNSStart: func(info httptrace.DNSStartInfo) {
   211  				assert.Equal(t, "localhost", info.Host)
   212  			},
   213  		}), http.MethodGet, svr.URL, nil)
   214  	assert.Nil(t, err)
   215  
   216  }