1package config
2
3import (
4 "os"
5 "path/filepath"
6 "testing"
7
8 "github.com/charmbracelet/catwalk/pkg/catwalk"
9 "github.com/charmbracelet/crush/internal/env"
10 "github.com/stretchr/testify/require"
11)
12
13func TestIsDockerMCPEnabled(t *testing.T) {
14 t.Parallel()
15
16 t.Run("returns false when MCP is nil", func(t *testing.T) {
17 t.Parallel()
18 cfg := &Config{
19 MCP: nil,
20 }
21 require.False(t, cfg.IsDockerMCPEnabled())
22 })
23
24 t.Run("returns false when docker mcp not configured", func(t *testing.T) {
25 t.Parallel()
26 cfg := &Config{
27 MCP: make(map[string]MCPConfig),
28 }
29 require.False(t, cfg.IsDockerMCPEnabled())
30 })
31
32 t.Run("returns true when docker mcp is configured", func(t *testing.T) {
33 t.Parallel()
34 cfg := &Config{
35 MCP: map[string]MCPConfig{
36 DockerMCPName: {
37 Type: MCPStdio,
38 Command: "docker",
39 },
40 },
41 }
42 require.True(t, cfg.IsDockerMCPEnabled())
43 })
44}
45
46func TestEnableDockerMCP(t *testing.T) {
47 t.Parallel()
48
49 t.Run("adds docker mcp to config", func(t *testing.T) {
50 t.Parallel()
51
52 // Create a temporary directory for config.
53 tmpDir := t.TempDir()
54 configPath := filepath.Join(tmpDir, "crush.json")
55
56 cfg := &Config{
57 MCP: make(map[string]MCPConfig),
58 dataConfigDir: configPath,
59 resolver: NewShellVariableResolver(env.New()),
60 knownProviders: []catwalk.Provider{},
61 }
62
63 // Only run this test if docker mcp is available.
64 if !IsDockerMCPAvailable() {
65 t.Skip("Docker MCP not available, skipping test")
66 }
67
68 err := cfg.EnableDockerMCP()
69 require.NoError(t, err)
70
71 // Check in-memory config.
72 require.True(t, cfg.IsDockerMCPEnabled())
73 mcpConfig, exists := cfg.MCP[DockerMCPName]
74 require.True(t, exists)
75 require.Equal(t, MCPStdio, mcpConfig.Type)
76 require.Equal(t, "docker", mcpConfig.Command)
77 require.Equal(t, []string{"mcp", "gateway", "run"}, mcpConfig.Args)
78 require.False(t, mcpConfig.Disabled)
79
80 // Check persisted config.
81 data, err := os.ReadFile(configPath)
82 require.NoError(t, err)
83 require.Contains(t, string(data), "crush_docker")
84 require.Contains(t, string(data), "docker")
85 require.Contains(t, string(data), "gateway")
86 })
87
88 t.Run("fails when docker mcp not available", func(t *testing.T) {
89 t.Parallel()
90
91 // Create a temporary directory for config.
92 tmpDir := t.TempDir()
93 configPath := filepath.Join(tmpDir, "crush.json")
94
95 cfg := &Config{
96 MCP: make(map[string]MCPConfig),
97 dataConfigDir: configPath,
98 resolver: NewShellVariableResolver(env.New()),
99 knownProviders: []catwalk.Provider{},
100 }
101
102 // Skip if docker mcp is actually available.
103 if IsDockerMCPAvailable() {
104 t.Skip("Docker MCP is available, skipping unavailable test")
105 }
106
107 err := cfg.EnableDockerMCP()
108 require.Error(t, err)
109 require.Contains(t, err.Error(), "docker mcp is not available")
110 })
111}
112
113func TestDisableDockerMCP(t *testing.T) {
114 t.Parallel()
115
116 t.Run("removes docker mcp from config", func(t *testing.T) {
117 t.Parallel()
118
119 // Create a temporary directory for config.
120 tmpDir := t.TempDir()
121 configPath := filepath.Join(tmpDir, "crush.json")
122
123 cfg := &Config{
124 MCP: map[string]MCPConfig{
125 DockerMCPName: {
126 Type: MCPStdio,
127 Command: "docker",
128 Args: []string{"mcp", "gateway", "run"},
129 Disabled: false,
130 },
131 },
132 dataConfigDir: configPath,
133 resolver: NewShellVariableResolver(env.New()),
134 knownProviders: []catwalk.Provider{},
135 }
136
137 // Verify it's enabled first.
138 require.True(t, cfg.IsDockerMCPEnabled())
139
140 err := cfg.DisableDockerMCP()
141 require.NoError(t, err)
142
143 // Check in-memory config.
144 require.False(t, cfg.IsDockerMCPEnabled())
145 _, exists := cfg.MCP[DockerMCPName]
146 require.False(t, exists)
147 })
148
149 t.Run("does nothing when MCP is nil", func(t *testing.T) {
150 t.Parallel()
151
152 cfg := &Config{
153 MCP: nil,
154 dataConfigDir: t.TempDir() + "/crush.json",
155 resolver: NewShellVariableResolver(env.New()),
156 knownProviders: []catwalk.Provider{},
157 }
158
159 err := cfg.DisableDockerMCP()
160 require.NoError(t, err)
161 })
162}