package cli import ( "log/slog" "os" "testing" "github.com/thepeterstone/claudomator/internal/config" "github.com/thepeterstone/claudomator/internal/executor" ) // TestRegisterCloudRunners_RegistersAllFiveConfiguredProviders confirms // registerCloudRunners (used identically by both `serve` and `run`) wires up // a NativeRunner for every cloud provider that has a non-empty API key — // including groq/openrouter/openai, which docs/api-keys-setup.md documented // as "works once configured" before this phase actually configured them. func TestRegisterCloudRunners_RegistersAllFiveConfiguredProviders(t *testing.T) { cfg := &config.Config{ SandboxImage: "test-image:latest", Providers: map[string]config.ProviderConfig{ "anthropic": {APIKey: "ak", DefaultModel: "claude-sonnet-5"}, "google": {APIKey: "gk", DefaultModel: "gemini-2.5-flash"}, "groq": {APIKey: "grk", Endpoint: "https://api.groq.com/openai/v1", DefaultModel: "llama-3.3-70b-versatile"}, "openrouter": {APIKey: "ork", Endpoint: "https://openrouter.ai/api/v1", DefaultModel: "meta-llama/llama-3.3-70b-instruct:free"}, "openai": {APIKey: "oak", Endpoint: "https://api.openai.com/v1", DefaultModel: "gpt-4o-mini"}, }, } runners := map[string]executor.Runner{} logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})) registerCloudRunners(runners, cfg, logger, t.TempDir()) for _, name := range []string{"anthropic", "google", "groq", "openrouter", "openai"} { r, ok := runners[name] if !ok { t.Errorf("expected a %q runner to be registered", name) continue } nr, ok := r.(*executor.NativeRunner) if !ok { t.Errorf("%q runner should be a *executor.NativeRunner", name) continue } if nr.Provider == nil { t.Errorf("%q runner has a nil Provider", name) } if nr.SandboxKind != "docker" { t.Errorf("%q runner should use SandboxKind \"docker\", got %q", name, nr.SandboxKind) } } } // TestRegisterCloudRunners_SkipsProvidersWithoutAPIKeyOrDisabled confirms // providers are skipped when unconfigured (no api_key) or explicitly // disabled via [runners], matching the anthropic/google-only behavior this // generalizes. func TestRegisterCloudRunners_SkipsProvidersWithoutAPIKeyOrDisabled(t *testing.T) { f := false cfg := &config.Config{ Providers: map[string]config.ProviderConfig{ "groq": {APIKey: "", DefaultModel: "x"}, // no key "openrouter": {APIKey: "ork", DefaultModel: "x"}, }, Runners: config.RunnersConfig{OpenRouter: &f}, // explicitly disabled } runners := map[string]executor.Runner{} logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})) registerCloudRunners(runners, cfg, logger, t.TempDir()) if _, ok := runners["groq"]; ok { t.Error("groq should not be registered without an api_key") } if _, ok := runners["openrouter"]; ok { t.Error("openrouter should not be registered when explicitly disabled") } if _, ok := runners["openai"]; ok { t.Error("openai should not be registered when absent from cfg.Providers") } }