返回 DeepSeek-Reasonix
mcp_oauth_test.go
根目录 / internal / cli / mcp_oauth_test.go
1 package cli
2
3 import (
4 "context"
5 "path/filepath"
6 "strings"
7 "testing"
8
9 "reasonix/internal/config"
10 "reasonix/internal/plugin"
11 )
12
13 func TestMCPAuthCLIUsesReasonixPrivateState(t *testing.T) {
14 home, workspace := t.TempDir(), t.TempDir()
15 t.Setenv("REASONIX_HOME", home)
16 t.Chdir(workspace)
17 entry := config.PluginEntry{Name: "figma", Type: "http", URL: "https://mcp.figma.com/mcp", Source: config.MCPSourceUserConfig}
18 if _, err := config.InstallUserPluginForRoot(workspace, entry, true); err != nil {
19 t.Fatal(err)
20 }
21
22 previous := mcpAuthorizeForCLI
23 mcpAuthorizeForCLI = func(_ context.Context, spec plugin.Spec, openURL func(string) error) error {
24 if spec.Name != "figma" || spec.URL != entry.URL {
25 t.Fatalf("authorization spec = %+v", spec)
26 }
27 if spec.StateDir == "" || strings.HasPrefix(filepath.Clean(spec.StateDir), filepath.Clean(workspace)+string(filepath.Separator)) {
28 t.Fatalf("OAuth state dir must be private Reasonix state, got %q", spec.StateDir)
29 }
30 if spec.OAuthHTTPClient == nil || openURL == nil {
31 t.Fatal("authorization requires the proxy-aware client and browser opener")
32 }
33 return nil
34 }
35 t.Cleanup(func() { mcpAuthorizeForCLI = previous })
36 if code := mcpAuthCLI([]string{"figma"}); code != 0 {
37 t.Fatalf("mcp auth exit = %d", code)
38 }
39 }
40
41 func TestMCPAuthCLIRejectsIneligibleConfigurations(t *testing.T) {
42 tests := []struct {
43 name string
44 entry config.PluginEntry
45 }{
46 {name: "stdio", entry: config.PluginEntry{Name: "server", Type: "stdio", Command: "server-mcp"}},
47 {name: "legacy SSE", entry: config.PluginEntry{Name: "server", Type: "sse", URL: "https://mcp.example.test/sse"}},
48 {name: "static authentication", entry: config.PluginEntry{
49 Name: "server", Type: "http", URL: "https://mcp.example.test/mcp",
50 Headers: map[string]string{"Authorization": "Bearer configured"},
51 }},
52 }
53 for _, tc := range tests {
54 t.Run(tc.name, func(t *testing.T) {
55 isolateCLIConfigHome(t)
56 workspace := t.TempDir()
57 t.Chdir(workspace)
58 tc.entry.Source = config.MCPSourceUserConfig
59 if _, err := config.InstallUserPluginForRoot(workspace, tc.entry, true); err != nil {
60 t.Fatal(err)
61 }
62
63 called := false
64 previous := mcpAuthorizeForCLI
65 mcpAuthorizeForCLI = func(context.Context, plugin.Spec, func(string) error) error {
66 called = true
67 return nil
68 }
69 t.Cleanup(func() { mcpAuthorizeForCLI = previous })
70 if code := mcpAuthCLI([]string{"server"}); code == 0 {
71 t.Fatal("mcp auth unexpectedly accepted an ineligible server")
72 }
73 if called {
74 t.Fatal("ineligible server reached the OAuth implementation")
75 }
76 })
77 }
78 }
79
79 lines GO