返回 DeepSeek-Reasonix
mcp_remove_test.go
根目录 / internal / cli / mcp_remove_test.go
1 package cli
2
3 import (
4 "errors"
5 "os"
6 "path/filepath"
7 "testing"
8
9 "reasonix/internal/config"
10 "reasonix/internal/plugin"
11 )
12
13 func TestMCPRemoveCLIClearsReasonixOAuthState(t *testing.T) {
14 isolateCLIConfigHome(t)
15 workspace := t.TempDir()
16 t.Chdir(workspace)
17 entry := config.PluginEntry{
18 Name: "figma", Type: "http", URL: "https://mcp.figma.com/mcp", Source: config.MCPSourceUserConfig,
19 }
20 if _, err := config.InstallUserPluginForRoot(workspace, entry, true); err != nil {
21 t.Fatal(err)
22 }
23 oauthState := writeCLIAuthState(t, workspace, entry.Name, entry.URL)
24
25 if code := mcpRemoveCLI([]string{entry.Name}); code != 0 {
26 t.Fatalf("mcp remove exit = %d", code)
27 }
28 if _, err := os.Stat(oauthState); !errors.Is(err, os.ErrNotExist) {
29 t.Fatalf("OAuth state still exists after CLI removal: %v", err)
30 }
31 }
32
33 func TestMCPRemoveCLIPreservesOAuthStateForMatchingFallback(t *testing.T) {
34 isolateCLIConfigHome(t)
35 workspace := t.TempDir()
36 t.Chdir(workspace)
37 const resource = "https://mcp.example.test/mcp"
38 global := config.PluginEntry{
39 Name: "shared", Type: "http", URL: resource, Source: config.MCPSourceUserConfig,
40 }
41 if _, err := config.InstallUserPluginForRoot(workspace, global, true); err != nil {
42 t.Fatal(err)
43 }
44 projectConfig := minimalTestModelTOML + `
45 [[plugins]]
46 name = "shared"
47 type = "http"
48 url = "https://mcp.example.test/mcp"
49 `
50 if err := os.WriteFile(filepath.Join(workspace, "reasonix.toml"), []byte(projectConfig), 0o644); err != nil {
51 t.Fatal(err)
52 }
53 oauthState := writeCLIAuthState(t, workspace, global.Name, resource)
54
55 if code := mcpRemoveCLI([]string{global.Name}); code != 0 {
56 t.Fatalf("mcp remove exit = %d", code)
57 }
58 if _, err := os.Stat(oauthState); err != nil {
59 t.Fatalf("matching fallback OAuth state was removed: %v", err)
60 }
61 }
62
63 func writeCLIAuthState(t *testing.T, workspace, name, resource string) string {
64 t.Helper()
65 stateDir := plugin.MCPStateDir(config.ReasonixHomeDir(), workspace, name)
66 if err := os.MkdirAll(stateDir, 0o700); err != nil {
67 t.Fatal(err)
68 }
69 path := filepath.Join(stateDir, "oauth.json")
70 raw := []byte(`{"version":1,"resource":"` + resource + `","access_token":"private"}`)
71 if err := os.WriteFile(path, raw, 0o600); err != nil {
72 t.Fatal(err)
73 }
74 return path
75 }
76
76 lines GO