// Copyright 2025 The Go MCP SDK Authors. All rights reserved. // Use of this source code is governed by an MIT-style // license that can be found in the LICENSE file. package auth import ( "context" "errors" "net/http" "testing" "time" ) func TestVerify(t *testing.T) { verifier := func(_ context.Context, token string, _ *http.Request) (*TokenInfo, error) { switch token { case "valid": return &TokenInfo{Expiration: time.Now().Add(time.Hour)}, nil case "invalid": return nil, ErrInvalidToken case "oauth": return nil, ErrOAuth case "noexp": return &TokenInfo{}, nil case "expired": return &TokenInfo{Expiration: time.Now().Add(-time.Hour)}, nil default: return nil, errors.New("unknown") } } for _, tt := range []struct { name string opts *RequireBearerTokenOptions header string wantMsg string wantCode int }{ { "valid", nil, "Bearer valid", "", 0, }, { "bad header", nil, "Barer valid", "no bearer token", 401, }, { "invalid", nil, "bearer invalid", "invalid token", 401, }, { "oauth error", nil, "Bearer oauth", "oauth error", 400, }, { "no expiration", nil, "Bearer noexp", "token missing expiration", 401, }, { "expired", nil, "Bearer expired", "token expired", 401, }, { "missing scope", &RequireBearerTokenOptions{Scopes: []string{"s1"}}, "Bearer valid", "insufficient scope", 403, }, } { t.Run(tt.name, func(t *testing.T) { _, gotMsg, gotCode := verify(&http.Request{ Header: http.Header{"Authorization": {tt.header}}, }, verifier, tt.opts) if gotMsg != tt.wantMsg || gotCode != tt.wantCode { t.Errorf("got (%q, %d), want (%q, %d)", gotMsg, gotCode, tt.wantMsg, tt.wantCode) } }) } }