You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kratos/transport/http/route_test.go

136 lines
3.1 KiB

package http
import (
"context"
"encoding/json"
"fmt"
"log"
"net/http"
"strings"
"testing"
"time"
"github.com/go-kratos/kratos/v2/internal/host"
)
type User struct {
Name string `json:"name"`
}
func authFilter(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Do stuff here
log.Println("auth:", r.Method, r.RequestURI)
// Call the next handler, which can be another middleware in the chain, or the final handler.
next.ServeHTTP(w, r)
})
}
func loggingFilter(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Do stuff here
log.Println("logging:", r.Method, r.RequestURI)
// Call the next handler, which can be another middleware in the chain, or the final handler.
next.ServeHTTP(w, r)
})
}
func TestRoute(t *testing.T) {
ctx := context.Background()
srv := NewServer(
Filter(loggingFilter),
)
route := srv.Route("/v1")
route.GET("/users/{name}", func(ctx Context) error {
u := new(User)
u.Name = ctx.Vars().Get("name")
return ctx.Result(200, u)
}, authFilter)
route.POST("/users", func(ctx Context) error {
u := new(User)
if err := ctx.Bind(u); err != nil {
return err
}
return ctx.Result(201, u)
})
route.PUT("/users", func(ctx Context) error {
u := new(User)
if err := ctx.Bind(u); err != nil {
return err
}
h := ctx.Middleware(func(ctx context.Context, in interface{}) (interface{}, error) {
return u, nil
})
return ctx.Returns(h(ctx, u))
})
if e, err := srv.Endpoint(); err != nil || e == nil {
t.Fatal(e, err)
}
go func() {
if err := srv.Start(ctx); err != nil {
panic(err)
}
}()
time.Sleep(time.Second)
testRoute(t, srv)
srv.Stop(ctx)
}
func testRoute(t *testing.T, srv *Server) {
port, ok := host.Port(srv.lis)
if !ok {
t.Fatalf("extract port error: %v", srv.lis)
}
base := fmt.Sprintf("http://127.0.0.1:%d/v1", port)
// GET
resp, err := http.Get(base + "/users/foo")
if err != nil {
t.Fatal(err)
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
t.Fatalf("code: %d", resp.StatusCode)
}
u := new(User)
if err := json.NewDecoder(resp.Body).Decode(u); err != nil {
t.Fatal(err)
}
if u.Name != "foo" {
t.Fatalf("got %s want foo", u.Name)
}
// POST
resp, err = http.Post(base+"/users", "application/json", strings.NewReader(`{"name":"bar"}`))
if err != nil {
t.Fatal(err)
}
defer resp.Body.Close()
if resp.StatusCode != 201 {
t.Fatalf("code: %d", resp.StatusCode)
}
u = new(User)
if err = json.NewDecoder(resp.Body).Decode(u); err != nil {
t.Fatal(err)
}
if u.Name != "bar" {
t.Fatalf("got %s want bar", u.Name)
}
// PUT
req, _ := http.NewRequest("PUT", base+"/users", strings.NewReader(`{"name":"bar"}`))
req.Header.Set("Content-Type", "application/json")
resp, err = http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
t.Fatalf("code: %d", resp.StatusCode)
}
u = new(User)
if err = json.NewDecoder(resp.Body).Decode(u); err != nil {
t.Fatal(err)
}
if u.Name != "bar" {
t.Fatalf("got %s want bar", u.Name)
}
}