package workspace import ( "encoding/json" "os" "path/filepath" "runtime" "strings" "testing" ) func TestChatOnly_NoApiKey_KeepsHome(t *testing.T) { t.Setenv("CURSOR_API_KEY", "") dir, env, err := ChatOnly("") if err != nil { t.Fatalf("ChatOnly: %v", err) } t.Cleanup(func() { _ = os.RemoveAll(dir) }) if !filepath.IsAbs(dir) { t.Errorf("expected absolute path, got %q", dir) } cfgPath := filepath.Join(dir, ".cursor", "cli-config.json") data, err := os.ReadFile(cfgPath) if err != nil { t.Fatalf("expected cli-config.json to exist: %v", err) } var parsed map[string]any if err := json.Unmarshal(data, &parsed); err != nil { t.Fatalf("cli-config.json is not valid JSON: %v", err) } if env["CURSOR_CONFIG_DIR"] != filepath.Join(dir, ".cursor") { t.Errorf("CURSOR_CONFIG_DIR override wrong: %q", env["CURSOR_CONFIG_DIR"]) } if _, ok := env["HOME"]; ok { t.Errorf("HOME should NOT be overridden without CURSOR_API_KEY, got %q (would break keychain auth)", env["HOME"]) } } func TestChatOnly_WithApiKey_IsolatesHome(t *testing.T) { t.Setenv("CURSOR_API_KEY", "sk-fake-for-test") dir, env, err := ChatOnly("") if err != nil { t.Fatalf("ChatOnly: %v", err) } t.Cleanup(func() { _ = os.RemoveAll(dir) }) if env["HOME"] != dir { t.Errorf("HOME override = %q, want %q", env["HOME"], dir) } if runtime.GOOS != "windows" && env["XDG_CONFIG_HOME"] != filepath.Join(dir, ".config") { t.Errorf("XDG_CONFIG_HOME override wrong: %q", env["XDG_CONFIG_HOME"]) } } func TestChatOnly_WithAuthConfigDir_OnlySetsCursorConfigDir(t *testing.T) { dir, env, err := ChatOnly("/tmp/fake-auth") if err != nil { t.Fatalf("ChatOnly: %v", err) } t.Cleanup(func() { _ = os.RemoveAll(dir) }) if env["CURSOR_CONFIG_DIR"] != "/tmp/fake-auth" { t.Errorf("expected CURSOR_CONFIG_DIR to be the auth dir, got %q", env["CURSOR_CONFIG_DIR"]) } if _, ok := env["HOME"]; ok { t.Errorf("HOME should not be overridden when authConfigDir is set, got %q", env["HOME"]) } } func TestMergeEnv_OverridesExistingKeys(t *testing.T) { base := []string{"FOO=1", "HOME=/old", "BAR=2"} out := MergeEnv(base, map[string]string{ "HOME": "/new", "BAZ": "3", }) joined := strings.Join(out, "\n") if !strings.Contains(joined, "HOME=/new") { t.Errorf("expected HOME=/new in merged env, got: %v", out) } if strings.Contains(joined, "HOME=/old") { t.Errorf("old HOME should have been replaced, got: %v", out) } if !strings.Contains(joined, "FOO=1") || !strings.Contains(joined, "BAR=2") { t.Errorf("unchanged keys should pass through, got: %v", out) } if !strings.Contains(joined, "BAZ=3") { t.Errorf("new key should be appended, got: %v", out) } } func TestMergeEnv_EmptyOverridesReturnsSameSlice(t *testing.T) { base := []string{"FOO=1"} out := MergeEnv(base, nil) if len(out) != 1 || out[0] != "FOO=1" { t.Errorf("expected base unchanged, got %v", out) } }