|
1 | 1 | package commands |
2 | 2 |
|
3 | 3 | import ( |
4 | | - "encoding/json" |
5 | | - "os" |
6 | | - "path/filepath" |
7 | | - "strconv" |
8 | 4 | "testing" |
9 | 5 |
|
10 | 6 | "github.com/docker/cli/cli/config/configfile" |
11 | 7 | "github.com/stretchr/testify/assert" |
12 | | - "github.com/stretchr/testify/require" |
13 | 8 | ) |
14 | 9 |
|
15 | | -func TestIsFeatureEnabledTrue(t *testing.T) { |
16 | | - // Create temporary config directory |
17 | | - tempDir := t.TempDir() |
18 | | - configFile := filepath.Join(tempDir, "config.json") |
19 | | - |
20 | | - // Create config with enabled feature |
21 | | - config := map[string]any{ |
22 | | - "features": map[string]string{ |
23 | | - "configured-catalogs": "enabled", |
24 | | - }, |
25 | | - } |
26 | | - configData, err := json.Marshal(config) |
27 | | - require.NoError(t, err) |
28 | | - err = os.WriteFile(configFile, configData, 0o644) |
29 | | - require.NoError(t, err) |
30 | | - |
31 | | - // Load config file |
32 | | - configFile2 := &configfile.ConfigFile{ |
33 | | - Filename: configFile, |
34 | | - } |
35 | | - _ = configFile2.LoadFromReader(os.Stdin) // This will load from the filename |
36 | | - |
37 | | - // Test directly with Features map |
38 | | - configFile2.Features = map[string]string{ |
39 | | - "configured-catalogs": "enabled", |
40 | | - } |
41 | | - |
42 | | - enabled := isFeatureEnabled(configFile2, "configured-catalogs") |
43 | | - assert.True(t, enabled) |
44 | | -} |
45 | | - |
46 | | -func TestIsFeatureEnabledFalse(t *testing.T) { |
47 | | - configFile := &configfile.ConfigFile{ |
48 | | - Features: map[string]string{ |
49 | | - "configured-catalogs": "disabled", |
50 | | - }, |
51 | | - } |
52 | | - |
53 | | - enabled := isFeatureEnabled(configFile, "configured-catalogs") |
54 | | - assert.False(t, enabled) |
55 | | -} |
56 | | - |
57 | | -func TestIsFeatureEnabledMissing(t *testing.T) { |
58 | | - configFile := &configfile.ConfigFile{ |
59 | | - Features: make(map[string]string), |
60 | | - } |
61 | | - |
62 | | - enabled := isFeatureEnabled(configFile, "configured-catalogs") |
63 | | - assert.False(t, enabled, "missing features should default to disabled") |
| 10 | +func TestIsFeatureEnabledOAuthInterceptor(t *testing.T) { |
| 11 | + t.Run("enabled", func(t *testing.T) { |
| 12 | + configFile := &configfile.ConfigFile{ |
| 13 | + Features: map[string]string{ |
| 14 | + "oauth-interceptor": "enabled", |
| 15 | + }, |
| 16 | + } |
| 17 | + enabled := isFeatureEnabledFromConfig(configFile, "oauth-interceptor") |
| 18 | + assert.True(t, enabled) |
| 19 | + }) |
| 20 | + |
| 21 | + t.Run("disabled", func(t *testing.T) { |
| 22 | + configFile := &configfile.ConfigFile{ |
| 23 | + Features: map[string]string{ |
| 24 | + "oauth-interceptor": "disabled", |
| 25 | + }, |
| 26 | + } |
| 27 | + enabled := isFeatureEnabledFromConfig(configFile, "oauth-interceptor") |
| 28 | + assert.False(t, enabled) |
| 29 | + }) |
| 30 | + |
| 31 | + t.Run("missing", func(t *testing.T) { |
| 32 | + configFile := &configfile.ConfigFile{ |
| 33 | + Features: make(map[string]string), |
| 34 | + } |
| 35 | + enabled := isFeatureEnabledFromConfig(configFile, "oauth-interceptor") |
| 36 | + assert.False(t, enabled, "missing features should default to disabled") |
| 37 | + }) |
64 | 38 | } |
65 | 39 |
|
66 | | -func TestIsFeatureEnabledCorrupt(t *testing.T) { |
67 | | - configFile := &configfile.ConfigFile{ |
68 | | - Features: map[string]string{ |
69 | | - "configured-catalogs": "invalid-boolean", |
70 | | - }, |
71 | | - } |
72 | | - |
73 | | - enabled := isFeatureEnabled(configFile, "configured-catalogs") |
74 | | - assert.False(t, enabled, "corrupted feature values should default to disabled") |
| 40 | +func TestIsFeatureEnabledDynamicTools(t *testing.T) { |
| 41 | + t.Run("enabled", func(t *testing.T) { |
| 42 | + configFile := &configfile.ConfigFile{ |
| 43 | + Features: map[string]string{ |
| 44 | + "dynamic-tools": "enabled", |
| 45 | + }, |
| 46 | + } |
| 47 | + enabled := isFeatureEnabledFromConfig(configFile, "dynamic-tools") |
| 48 | + assert.True(t, enabled) |
| 49 | + }) |
| 50 | + |
| 51 | + t.Run("disabled", func(t *testing.T) { |
| 52 | + configFile := &configfile.ConfigFile{ |
| 53 | + Features: map[string]string{ |
| 54 | + "dynamic-tools": "disabled", |
| 55 | + }, |
| 56 | + } |
| 57 | + enabled := isFeatureEnabledFromConfig(configFile, "dynamic-tools") |
| 58 | + assert.False(t, enabled) |
| 59 | + }) |
| 60 | + |
| 61 | + t.Run("missing", func(t *testing.T) { |
| 62 | + configFile := &configfile.ConfigFile{ |
| 63 | + Features: make(map[string]string), |
| 64 | + } |
| 65 | + enabled := isFeatureEnabledFromConfig(configFile, "dynamic-tools") |
| 66 | + assert.False(t, enabled, "missing features should default to disabled") |
| 67 | + }) |
75 | 68 | } |
76 | 69 |
|
77 | | -func TestEnableFeature(t *testing.T) { |
78 | | - // Create temporary config directory |
79 | | - tempDir := t.TempDir() |
80 | | - configPath := filepath.Join(tempDir, "config.json") |
81 | | - |
82 | | - // Create initial config |
83 | | - configFile := &configfile.ConfigFile{ |
84 | | - Filename: configPath, |
85 | | - Features: make(map[string]string), |
86 | | - } |
87 | | - |
88 | | - // Test enabling configured-catalogs feature |
89 | | - err := enableFeature(configFile, "configured-catalogs") |
90 | | - require.NoError(t, err) |
91 | | - |
92 | | - // Verify feature was enabled |
93 | | - enabled := isFeatureEnabled(configFile, "configured-catalogs") |
94 | | - assert.True(t, enabled, "configured-catalogs feature should be enabled") |
95 | | -} |
96 | | - |
97 | | -func TestDisableFeature(t *testing.T) { |
98 | | - // Create temporary config directory |
99 | | - tempDir := t.TempDir() |
100 | | - configPath := filepath.Join(tempDir, "config.json") |
101 | | - |
102 | | - // Create config with feature already enabled |
103 | | - configFile := &configfile.ConfigFile{ |
104 | | - Filename: configPath, |
105 | | - Features: map[string]string{ |
106 | | - "configured-catalogs": "enabled", |
107 | | - }, |
108 | | - } |
109 | | - |
110 | | - // Test disabling configured-catalogs feature |
111 | | - err := disableFeature(configFile, "configured-catalogs") |
112 | | - require.NoError(t, err) |
113 | | - |
114 | | - // Verify feature was disabled |
115 | | - enabled := isFeatureEnabled(configFile, "configured-catalogs") |
116 | | - assert.False(t, enabled, "configured-catalogs feature should be disabled") |
117 | | -} |
118 | | - |
119 | | -func TestListFeatures(t *testing.T) { |
120 | | - // Create config with mixed features |
121 | | - configFile := &configfile.ConfigFile{ |
122 | | - Features: map[string]string{ |
123 | | - "configured-catalogs": "enabled", |
124 | | - "other-feature": "disabled", |
125 | | - }, |
126 | | - } |
127 | | - |
128 | | - // Test listing features |
129 | | - features := listFeatures(configFile) |
130 | | - |
131 | | - // Should contain our feature with correct status |
132 | | - assert.Contains(t, features, "configured-catalogs") |
133 | | - assert.Contains(t, features, "other-feature") |
134 | | - assert.Equal(t, "enabled", features["configured-catalogs"]) |
135 | | - assert.Equal(t, "disabled", features["other-feature"]) |
136 | | -} |
137 | | - |
138 | | -func TestInvalidFeature(t *testing.T) { |
139 | | - configFile := &configfile.ConfigFile{ |
140 | | - Features: make(map[string]string), |
141 | | - } |
142 | | - |
143 | | - // Test enabling invalid feature |
144 | | - err := enableFeature(configFile, "invalid-feature") |
145 | | - require.Error(t, err, "should reject invalid feature names") |
146 | | - assert.Contains(t, err.Error(), "unknown feature") |
147 | | -} |
148 | | - |
149 | | -// Feature management functions that need to be implemented |
150 | | -func enableFeature(configFile *configfile.ConfigFile, feature string) error { |
151 | | - // Validate feature name |
152 | | - if !isKnownFeature(feature) { |
153 | | - return &featureError{feature: feature, message: "unknown feature"} |
154 | | - } |
155 | | - |
156 | | - // Enable the feature |
157 | | - if configFile.Features == nil { |
158 | | - configFile.Features = make(map[string]string) |
159 | | - } |
160 | | - configFile.Features[feature] = "enabled" |
161 | | - |
162 | | - // Save config file |
163 | | - return configFile.Save() |
164 | | -} |
165 | | - |
166 | | -func disableFeature(configFile *configfile.ConfigFile, feature string) error { |
167 | | - // Validate feature name |
168 | | - if !isKnownFeature(feature) { |
169 | | - return &featureError{feature: feature, message: "unknown feature"} |
170 | | - } |
171 | | - |
172 | | - // Disable the feature |
173 | | - if configFile.Features == nil { |
174 | | - configFile.Features = make(map[string]string) |
175 | | - } |
176 | | - configFile.Features[feature] = "disabled" |
177 | | - |
178 | | - // Save config file |
179 | | - return configFile.Save() |
180 | | -} |
181 | | - |
182 | | -func listFeatures(configFile *configfile.ConfigFile) map[string]string { |
183 | | - if configFile.Features == nil { |
184 | | - return make(map[string]string) |
185 | | - } |
186 | | - |
187 | | - // Return copy of features map |
188 | | - result := make(map[string]string) |
189 | | - for k, v := range configFile.Features { |
190 | | - result[k] = v |
191 | | - } |
192 | | - return result |
193 | | -} |
194 | | - |
195 | | -func isFeatureEnabled(configFile *configfile.ConfigFile, _ string) bool { |
196 | | - if configFile.Features == nil { |
197 | | - return false |
198 | | - } |
199 | | - |
200 | | - value, exists := configFile.Features["configured-catalogs"] |
201 | | - if !exists { |
202 | | - return false |
203 | | - } |
204 | | - |
205 | | - // Handle both boolean string values and "enabled"/"disabled" strings |
206 | | - if value == "enabled" { |
207 | | - return true |
208 | | - } |
209 | | - if value == "disabled" { |
210 | | - return false |
211 | | - } |
212 | | - |
213 | | - // Fallback to parsing as boolean |
214 | | - enabled, err := strconv.ParseBool(value) |
215 | | - return err == nil && enabled |
216 | | -} |
217 | | - |
218 | | -// Feature error type |
219 | | -type featureError struct { |
220 | | - feature string |
221 | | - message string |
222 | | -} |
| 70 | +func TestIsKnownFeature(t *testing.T) { |
| 71 | + // Test valid features |
| 72 | + assert.True(t, isKnownFeature("oauth-interceptor")) |
| 73 | + assert.True(t, isKnownFeature("dynamic-tools")) |
223 | 74 |
|
224 | | -func (e *featureError) Error() string { |
225 | | - return e.message + ": " + e.feature |
| 75 | + // Test invalid features |
| 76 | + assert.False(t, isKnownFeature("invalid-feature")) |
| 77 | + assert.False(t, isKnownFeature("configured-catalogs")) // No longer supported |
| 78 | + assert.False(t, isKnownFeature("")) |
226 | 79 | } |
0 commit comments