diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-01 13:31:12 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-01 13:31:12 +0300 |
| commit | 7435d08d70107d20e13a0a725c9e8645ac3f7c57 (patch) | |
| tree | 58036d3b2cc978734ea001b8a8f1b25a95d6d71d /internal | |
| parent | 327817bae6a386f37d31d50a962c559d747a5383 (diff) | |
zs: preserve OpenAI default for phonetics
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/phonetic/fetcher.go | 9 | ||||
| -rw-r--r-- | internal/phonetic/fetcher_test.go | 86 | ||||
| -rw-r--r-- | internal/processor/processor_test.go | 40 |
3 files changed, 111 insertions, 24 deletions
diff --git a/internal/phonetic/fetcher.go b/internal/phonetic/fetcher.go index 8919345..a59d1f4 100644 --- a/internal/phonetic/fetcher.go +++ b/internal/phonetic/fetcher.go @@ -147,6 +147,11 @@ func (f *Fetcher) FetchAndSave(word, wordDir string) error { return nil } +// Provider reports the configured phonetic backend. +func (f *Fetcher) Provider() Provider { + return f.provider +} + func (f *Fetcher) fetchPhoneticInfo(ctx context.Context, word string) (string, error) { switch f.provider { case ProviderOpenAI: @@ -185,7 +190,7 @@ func (f *Fetcher) fetchWithGemini(ctx context.Context, word string) (string, err func normalizeConfig(config *Config) Config { normalized := Config{ - Provider: ProviderGemini, + Provider: ProviderOpenAI, OpenAIKey: "", GoogleAPIKey: "", } @@ -204,7 +209,7 @@ func normalizeConfig(config *Config) Config { func normalizeProvider(provider Provider) Provider { normalized := Provider(strings.ToLower(strings.TrimSpace(string(provider)))) if normalized == "" { - return ProviderGemini + return ProviderOpenAI } return normalized diff --git a/internal/phonetic/fetcher_test.go b/internal/phonetic/fetcher_test.go index 3382457..fedc5c2 100644 --- a/internal/phonetic/fetcher_test.go +++ b/internal/phonetic/fetcher_test.go @@ -10,28 +10,34 @@ import ( "google.golang.org/genai" ) -func TestNewFetcher_DefaultsToGemini(t *testing.T) { +func TestNewFetcher_DefaultsToOpenAI(t *testing.T) { fetcher := NewFetcher(nil) if fetcher == nil { t.Fatal("NewFetcher returned nil") } - if fetcher.provider != ProviderGemini { - t.Fatalf("expected default provider %q, got %q", ProviderGemini, fetcher.provider) + if got := fetcher.Provider(); got != ProviderOpenAI { + t.Fatalf("expected default provider %q, got %q", ProviderOpenAI, got) } +} - if fetcher.openAIClient != nil { - t.Error("expected OpenAI client to be nil without an API key") +func TestFetchAndSave_NoOpenAIAPIKey(t *testing.T) { + fetcher := NewFetcher(&Config{Provider: ProviderOpenAI}) + tmpDir := t.TempDir() + + err := fetcher.FetchAndSave("ябълка", tmpDir) + if err == nil { + t.Fatal("expected error for missing OpenAI API key") } - if fetcher.geminiClient != nil { - t.Error("expected Gemini client to be nil without an API key") + if err.Error() != "OpenAI API key not configured" { + t.Fatalf("expected OpenAI API key error, got %v", err) } } func TestFetchAndSave_NoGoogleAPIKey(t *testing.T) { - fetcher := NewFetcher(nil) + fetcher := NewFetcher(&Config{Provider: ProviderGemini}) tmpDir := t.TempDir() err := fetcher.FetchAndSave("ябълка", tmpDir) @@ -44,17 +50,17 @@ func TestFetchAndSave_NoGoogleAPIKey(t *testing.T) { } } -func TestFetchAndSave_NoOpenAIAPIKey(t *testing.T) { - fetcher := NewFetcher(&Config{Provider: ProviderOpenAI}) +func TestFetchAndSave_UnknownProvider(t *testing.T) { + fetcher := NewFetcher(&Config{Provider: Provider("mystery")}) tmpDir := t.TempDir() err := fetcher.FetchAndSave("ябълка", tmpDir) if err == nil { - t.Fatal("expected error for missing OpenAI API key") + t.Fatal("expected error for unknown provider") } - if err.Error() != "OpenAI API key not configured" { - t.Fatalf("expected OpenAI API key error, got %v", err) + if err.Error() != "unknown phonetic provider: mystery" { + t.Fatalf("expected unknown provider error, got %v", err) } } @@ -124,22 +130,58 @@ func TestFetchAndSave_GeminiProvider_WritesFile(t *testing.T) { } } -func TestFetchAndSave_InvalidDirectory(t *testing.T) { - originalFetch := fetchOpenAIPhonetic - fetchOpenAIPhonetic = func(context.Context, *openai.Client, string) (string, error) { - return "[ˈjɤbɐlkɐ]", nil +func TestFetchAndSave_GeminiInitFailure(t *testing.T) { + originalNewGeminiClient := newGeminiClient + newGeminiClient = func(context.Context, *genai.ClientConfig) (*genai.Client, error) { + return nil, context.Canceled } t.Cleanup(func() { - fetchOpenAIPhonetic = originalFetch + newGeminiClient = originalNewGeminiClient }) fetcher := NewFetcher(&Config{ - Provider: ProviderOpenAI, - OpenAIKey: "test-openai-key", + Provider: ProviderGemini, + GoogleAPIKey: "test-google-key", }) - err := fetcher.FetchAndSave("ябълка", "/nonexistent/path") + err := fetcher.FetchAndSave("ябълка", t.TempDir()) if err == nil { - t.Fatal("expected error for invalid directory") + t.Fatal("expected Gemini init failure") + } + + if err.Error() != "Gemini client initialization failed: context canceled" { + t.Fatalf("unexpected Gemini init error: %v", err) + } +} + +func TestFetchAndSave_GeminiAPIFailure(t *testing.T) { + originalFetch := fetchGeminiPhonetic + fetchGeminiPhonetic = func(context.Context, *genai.Client, string) (string, error) { + return "", context.DeadlineExceeded + } + t.Cleanup(func() { + fetchGeminiPhonetic = originalFetch + }) + + originalNewGeminiClient := newGeminiClient + newGeminiClient = func(context.Context, *genai.ClientConfig) (*genai.Client, error) { + return &genai.Client{}, nil + } + t.Cleanup(func() { + newGeminiClient = originalNewGeminiClient + }) + + fetcher := NewFetcher(&Config{ + Provider: ProviderGemini, + GoogleAPIKey: "test-google-key", + }) + + err := fetcher.FetchAndSave("ябълка", t.TempDir()) + if err == nil { + t.Fatal("expected Gemini API failure") + } + + if err.Error() != "context deadline exceeded" { + t.Fatalf("unexpected Gemini API error: %v", err) } } diff --git a/internal/processor/processor_test.go b/internal/processor/processor_test.go index d0a0070..ad71263 100644 --- a/internal/processor/processor_test.go +++ b/internal/processor/processor_test.go @@ -6,6 +6,7 @@ import ( "testing" "codeberg.org/snonux/totalrecall/internal/cli" + "codeberg.org/snonux/totalrecall/internal/phonetic" "github.com/spf13/viper" ) @@ -44,6 +45,45 @@ func TestNewProcessor(t *testing.T) { } } +func TestNewProcessor_DefaultPhoneticProviderUsesOpenAI(t *testing.T) { + t.Setenv("OPENAI_API_KEY", "") + t.Setenv("GOOGLE_API_KEY", "") + + originalConfig := viper.New() + *originalConfig = *viper.GetViper() + defer func() { + *viper.GetViper() = *originalConfig + }() + viper.Reset() + + flags := cli.NewFlags() + p := NewProcessor(flags) + + if got := p.phoneticFetcher.Provider(); got != phonetic.ProviderOpenAI { + t.Fatalf("expected default phonetic provider %q, got %q", phonetic.ProviderOpenAI, got) + } +} + +func TestNewProcessor_ExplicitGeminiPhoneticProvider(t *testing.T) { + t.Setenv("OPENAI_API_KEY", "") + t.Setenv("GOOGLE_API_KEY", "") + + originalConfig := viper.New() + *originalConfig = *viper.GetViper() + defer func() { + *viper.GetViper() = *originalConfig + }() + viper.Reset() + viper.Set("phonetic.provider", "gemini") + + flags := cli.NewFlags() + p := NewProcessor(flags) + + if got := p.phoneticFetcher.Provider(); got != phonetic.ProviderGemini { + t.Fatalf("expected gemini phonetic provider %q, got %q", phonetic.ProviderGemini, got) + } +} + func TestNewProcessor_DefaultTranslationProviderUsesOpenAI(t *testing.T) { t.Setenv("OPENAI_API_KEY", "") t.Setenv("GOOGLE_API_KEY", "") |
