|
6 | 6 | "context" |
7 | 7 | "encoding/json" |
8 | 8 | "errors" |
| 9 | + "net/http" |
| 10 | + "net/http/httptest" |
9 | 11 | "os" |
10 | 12 | "path/filepath" |
11 | 13 | "runtime" |
@@ -269,6 +271,52 @@ func TestExecutePlanSkipBlockedPluginExit0(t *testing.T) { |
269 | 271 | require.Error(t, err) |
270 | 272 | } |
271 | 273 |
|
| 274 | +func TestExecutePlanPluginWithUnresolvedSkillsRelease(t *testing.T) { |
| 275 | + tmp := t.TempDir() |
| 276 | + t.Setenv("DATABRICKS_SKILLS_REF", "") |
| 277 | + t.Setenv("DATABRICKS_FORCE_EMBEDDED_COMPAT", "false") |
| 278 | + t.Setenv("DATABRICKS_CACHE_ENABLED", "true") |
| 279 | + t.Setenv("DATABRICKS_CACHE_DIR", tmp) |
| 280 | + require.NoError(t, os.WriteFile(filepath.Join(tmp, "compat-manifest.json"), []byte(`{"0.0.0":{"appkit":"0.84.0","skills":"latest"}}`), 0o600)) |
| 281 | + lookups := 0 |
| 282 | + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { |
| 283 | + lookups++ |
| 284 | + w.WriteHeader(http.StatusForbidden) |
| 285 | + })) |
| 286 | + t.Cleanup(srv.Close) |
| 287 | + t.Setenv("DATABRICKS_CLI_GITHUB_API_URL", srv.URL) |
| 288 | + |
| 289 | + installRef, recordRef := "unset", "unset" |
| 290 | + orig := installPluginForAgentFn |
| 291 | + origRec := recordPluginInstallsFn |
| 292 | + origCleanup := cleanupLegacyFn |
| 293 | + t.Cleanup(func() { |
| 294 | + installPluginForAgentFn = orig |
| 295 | + recordPluginInstallsFn = origRec |
| 296 | + cleanupLegacyFn = origCleanup |
| 297 | + }) |
| 298 | + cleanupLegacyFn = func(context.Context, *agents.Agent, string) error { return nil } |
| 299 | + installPluginForAgentFn = func(_ context.Context, _ *agents.Agent, scope, ref string) (installer.PluginRecord, error) { |
| 300 | + installRef = ref |
| 301 | + return installer.PluginRecord{Plugin: "databricks", Scope: scope, Version: installer.DisplaySkillsVersion(ref)}, nil |
| 302 | + } |
| 303 | + recordPluginInstallsFn = func(_ context.Context, _ string, _ map[string]installer.PluginRecord, ref string) error { |
| 304 | + recordRef = ref |
| 305 | + return nil |
| 306 | + } |
| 307 | + |
| 308 | + claude := testPluginAgent(agents.NameClaudeCode, "Claude Code", "claude") |
| 309 | + plan := buildPlan([]*agents.Agent{claude}, installer.ScopeGlobal, false, true) |
| 310 | + outcomes, err := executePlan(cmdio.MockDiscard(t.Context()), nil, plan, installer.InstallOptions{Scope: installer.ScopeGlobal}, false) |
| 311 | + require.NoError(t, err) |
| 312 | + require.Len(t, outcomes, 1) |
| 313 | + assert.Equal(t, outcomeInstalled, outcomes[0].status) |
| 314 | + assert.Equal(t, 1, lookups) |
| 315 | + // The marketplace picks the plugin version, so a failed lookup records it as unknown. |
| 316 | + assert.Empty(t, installRef) |
| 317 | + assert.Empty(t, recordRef) |
| 318 | +} |
| 319 | + |
272 | 320 | // --- RunE: skills-only path (config-dir detection, no plugin) --- |
273 | 321 |
|
274 | 322 | func TestInstallSkillsOnlyAllAgents(t *testing.T) { |
|
0 commit comments