diff --git a/cmd/ask_test.go b/cmd/ask_test.go index b606482..29b4b16 100644 --- a/cmd/ask_test.go +++ b/cmd/ask_test.go @@ -1,8 +1,11 @@ package cmd import ( + "os" + "path/filepath" "testing" + "github.com/spf13/viper" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -40,27 +43,34 @@ func TestAskCommand_RequiresDescription(t *testing.T) { } func TestAskCommand_FailsWhenNoProvider(t *testing.T) { - // Clear all API key env vars so config.Load() returns a noop provider. - t.Setenv("ANTHROPIC_API_KEY", "") - t.Setenv("OPENAI_API_KEY", "") - t.Setenv("GEMINI_API_KEY", "") - // NoopProvider.IsAvailable() returns false → Generator.Generate returns error. + // Reset viper and set noop provider — prior tests may have loaded ~/.caseforge.yaml + // via rootCmd.Execute(), leaving a real API key in viper's state. + viper.Reset() + t.Cleanup(func() { viper.Reset() }) + viper.Set("ai.provider", "noop") + err := runAsk(askCmd, []string{"POST /users - create user"}) require.Error(t, err) assert.Contains(t, err.Error(), "AI provider") } func TestAskCommand_Integration_NoProvider(t *testing.T) { - // Clear env so no real LLM is configured. - t.Setenv("ANTHROPIC_API_KEY", "") - t.Setenv("OPENAI_API_KEY", "") - t.Setenv("GEMINI_API_KEY", "") + // Use a temp config with provider=noop so initConfig() doesn't pick up + // the real ~/.caseforge.yaml (which may have a real API key). + tmpCfg := filepath.Join(t.TempDir(), ".caseforge.yaml") + require.NoError(t, os.WriteFile(tmpCfg, []byte("ai:\n provider: noop\n"), 0600)) + + viper.Reset() + t.Cleanup(func() { + viper.Reset() + cfgFile = "" // prevent stale temp path from leaking into subsequent rootCmd.Execute() calls + }) outDir := t.TempDir() t.Cleanup(func() { rootCmd.SetArgs(nil) }) - rootCmd.SetArgs([]string{"ask", "--output", outDir, "POST /users create user"}) + rootCmd.SetArgs([]string{"ask", "--config", tmpCfg, "--output", outDir, "POST /users create user"}) err := rootCmd.Execute() - // With no provider configured, we expect an "AI provider" error. + // With noop provider, Generator.Generate returns "AI provider" error. require.Error(t, err) assert.Contains(t, err.Error(), "AI provider") } diff --git a/scripts/acceptance.sh b/scripts/acceptance.sh index 7b165d2..e9801c4 100755 --- a/scripts/acceptance.sh +++ b/scripts/acceptance.sh @@ -1503,8 +1503,10 @@ contains "AT-233" "conformance --spec required" "required flag" \ "$BIN conformance --target http://localhost:8080 2>&1 || true" contains "AT-234" "conformance --target required" "required flag" \ "(cd $REPO_ROOT && $BIN conformance --spec cmd/testdata/crud.yaml 2>&1 || true)" +NOPROV_CFG="$WORKDIR/caseforge-noprov.yaml" +printf 'ai:\n provider: noop\n' > "$NOPROV_CFG" contains "AT-235" "conformance no LLM fails gracefully" "LLM provider not available" \ - "(cd $REPO_ROOT && $BIN conformance --spec cmd/testdata/crud.yaml --target http://localhost:8080 2>&1 || true)" + "(cd $REPO_ROOT && $BIN conformance --config \"$NOPROV_CFG\" --spec cmd/testdata/crud.yaml --target http://localhost:8080 2>&1 || true)" echo ""