Files
zero/internal/cli/setup_test.go
Anandan d1c5af7392 Polish model status and reasoning streams (#190)
* Polish model status and reasoning streams

* Polish custom provider setup flow

* Clean up pending composer hints

* Address custom provider setup review

* Polish composer overflow handling

* Fix composer paste and wheel edge cases

* Use line counts for paste previews

* Revert "Use line counts for paste previews"

This reverts commit 4feb814d09.

* Fix composer paste preview deletion

* Disable textinput ctrl-v paste binding

* Preserve paste previews through file suggestions

* Clarify composer paste preview behavior

* Keep OpenAI reasoning out of answer text
2026-06-13 22:40:32 +05:30

222 lines
6.4 KiB
Go

package cli
import (
"path/filepath"
"reflect"
"testing"
"github.com/Gitlawb/zero/internal/config"
"github.com/Gitlawb/zero/internal/providercatalog"
"github.com/Gitlawb/zero/internal/tui"
)
func TestSetupMissingCredentialEnv(t *testing.T) {
tests := []struct {
name string
profile config.ProviderProfile
wantEnv string
want bool
}{
{
name: "catalog provider",
profile: config.ProviderProfile{
Name: "groq",
CatalogID: "groq",
},
wantEnv: "GROQ_API_KEY",
want: true,
},
{
name: "openai compatible without catalog",
profile: config.ProviderProfile{
Name: "custom",
ProviderKind: config.ProviderKindOpenAICompatible,
},
wantEnv: "OPENAI_API_KEY",
want: true,
},
{
name: "local provider",
profile: config.ProviderProfile{
Name: "local",
CatalogID: "ollama",
},
want: false,
},
{
name: "ollama cloud provider",
profile: config.ProviderProfile{
Name: "ollama-cloud",
CatalogID: "ollama-cloud",
},
wantEnv: "OLLAMA_API_KEY",
want: true,
},
{
name: "credential resolved",
profile: config.ProviderProfile{
Name: "openai",
ProviderKind: config.ProviderKindOpenAI,
APIKey: "sk-test",
},
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotEnv, got := setupMissingCredentialEnv(tt.profile)
if got != tt.want || gotEnv != tt.wantEnv {
t.Fatalf("setupMissingCredentialEnv() = (%q, %v), want (%q, %v)", gotEnv, got, tt.wantEnv, tt.want)
}
})
}
}
func TestSetupProviderOptionsUseRuntimeSupportedCatalog(t *testing.T) {
options := setupProviderOptions()
got := make([]string, 0, len(options))
for _, option := range options {
got = append(got, option.ID)
}
want := make([]string, 0)
for _, descriptor := range providercatalog.All() {
if providercatalog.RuntimeSupported(descriptor) {
want = append(want, descriptor.ID)
}
}
if !reflect.DeepEqual(got, want) {
t.Fatalf("setupProviderOptions IDs = %#v, want runtime-supported catalog IDs %#v", got, want)
}
for _, excluded := range []string{"bedrock", "vertex"} {
for _, id := range got {
if id == excluded {
t.Fatalf("setupProviderOptions included unsupported provider %q in %#v", excluded, got)
}
}
}
}
func TestSaveSetupProviderStoresPastedAPIKey(t *testing.T) {
configPath := filepath.Join(t.TempDir(), "zero", "config.json")
result, err := saveSetupProvider(appDeps{
userConfigPath: func() (string, error) {
return configPath, nil
},
}, tui.SetupSelection{
CatalogID: "ollama-cloud",
Model: "qwen3-coder:480b",
APIKey: "sk-pasted-secret",
}, setupSaveOptions{})
if err != nil {
t.Fatalf("saveSetupProvider() error = %v", err)
}
if result.Provider.APIKey != "sk-pasted-secret" {
t.Fatalf("Provider.APIKey = %q, want pasted key", result.Provider.APIKey)
}
if result.Provider.APIKeyEnv != "" {
t.Fatalf("Provider.APIKeyEnv = %q, want empty when API key is pasted", result.Provider.APIKeyEnv)
}
cfg := readFileConfig(t, configPath)
if cfg.ActiveProvider != "ollama-cloud" {
t.Fatalf("ActiveProvider = %q, want ollama-cloud", cfg.ActiveProvider)
}
if len(cfg.Providers) != 1 {
t.Fatalf("Providers = %#v, want one provider", cfg.Providers)
}
if cfg.Providers[0].APIKey != "sk-pasted-secret" || cfg.Providers[0].APIKeyEnv != "" {
t.Fatalf("stored provider credentials = APIKey %q APIKeyEnv %q, want pasted key only", cfg.Providers[0].APIKey, cfg.Providers[0].APIKeyEnv)
}
}
func TestSaveSetupProviderStoresCustomEndpointSelection(t *testing.T) {
configPath := filepath.Join(t.TempDir(), "zero", "config.json")
result, err := saveSetupProvider(appDeps{
userConfigPath: func() (string, error) {
return configPath, nil
},
}, tui.SetupSelection{
CatalogID: "custom-openai-compatible",
Name: "minimax",
BaseURL: "https://api.minimax.io/v1",
Model: "MiniMax-M3",
}, setupSaveOptions{})
if err != nil {
t.Fatalf("saveSetupProvider() error = %v", err)
}
if result.Provider.Name != "minimax" {
t.Fatalf("Provider.Name = %q, want minimax", result.Provider.Name)
}
if result.Provider.BaseURL != "https://api.minimax.io/v1" {
t.Fatalf("Provider.BaseURL = %q, want custom endpoint", result.Provider.BaseURL)
}
if result.Provider.Model != "MiniMax-M3" {
t.Fatalf("Provider.Model = %q, want typed model", result.Provider.Model)
}
cfg := readFileConfig(t, configPath)
if cfg.ActiveProvider != "minimax" {
t.Fatalf("ActiveProvider = %q, want minimax", cfg.ActiveProvider)
}
if len(cfg.Providers) != 1 {
t.Fatalf("Providers = %#v, want one provider", cfg.Providers)
}
profile := cfg.Providers[0]
if profile.Name != "minimax" || profile.CatalogID != "custom-openai-compatible" {
t.Fatalf("stored provider identity = %#v, want minimax custom-openai-compatible", profile)
}
if profile.BaseURL != "https://api.minimax.io/v1" || profile.Model != "MiniMax-M3" {
t.Fatalf("stored provider endpoint/model = %#v", profile)
}
}
func TestSaveSetupProviderCLIOptionsOverrideCustomEndpointSelection(t *testing.T) {
configPath := filepath.Join(t.TempDir(), "zero", "config.json")
result, err := saveSetupProvider(appDeps{
userConfigPath: func() (string, error) {
return configPath, nil
},
}, tui.SetupSelection{
CatalogID: "custom-openai-compatible",
Name: "selection-name",
BaseURL: "https://selection.example/v1",
Model: "selection-model",
}, setupSaveOptions{
name: "cli-name",
baseURL: "https://cli.example/v1",
})
if err != nil {
t.Fatalf("saveSetupProvider() error = %v", err)
}
if result.Provider.Name != "cli-name" {
t.Fatalf("Provider.Name = %q, want CLI name", result.Provider.Name)
}
if result.Provider.BaseURL != "https://cli.example/v1" {
t.Fatalf("Provider.BaseURL = %q, want CLI endpoint", result.Provider.BaseURL)
}
if result.Provider.Model != "selection-model" {
t.Fatalf("Provider.Model = %q, want selection model", result.Provider.Model)
}
cfg := readFileConfig(t, configPath)
if cfg.ActiveProvider != "cli-name" {
t.Fatalf("ActiveProvider = %q, want cli-name", cfg.ActiveProvider)
}
if len(cfg.Providers) != 1 {
t.Fatalf("Providers = %#v, want one provider", cfg.Providers)
}
profile := cfg.Providers[0]
if profile.Name != "cli-name" || profile.BaseURL != "https://cli.example/v1" || profile.Model != "selection-model" {
t.Fatalf("stored provider = %#v, want CLI name/baseURL and selection model", profile)
}
}