Repository: go-kratos/kratos
Pull request #2447 (2022-10-14 03:39:47)

test(middleware/auth/jwt): add test TestNewContextAndFromContext

codecov-commenter: # [Codecov](https://codecov.io/gh/go-kratos/kratos/pull/2447?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) Report
> Merging [#2447](https://codecov.io/gh/go-kratos/kratos/pull/2447?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) (a35ee35) into [main](https://codecov.io/gh/go-kratos/kratos/commit/7a99e8bbdc01d49b6f612bdc0890a06be5402f53?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) (7a99e8b) will **decrease** coverage by `0.05%`.
> The diff coverage is `n/a`.

> :exclamation: Current head a35ee35 differs from pull request most recent head 09c30fe. Consider uploading reports for the commit 09c30fe to get more accurate results

```diff
@@            Coverage Diff             @@
##             main    #2447      +/-   ##
==========================================
- Coverage   84.95%   84.89%   -0.06%     
==========================================
  Files          88       88              
  Lines        3788     3788              
==========================================
- Hits         3218     3216       -2     
- Misses        402      404       +2     
  Partials      168      168              
```


| [Impacted Files](https://codecov.io/gh/go-kratos/kratos/pull/2447?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) | Coverage Δ | |
|---|---|---|
| [internal/context/context.go](https://codecov.io/gh/go-kratos/kratos/pull/2447/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos#diff-aW50ZXJuYWwvY29udGV4dC9jb250ZXh0Lmdv) | `97.01% <0.00%> (-2.99%)` | :arrow_down: |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos)


Patch:
diff --git a/contrib/config/etcd/README.md b/contrib/config/etcd/README.md
index d7668745..d69edd82 100644
--- a/contrib/config/etcd/README.md
+++ b/contrib/config/etcd/README.md
@@ -30,12 +30,16 @@ if err != nil {
 c := config.New(config.WithSource(source))
 defer c.Close()
 
+// load sources before get
+if err := c.Load(); err != nil {
+    log.Fatalln(err)
+}
+
 // acquire config value
 foo, err := c.Value("/app-config").String()
 if err != nil {
-    log.Println(err)
+    log.Fatalln(err)
 }
-println(foo)
 
+log.Println(foo)
 ```
-
diff --git a/middleware/metadata/metadata.go b/middleware/metadata/metadata.go
index 5c29189f..da9e43a9 100644
--- a/middleware/metadata/metadata.go
+++ b/middleware/metadata/metadata.go
@@ -51,16 +51,19 @@ func Server(opts ...Option) middleware.Middleware {
 	}
 	return func(handler middleware.Handler) middleware.Handler {
 		return func(ctx context.Context, req interface{}) (reply interface{}, err error) {
-			if tr, ok := transport.FromServerContext(ctx); ok {
-				md := options.md.Clone()
-				header := tr.RequestHeader()
-				for _, k := range header.Keys() {
-					if options.hasPrefix(k) {
-						md.Set(k, header.Get(k))
-					}
+			tr, ok := transport.FromServerContext(ctx)
+			if !ok {
+				return handler(ctx, req)
+			}
+
+			md := options.md.Clone()
+			header := tr.RequestHeader()
+			for _, k := range header.Keys() {
+				if options.hasPrefix(k) {
+					md.Set(k, header.Get(k))
 				}
-				ctx = metadata.NewServerContext(ctx, md)
 			}
+			ctx = metadata.NewServerContext(ctx, md)
 			return handler(ctx, req)
 		}
 	}
@@ -76,25 +79,28 @@ func Client(opts ...Option) middleware.Middleware {
 	}
 	return func(handler middleware.Handler) middleware.Handler {
 		return func(ctx context.Context, req interface{}) (reply interface{}, err error) {
-			if tr, ok := transport.FromClientContext(ctx); ok {
-				header := tr.RequestHeader()
-				// x-md-local-
-				for k, v := range options.md {
+			tr, ok := transport.FromClientContext(ctx)
+			if !ok {
+				return handler(ctx, req)
+			}
+
+			header := tr.RequestHeader()
+			// x-md-local-
+			for k, v := range options.md {
+				header.Set(k, v)
+			}
+			if md, ok := metadata.FromClientContext(ctx); ok {
+				for k, v := range md {
 					header.Set(k, v)
 				}
-				if md, ok := metadata.FromClientContext(ctx); ok {
-					for k, v := range md {
+			}
+			// x-md-global-
+			if md, ok := metadata.FromServerContext(ctx); ok {
+				for k, v := range md {
+					if options.hasPrefix(k) {
 						header.Set(k, v)
 					}
 				}
-				// x-md-global-
-				if md, ok := metadata.FromServerContext(ctx); ok {
-					for k, v := range md {
-						if options.hasPrefix(k) {
-							header.Set(k, v)
-						}
-					}
-				}
 			}
 			return handler(ctx, req)
 		}
diff --git a/transport/http/server.go b/transport/http/server.go
index b756a0f8..165bb99b 100644
--- a/transport/http/server.go
+++ b/transport/http/server.go
@@ -128,6 +128,13 @@ func Listener(lis net.Listener) ServerOption {
 	}
 }
 
+// PathPrefix with mux's PathPrefix, router will replaced by a subrouter that start with prefix.
+func PathPrefix(prefix string) ServerOption {
+	return func(s *Server) {
+		s.router = s.router.PathPrefix(prefix).Subrouter()
+	}
+}
+
 // Server is an HTTP server wrapper.
 type Server struct {
 	*http.Server
@@ -162,11 +169,12 @@ func NewServer(opts ...ServerOption) *Server {
 		enc:         DefaultResponseEncoder,
 		ene:         DefaultErrorEncoder,
 		strictSlash: true,
+		router:      mux.NewRouter(),
 	}
 	for _, o := range opts {
 		o(srv)
 	}
-	srv.router = mux.NewRouter().StrictSlash(srv.strictSlash)
+	srv.router.StrictSlash(srv.strictSlash)
 	srv.router.NotFoundHandler = http.DefaultServeMux
 	srv.router.MethodNotAllowedHandler = http.DefaultServeMux
 	srv.router.Use(srv.filter())


Test patch:
diff --git a/middleware/auth/jwt/jwt_test.go b/middleware/auth/jwt/jwt_test.go
index 188744b0..711757bc 100644
--- a/middleware/auth/jwt/jwt_test.go
+++ b/middleware/auth/jwt/jwt_test.go
@@ -254,7 +254,7 @@ func TestServer(t *testing.T) {
 			}
 			if test.exceptErr == nil {
 				if testToken == nil {
-					t.Errorf("except testToken not nil, but got nil")
+					t.Fatal("except testToken not nil, but got nil")
 				}
 				_, ok := testToken.(jwt.MapClaims)
 				if !ok {
@@ -493,3 +493,26 @@ func TestClientMissKey(t *testing.T) {
 		}
 	})
 }
+
+func TestNewContextAndFromContext(t *testing.T) {
+	tests := []struct {
+		name   string
+		claims jwt.MapClaims
+	}{
+		{"val not nil", jwt.MapClaims{"name": "kratos"}},
+		{"val nil", nil},
+	}
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			ctx := NewContext(context.Background(), test.claims)
+
+			claims, ok := FromContext(ctx)
+			if !ok {
+				t.Fatal("ctx not found authKey{}")
+			}
+			if !reflect.DeepEqual(test.claims, claims) {
+				t.Errorf(`want: %s, got: %v`, test.claims, claims)
+			}
+		})
+	}
+}
diff --git a/middleware/metadata/metadata_test.go b/middleware/metadata/metadata_test.go
index e46a94f5..b083f9c1 100644
--- a/middleware/metadata/metadata_test.go
+++ b/middleware/metadata/metadata_test.go
@@ -4,6 +4,7 @@ import (
 	"context"
 	"errors"
 	"net/http"
+	"reflect"
 	"testing"
 
 	"github.com/go-kratos/kratos/v2/metadata"
@@ -33,15 +34,18 @@ func (tr *testTransport) Operation() string               { return "" }
 func (tr *testTransport) RequestHeader() transport.Header { return tr.header }
 func (tr *testTransport) ReplyHeader() transport.Header   { return tr.header }
 
+var (
+	globalKey   = "x-md-global-key"
+	globalValue = "global-value"
+	localKey    = "x-md-local-key"
+	localValue  = "local-value"
+	customKey   = "x-md-local-custom"
+	customValue = "custom-value"
+	constKey    = "x-md-local-const"
+	constValue  = "x-md-local-const"
+)
+
 func TestSever(t *testing.T) {
-	var (
-		globalKey   = "x-md-global-key"
-		globalValue = "global-value"
-		localKey    = "x-md-local-key"
-		localValue  = "local-value"
-		constKey    = "x-md-local-const"
-		constValue  = "x-md-local-const"
-	)
 	hs := func(ctx context.Context, in interface{}) (interface{}, error) {
 		md, ok := metadata.FromServerContext(ctx)
 		if !ok {
@@ -75,16 +79,6 @@ func TestSever(t *testing.T) {
 }
 
 func TestClient(t *testing.T) {
-	var (
-		globalKey   = "x-md-global-key"
-		globalValue = "global-value"
-		localKey    = "x-md-local-key"
-		localValue  = "local-value"
-		customKey   = "x-md-local-custom"
-		customValue = "custom-value"
-		constKey    = "x-md-local-const"
-		constValue  = "x-md-local-const"
-	)
 	hs := func(ctx context.Context, in interface{}) (interface{}, error) {
 		tr, ok := transport.FromClientContext(ctx)
 		if !ok {
@@ -127,13 +121,52 @@ func TestClient(t *testing.T) {
 	}
 }
 
-func Test_WithPropagatedPrefix(t *testing.T) {
-	o := &options{
+func TestWithConstants(t *testing.T) {
+	md := metadata.Metadata{
+		constKey: constValue,
+	}
+	options := &options{
+		md: metadata.Metadata{
+			"override": "override",
+		},
+	}
+
+	WithConstants(md)(options)
+	if !reflect.DeepEqual(md, options.md) {
+		t.Errorf("want: %v, got: %v", md, options.md)
+	}
+}
+
+func TestOptions_WithPropagatedPrefix(t *testing.T) {
+	options := &options{
 		prefix: []string{"override"},
 	}
-	WithPropagatedPrefix("something", "another")(o)
+	prefixes := []string{"something", "another"}
 
-	if len(o.prefix) != 2 {
+	WithPropagatedPrefix(prefixes...)(options)
+	if !reflect.DeepEqual(prefixes, options.prefix) {
 		t.Error("The prefix must be overridden.")
 	}
 }
+
+func TestOptions_hasPrefix(t *testing.T) {
+	tests := []struct {
+		name    string
+		options *options
+		key     string
+		exists  bool
+	}{
+		{"exists key upper", &options{prefix: []string{"prefix"}}, "PREFIX_true", true},
+		{"exists key lower", &options{prefix: []string{"prefix"}}, "prefix_true", true},
+		{"not exists key upper", &options{prefix: []string{"prefix"}}, "false_PREFIX", false},
+		{"not exists key lower", &options{prefix: []string{"prefix"}}, "false_prefix", false},
+	}
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			exists := test.options.hasPrefix(test.key)
+			if test.exists != exists {
+				t.Errorf("key: '%sr', not exists prefixs: %v", test.key, test.options.prefix)
+			}
+		})
+	}
+}