Files
go-admin/common/middleware/init_test.go
T
zhangwenjian be3c4452e3 test: pin the jwt handler being retrievable and shared
Two properties the previous shape broke silently: GetHandlerFunc must
report ok for the JwtToken key, and every module must read back the same
instance. Reverting the registration to the unbound method expression
still compiles and turns the first of these red, which is the failure
this pins.

Claude-Session: https://claude.ai/code/session_01HPTAw8b8tAdFNFn8rKdPYx
2026-09-05 10:26:54 +08:00

78 lines
2.8 KiB
Go

package middleware
import (
"testing"
"github.com/gin-gonic/gin"
"github.com/go-admin-team/go-admin-core/v2/sdk"
"github.com/go-admin-team/go-admin-core/v2/sdk/config"
"github.com/go-admin-team/go-admin-core/v2/sdk/runtime"
)
// freshRuntime hands the test its own Runtime and puts the old one back, the
// same pattern cmd/api/server_test.go uses: sdk.Runtime is a process-wide
// singleton, and a test that registers into it would otherwise leak state
// into every other test in the binary.
func freshRuntime(t *testing.T) {
t.Helper()
previous := sdk.Runtime
t.Cleanup(func() { sdk.Runtime = previous })
sdk.Runtime = runtime.NewConfig()
}
// TestInitMiddlewareRegistersUsableJwtHandlerFunc is the reverse proof for
// hoisting the JWT instance's construction into InitMiddleware:
// sdk.Runtime.GetHandlerFunc(JwtTokenCheck) must hand back ok=true and a
// non-nil gin.HandlerFunc, not just something GetMiddleware can return as an
// untyped interface{}.
//
// Before this change, InitMiddleware registered the unbound method
// expression (*jwt.GinJWTMiddleware).MiddlewareFunc under this key - a value
// with no receiver bound to it, which is not a gin.HandlerFunc no matter how
// a caller asserts its type. Reverting the registration below to that
// expression makes GetHandlerFunc report ok=false; it does not fail to
// compile, because (*jwt.GinJWTMiddleware).MiddlewareFunc has a well-formed,
// unrelated method-expression type that SetMiddleware's interface{} param
// happily accepts.
func TestInitMiddlewareRegistersUsableJwtHandlerFunc(t *testing.T) {
freshRuntime(t)
previousSecret := config.JwtConfig.Secret
config.JwtConfig.Secret = "test-secret-key"
t.Cleanup(func() { config.JwtConfig.Secret = previousSecret })
gin.SetMode(gin.TestMode)
InitMiddleware(gin.New())
h, ok := sdk.Runtime.GetHandlerFunc(JwtTokenCheck)
if !ok {
t.Fatal("GetHandlerFunc(JwtTokenCheck) reported ok=false after InitMiddleware ran")
}
if h == nil {
t.Fatal("GetHandlerFunc(JwtTokenCheck) reported ok=true but returned a nil handler")
}
}
// TestInitMiddlewareBuildsOneSharedJwtInstance locks down the fix for the
// four-instances problem: GetAuthMiddleware must return the very instance
// InitMiddleware built and handed to sdk.Runtime, not a lookalike built
// separately by whichever caller asks first.
func TestInitMiddlewareBuildsOneSharedJwtInstance(t *testing.T) {
freshRuntime(t)
previousSecret := config.JwtConfig.Secret
config.JwtConfig.Secret = "test-secret-key"
t.Cleanup(func() { config.JwtConfig.Secret = previousSecret })
gin.SetMode(gin.TestMode)
InitMiddleware(gin.New())
shared := GetAuthMiddleware()
if shared == nil {
t.Fatal("GetAuthMiddleware returned nil after InitMiddleware ran")
}
if shared != authMiddleware {
t.Error("GetAuthMiddleware did not return the package-level instance InitMiddleware built")
}
}