add tests
This commit is contained in:
@@ -0,0 +1,776 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// createTestConfig returns a valid configuration for testing
|
||||
func createTestConfig() *Config {
|
||||
return &Config{
|
||||
Recording: RecordingConfig{
|
||||
SampleRate: 16000,
|
||||
Channels: 1,
|
||||
Format: "s16",
|
||||
BufferSize: 8192,
|
||||
Device: "",
|
||||
ChannelBufferSize: 30,
|
||||
Timeout: 5 * time.Minute,
|
||||
},
|
||||
Transcription: TranscriptionConfig{
|
||||
Provider: "openai",
|
||||
APIKey: "test-api-key",
|
||||
Language: "",
|
||||
Model: "whisper-1",
|
||||
},
|
||||
Injection: InjectionConfig{
|
||||
Mode: "fallback",
|
||||
RestoreClipboard: true,
|
||||
WtypeTimeout: 5 * time.Second,
|
||||
ClipboardTimeout: 3 * time.Second,
|
||||
},
|
||||
Notifications: NotificationsConfig{
|
||||
Enabled: true,
|
||||
Type: "log",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// createTestConfigWithInvalidValues returns a config with invalid values for testing validation
|
||||
func createTestConfigWithInvalidValues() *Config {
|
||||
return &Config{
|
||||
Recording: RecordingConfig{
|
||||
SampleRate: 0, // Invalid
|
||||
Channels: 0, // Invalid
|
||||
Format: "", // Invalid
|
||||
BufferSize: 0, // Invalid
|
||||
ChannelBufferSize: 0, // Invalid
|
||||
Timeout: 0, // Invalid
|
||||
},
|
||||
Transcription: TranscriptionConfig{
|
||||
Provider: "", // Invalid
|
||||
APIKey: "", // Invalid
|
||||
Model: "", // Invalid
|
||||
},
|
||||
Injection: InjectionConfig{
|
||||
Mode: "invalid", // Invalid
|
||||
WtypeTimeout: 0, // Invalid
|
||||
ClipboardTimeout: 0, // Invalid
|
||||
},
|
||||
Notifications: NotificationsConfig{
|
||||
Type: "invalid", // Invalid
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfig_Validate(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
config *Config
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "valid config",
|
||||
config: createTestConfig(),
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "invalid config",
|
||||
config: createTestConfigWithInvalidValues(),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "invalid recording sample rate",
|
||||
config: &Config{
|
||||
Recording: RecordingConfig{
|
||||
SampleRate: 0,
|
||||
Channels: 1,
|
||||
Format: "s16",
|
||||
BufferSize: 8192,
|
||||
ChannelBufferSize: 30,
|
||||
Timeout: time.Minute,
|
||||
},
|
||||
Transcription: TranscriptionConfig{
|
||||
Provider: "openai",
|
||||
APIKey: "test-key",
|
||||
Model: "whisper-1",
|
||||
},
|
||||
Injection: InjectionConfig{
|
||||
Mode: "fallback",
|
||||
WtypeTimeout: time.Second,
|
||||
ClipboardTimeout: time.Second,
|
||||
},
|
||||
Notifications: NotificationsConfig{
|
||||
Type: "log",
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "invalid transcription provider",
|
||||
config: &Config{
|
||||
Recording: RecordingConfig{
|
||||
SampleRate: 16000,
|
||||
Channels: 1,
|
||||
Format: "s16",
|
||||
BufferSize: 8192,
|
||||
ChannelBufferSize: 30,
|
||||
Timeout: time.Minute,
|
||||
},
|
||||
Transcription: TranscriptionConfig{
|
||||
Provider: "",
|
||||
APIKey: "test-key",
|
||||
Model: "whisper-1",
|
||||
},
|
||||
Injection: InjectionConfig{
|
||||
Mode: "fallback",
|
||||
WtypeTimeout: time.Second,
|
||||
ClipboardTimeout: time.Second,
|
||||
},
|
||||
Notifications: NotificationsConfig{
|
||||
Type: "log",
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "invalid injection mode",
|
||||
config: &Config{
|
||||
Recording: RecordingConfig{
|
||||
SampleRate: 16000,
|
||||
Channels: 1,
|
||||
Format: "s16",
|
||||
BufferSize: 8192,
|
||||
ChannelBufferSize: 30,
|
||||
Timeout: time.Minute,
|
||||
},
|
||||
Transcription: TranscriptionConfig{
|
||||
Provider: "openai",
|
||||
APIKey: "test-key",
|
||||
Model: "whisper-1",
|
||||
},
|
||||
Injection: InjectionConfig{
|
||||
Mode: "invalid",
|
||||
WtypeTimeout: time.Second,
|
||||
ClipboardTimeout: time.Second,
|
||||
},
|
||||
Notifications: NotificationsConfig{
|
||||
Type: "log",
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "invalid notification type",
|
||||
config: &Config{
|
||||
Recording: RecordingConfig{
|
||||
SampleRate: 16000,
|
||||
Channels: 1,
|
||||
Format: "s16",
|
||||
BufferSize: 8192,
|
||||
ChannelBufferSize: 30,
|
||||
Timeout: time.Minute,
|
||||
},
|
||||
Transcription: TranscriptionConfig{
|
||||
Provider: "openai",
|
||||
APIKey: "test-key",
|
||||
Model: "whisper-1",
|
||||
},
|
||||
Injection: InjectionConfig{
|
||||
Mode: "fallback",
|
||||
WtypeTimeout: time.Second,
|
||||
ClipboardTimeout: time.Second,
|
||||
},
|
||||
Notifications: NotificationsConfig{
|
||||
Type: "invalid",
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "valid language codes",
|
||||
config: &Config{
|
||||
Recording: RecordingConfig{
|
||||
SampleRate: 16000,
|
||||
Channels: 1,
|
||||
Format: "s16",
|
||||
BufferSize: 8192,
|
||||
ChannelBufferSize: 30,
|
||||
Timeout: time.Minute,
|
||||
},
|
||||
Transcription: TranscriptionConfig{
|
||||
Provider: "openai",
|
||||
APIKey: "test-key",
|
||||
Language: "en",
|
||||
Model: "whisper-1",
|
||||
},
|
||||
Injection: InjectionConfig{
|
||||
Mode: "fallback",
|
||||
WtypeTimeout: time.Second,
|
||||
ClipboardTimeout: time.Second,
|
||||
},
|
||||
Notifications: NotificationsConfig{
|
||||
Type: "log",
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "invalid language code",
|
||||
config: &Config{
|
||||
Recording: RecordingConfig{
|
||||
SampleRate: 16000,
|
||||
Channels: 1,
|
||||
Format: "s16",
|
||||
BufferSize: 8192,
|
||||
ChannelBufferSize: 30,
|
||||
Timeout: time.Minute,
|
||||
},
|
||||
Transcription: TranscriptionConfig{
|
||||
Provider: "openai",
|
||||
APIKey: "test-key",
|
||||
Language: "invalid",
|
||||
Model: "whisper-1",
|
||||
},
|
||||
Injection: InjectionConfig{
|
||||
Mode: "fallback",
|
||||
WtypeTimeout: time.Second,
|
||||
ClipboardTimeout: time.Second,
|
||||
},
|
||||
Notifications: NotificationsConfig{
|
||||
Type: "log",
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := tt.config.Validate()
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("Config.Validate() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfig_Load(t *testing.T) {
|
||||
// Test that Load creates default config when none exists
|
||||
t.Run("creates default config when none exists", func(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
originalConfigDir := os.Getenv("XDG_CONFIG_HOME")
|
||||
os.Setenv("XDG_CONFIG_HOME", tempDir)
|
||||
defer func() {
|
||||
if originalConfigDir == "" {
|
||||
os.Unsetenv("XDG_CONFIG_HOME")
|
||||
} else {
|
||||
os.Setenv("XDG_CONFIG_HOME", originalConfigDir)
|
||||
}
|
||||
}()
|
||||
|
||||
config, err := Load()
|
||||
if err != nil {
|
||||
t.Errorf("Load() error = %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Verify the loaded config is valid
|
||||
if err := config.Validate(); err != nil {
|
||||
t.Errorf("Loaded config is invalid: %v", err)
|
||||
}
|
||||
|
||||
// Verify config file was created
|
||||
configPath := filepath.Join(tempDir, "hyprvoice", "config.toml")
|
||||
if _, err := os.Stat(configPath); os.IsNotExist(err) {
|
||||
t.Errorf("Load() did not create config file")
|
||||
}
|
||||
})
|
||||
|
||||
// Test that Load works with existing valid config
|
||||
t.Run("loads existing valid config", func(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
configPath := filepath.Join(tempDir, "hyprvoice", "config.toml")
|
||||
|
||||
// Create directory and config file
|
||||
err := os.MkdirAll(filepath.Dir(configPath), 0755)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create config directory: %v", err)
|
||||
}
|
||||
|
||||
validConfig := `[recording]
|
||||
sample_rate = 16000
|
||||
channels = 1
|
||||
format = "s16"
|
||||
buffer_size = 8192
|
||||
channel_buffer_size = 30
|
||||
timeout = "5m"
|
||||
|
||||
[transcription]
|
||||
provider = "openai"
|
||||
api_key = "test-key"
|
||||
model = "whisper-1"
|
||||
|
||||
[injection]
|
||||
mode = "fallback"
|
||||
wtype_timeout = "5s"
|
||||
clipboard_timeout = "3s"
|
||||
|
||||
[notifications]
|
||||
enabled = true
|
||||
type = "log"`
|
||||
|
||||
err = os.WriteFile(configPath, []byte(validConfig), 0644)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create config file: %v", err)
|
||||
}
|
||||
|
||||
originalConfigDir := os.Getenv("XDG_CONFIG_HOME")
|
||||
os.Setenv("XDG_CONFIG_HOME", tempDir)
|
||||
defer func() {
|
||||
if originalConfigDir == "" {
|
||||
os.Unsetenv("XDG_CONFIG_HOME")
|
||||
} else {
|
||||
os.Setenv("XDG_CONFIG_HOME", originalConfigDir)
|
||||
}
|
||||
}()
|
||||
|
||||
config, err := Load()
|
||||
if err != nil {
|
||||
t.Errorf("Load() error = %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Verify the loaded config is valid
|
||||
if err := config.Validate(); err != nil {
|
||||
t.Errorf("Loaded config is invalid: %v", err)
|
||||
}
|
||||
|
||||
// Verify specific values were loaded
|
||||
if config.Recording.SampleRate != 16000 {
|
||||
t.Errorf("Expected SampleRate 16000, got %d", config.Recording.SampleRate)
|
||||
}
|
||||
if config.Transcription.Provider != "openai" {
|
||||
t.Errorf("Expected Provider 'openai', got %s", config.Transcription.Provider)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestConfig_SaveDefaultConfig(t *testing.T) {
|
||||
// Override the config path by setting environment variable
|
||||
tempDir := t.TempDir()
|
||||
originalConfigDir := os.Getenv("XDG_CONFIG_HOME")
|
||||
os.Setenv("XDG_CONFIG_HOME", tempDir)
|
||||
defer func() {
|
||||
if originalConfigDir == "" {
|
||||
os.Unsetenv("XDG_CONFIG_HOME")
|
||||
} else {
|
||||
os.Setenv("XDG_CONFIG_HOME", originalConfigDir)
|
||||
}
|
||||
}()
|
||||
|
||||
err := SaveDefaultConfig()
|
||||
if err != nil {
|
||||
t.Errorf("SaveDefaultConfig() error = %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Verify file was created
|
||||
configPath := filepath.Join(tempDir, "hyprvoice", "config.toml")
|
||||
if _, err := os.Stat(configPath); os.IsNotExist(err) {
|
||||
t.Errorf("SaveDefaultConfig() did not create config file")
|
||||
return
|
||||
}
|
||||
|
||||
// Verify file content
|
||||
content, err := os.ReadFile(configPath)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to read created config file: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(content) == 0 {
|
||||
t.Errorf("SaveDefaultConfig() created empty config file")
|
||||
return
|
||||
}
|
||||
|
||||
// Verify it's valid TOML
|
||||
config, err := Load()
|
||||
if err != nil {
|
||||
t.Errorf("SaveDefaultConfig() created invalid config: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Verify validation passes
|
||||
if err := config.Validate(); err != nil {
|
||||
t.Errorf("SaveDefaultConfig() created invalid config: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfig_ConversionMethods(t *testing.T) {
|
||||
config := createTestConfig()
|
||||
|
||||
t.Run("ToRecordingConfig", func(t *testing.T) {
|
||||
recordingConfig := config.ToRecordingConfig()
|
||||
|
||||
if recordingConfig.SampleRate != config.Recording.SampleRate {
|
||||
t.Errorf("SampleRate mismatch: got %d, want %d", recordingConfig.SampleRate, config.Recording.SampleRate)
|
||||
}
|
||||
if recordingConfig.Channels != config.Recording.Channels {
|
||||
t.Errorf("Channels mismatch: got %d, want %d", recordingConfig.Channels, config.Recording.Channels)
|
||||
}
|
||||
if recordingConfig.Format != config.Recording.Format {
|
||||
t.Errorf("Format mismatch: got %s, want %s", recordingConfig.Format, config.Recording.Format)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("ToTranscriberConfig", func(t *testing.T) {
|
||||
transcriberConfig := config.ToTranscriberConfig()
|
||||
|
||||
if transcriberConfig.Provider != config.Transcription.Provider {
|
||||
t.Errorf("Provider mismatch: got %s, want %s", transcriberConfig.Provider, config.Transcription.Provider)
|
||||
}
|
||||
if transcriberConfig.APIKey != config.Transcription.APIKey {
|
||||
t.Errorf("APIKey mismatch: got %s, want %s", transcriberConfig.APIKey, config.Transcription.APIKey)
|
||||
}
|
||||
if transcriberConfig.Language != config.Transcription.Language {
|
||||
t.Errorf("Language mismatch: got %s, want %s", transcriberConfig.Language, config.Transcription.Language)
|
||||
}
|
||||
if transcriberConfig.Model != config.Transcription.Model {
|
||||
t.Errorf("Model mismatch: got %s, want %s", transcriberConfig.Model, config.Transcription.Model)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("ToInjectionConfig", func(t *testing.T) {
|
||||
injectionConfig := config.ToInjectionConfig()
|
||||
|
||||
if injectionConfig.Mode != config.Injection.Mode {
|
||||
t.Errorf("Mode mismatch: got %s, want %s", injectionConfig.Mode, config.Injection.Mode)
|
||||
}
|
||||
if injectionConfig.RestoreClipboard != config.Injection.RestoreClipboard {
|
||||
t.Errorf("RestoreClipboard mismatch: got %t, want %t", injectionConfig.RestoreClipboard, config.Injection.RestoreClipboard)
|
||||
}
|
||||
if injectionConfig.WtypeTimeout != config.Injection.WtypeTimeout {
|
||||
t.Errorf("WtypeTimeout mismatch: got %v, want %v", injectionConfig.WtypeTimeout, config.Injection.WtypeTimeout)
|
||||
}
|
||||
if injectionConfig.ClipboardTimeout != config.Injection.ClipboardTimeout {
|
||||
t.Errorf("ClipboardTimeout mismatch: got %v, want %v", injectionConfig.ClipboardTimeout, config.Injection.ClipboardTimeout)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestIsValidLanguageCode(t *testing.T) {
|
||||
validCodes := []string{"en", "es", "fr", "de", "it", "pt", "ru", "ja", "ko", "zh", "ar", "hi"}
|
||||
invalidCodes := []string{"", "invalid", "xx", "123", "EN", "en-us"}
|
||||
|
||||
for _, code := range validCodes {
|
||||
t.Run("valid_"+code, func(t *testing.T) {
|
||||
if !isValidLanguageCode(code) {
|
||||
t.Errorf("isValidLanguageCode(%s) = false, want true", code)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
for _, code := range invalidCodes {
|
||||
t.Run("invalid_"+code, func(t *testing.T) {
|
||||
if isValidLanguageCode(code) {
|
||||
t.Errorf("isValidLanguageCode(%s) = true, want false", code)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetConfigPath(t *testing.T) {
|
||||
// Override user config dir for testing using environment variable
|
||||
tempDir := t.TempDir()
|
||||
originalConfigDir := os.Getenv("XDG_CONFIG_HOME")
|
||||
os.Setenv("XDG_CONFIG_HOME", tempDir)
|
||||
defer func() {
|
||||
if originalConfigDir == "" {
|
||||
os.Unsetenv("XDG_CONFIG_HOME")
|
||||
} else {
|
||||
os.Setenv("XDG_CONFIG_HOME", originalConfigDir)
|
||||
}
|
||||
}()
|
||||
|
||||
path, err := GetConfigPath()
|
||||
if err != nil {
|
||||
t.Errorf("GetConfigPath() error = %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
expectedPath := filepath.Join(tempDir, "hyprvoice", "config.toml")
|
||||
if path != expectedPath {
|
||||
t.Errorf("GetConfigPath() = %s, want %s", path, expectedPath)
|
||||
}
|
||||
|
||||
// Verify directory was created
|
||||
if _, err := os.Stat(filepath.Dir(path)); os.IsNotExist(err) {
|
||||
t.Errorf("GetConfigPath() did not create config directory")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfig_ToTranscriberConfig_WithEnvVar(t *testing.T) {
|
||||
config := &Config{
|
||||
Transcription: TranscriptionConfig{
|
||||
Provider: "openai",
|
||||
APIKey: "", // Empty API key to test env var fallback
|
||||
Language: "en",
|
||||
Model: "whisper-1",
|
||||
},
|
||||
}
|
||||
|
||||
// Set environment variable
|
||||
originalAPIKey := os.Getenv("OPENAI_API_KEY")
|
||||
os.Setenv("OPENAI_API_KEY", "env-api-key")
|
||||
defer func() {
|
||||
if originalAPIKey == "" {
|
||||
os.Unsetenv("OPENAI_API_KEY")
|
||||
} else {
|
||||
os.Setenv("OPENAI_API_KEY", originalAPIKey)
|
||||
}
|
||||
}()
|
||||
|
||||
transcriberConfig := config.ToTranscriberConfig()
|
||||
|
||||
if transcriberConfig.APIKey != "env-api-key" {
|
||||
t.Errorf("Expected APIKey from env var 'env-api-key', got %s", transcriberConfig.APIKey)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfig_ToTranscriberConfig_WithoutEnvVar(t *testing.T) {
|
||||
config := &Config{
|
||||
Transcription: TranscriptionConfig{
|
||||
Provider: "openai",
|
||||
APIKey: "config-api-key", // Config has API key
|
||||
Language: "en",
|
||||
Model: "whisper-1",
|
||||
},
|
||||
}
|
||||
|
||||
// Ensure environment variable is not set
|
||||
originalAPIKey := os.Getenv("OPENAI_API_KEY")
|
||||
os.Unsetenv("OPENAI_API_KEY")
|
||||
defer func() {
|
||||
if originalAPIKey != "" {
|
||||
os.Setenv("OPENAI_API_KEY", originalAPIKey)
|
||||
}
|
||||
}()
|
||||
|
||||
transcriberConfig := config.ToTranscriberConfig()
|
||||
|
||||
if transcriberConfig.APIKey != "config-api-key" {
|
||||
t.Errorf("Expected APIKey from config 'config-api-key', got %s", transcriberConfig.APIKey)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfig_Load_InvalidTOML(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
configPath := filepath.Join(tempDir, "hyprvoice", "config.toml")
|
||||
|
||||
// Create directory and invalid config file
|
||||
err := os.MkdirAll(filepath.Dir(configPath), 0755)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create config directory: %v", err)
|
||||
}
|
||||
|
||||
invalidConfig := `[recording]
|
||||
sample_rate = "invalid_number"`
|
||||
|
||||
err = os.WriteFile(configPath, []byte(invalidConfig), 0644)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create config file: %v", err)
|
||||
}
|
||||
|
||||
originalConfigDir := os.Getenv("XDG_CONFIG_HOME")
|
||||
os.Setenv("XDG_CONFIG_HOME", tempDir)
|
||||
defer func() {
|
||||
if originalConfigDir == "" {
|
||||
os.Unsetenv("XDG_CONFIG_HOME")
|
||||
} else {
|
||||
os.Setenv("XDG_CONFIG_HOME", originalConfigDir)
|
||||
}
|
||||
}()
|
||||
|
||||
_, err = Load()
|
||||
if err == nil {
|
||||
t.Errorf("Load() should have failed with invalid TOML")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfig_Validate_OpenAI_WithoutAPIKey(t *testing.T) {
|
||||
config := &Config{
|
||||
Recording: RecordingConfig{
|
||||
SampleRate: 16000,
|
||||
Channels: 1,
|
||||
Format: "s16",
|
||||
BufferSize: 8192,
|
||||
ChannelBufferSize: 30,
|
||||
Timeout: time.Minute,
|
||||
},
|
||||
Transcription: TranscriptionConfig{
|
||||
Provider: "openai",
|
||||
APIKey: "", // No API key
|
||||
Model: "whisper-1",
|
||||
},
|
||||
Injection: InjectionConfig{
|
||||
Mode: "fallback",
|
||||
WtypeTimeout: time.Second,
|
||||
ClipboardTimeout: time.Second,
|
||||
},
|
||||
Notifications: NotificationsConfig{
|
||||
Type: "log",
|
||||
},
|
||||
}
|
||||
|
||||
// Ensure environment variable is not set
|
||||
originalAPIKey := os.Getenv("OPENAI_API_KEY")
|
||||
os.Unsetenv("OPENAI_API_KEY")
|
||||
defer func() {
|
||||
if originalAPIKey != "" {
|
||||
os.Setenv("OPENAI_API_KEY", originalAPIKey)
|
||||
}
|
||||
}()
|
||||
|
||||
err := config.Validate()
|
||||
if err == nil {
|
||||
t.Errorf("Validate() should have failed without OpenAI API key")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfig_Validate_OpenAI_WithEnvVarAPIKey(t *testing.T) {
|
||||
config := &Config{
|
||||
Recording: RecordingConfig{
|
||||
SampleRate: 16000,
|
||||
Channels: 1,
|
||||
Format: "s16",
|
||||
BufferSize: 8192,
|
||||
ChannelBufferSize: 30,
|
||||
Timeout: time.Minute,
|
||||
},
|
||||
Transcription: TranscriptionConfig{
|
||||
Provider: "openai",
|
||||
APIKey: "", // No API key in config
|
||||
Model: "whisper-1",
|
||||
},
|
||||
Injection: InjectionConfig{
|
||||
Mode: "fallback",
|
||||
WtypeTimeout: time.Second,
|
||||
ClipboardTimeout: time.Second,
|
||||
},
|
||||
Notifications: NotificationsConfig{
|
||||
Type: "log",
|
||||
},
|
||||
}
|
||||
|
||||
// Set environment variable
|
||||
originalAPIKey := os.Getenv("OPENAI_API_KEY")
|
||||
os.Setenv("OPENAI_API_KEY", "env-api-key")
|
||||
defer func() {
|
||||
if originalAPIKey == "" {
|
||||
os.Unsetenv("OPENAI_API_KEY")
|
||||
} else {
|
||||
os.Setenv("OPENAI_API_KEY", originalAPIKey)
|
||||
}
|
||||
}()
|
||||
|
||||
err := config.Validate()
|
||||
if err != nil {
|
||||
t.Errorf("Validate() should have passed with OpenAI API key from environment: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfig_Validate_RecordingTimeout(t *testing.T) {
|
||||
config := &Config{
|
||||
Recording: RecordingConfig{
|
||||
SampleRate: 16000,
|
||||
Channels: 1,
|
||||
Format: "s16",
|
||||
BufferSize: 8192,
|
||||
ChannelBufferSize: 30,
|
||||
Timeout: 0, // Invalid timeout
|
||||
},
|
||||
Transcription: TranscriptionConfig{
|
||||
Provider: "openai",
|
||||
APIKey: "test-key",
|
||||
Model: "whisper-1",
|
||||
},
|
||||
Injection: InjectionConfig{
|
||||
Mode: "fallback",
|
||||
WtypeTimeout: time.Second,
|
||||
ClipboardTimeout: time.Second,
|
||||
},
|
||||
Notifications: NotificationsConfig{
|
||||
Type: "log",
|
||||
},
|
||||
}
|
||||
|
||||
err := config.Validate()
|
||||
if err == nil {
|
||||
t.Errorf("Validate() should have failed with invalid recording timeout")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfig_Validate_InjectionTimeouts(t *testing.T) {
|
||||
config := &Config{
|
||||
Recording: RecordingConfig{
|
||||
SampleRate: 16000,
|
||||
Channels: 1,
|
||||
Format: "s16",
|
||||
BufferSize: 8192,
|
||||
ChannelBufferSize: 30,
|
||||
Timeout: time.Minute,
|
||||
},
|
||||
Transcription: TranscriptionConfig{
|
||||
Provider: "openai",
|
||||
APIKey: "test-key",
|
||||
Model: "whisper-1",
|
||||
},
|
||||
Injection: InjectionConfig{
|
||||
Mode: "fallback",
|
||||
WtypeTimeout: 0, // Invalid timeout
|
||||
ClipboardTimeout: 0, // Invalid timeout
|
||||
},
|
||||
Notifications: NotificationsConfig{
|
||||
Type: "log",
|
||||
},
|
||||
}
|
||||
|
||||
err := config.Validate()
|
||||
if err == nil {
|
||||
t.Errorf("Validate() should have failed with invalid injection timeouts")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfig_Validate_RecordingBufferSizes(t *testing.T) {
|
||||
config := &Config{
|
||||
Recording: RecordingConfig{
|
||||
SampleRate: 16000,
|
||||
Channels: 1,
|
||||
Format: "s16",
|
||||
BufferSize: 0, // Invalid buffer size
|
||||
ChannelBufferSize: 0, // Invalid buffer size
|
||||
Timeout: time.Minute,
|
||||
},
|
||||
Transcription: TranscriptionConfig{
|
||||
Provider: "openai",
|
||||
APIKey: "test-key",
|
||||
Model: "whisper-1",
|
||||
},
|
||||
Injection: InjectionConfig{
|
||||
Mode: "fallback",
|
||||
WtypeTimeout: time.Second,
|
||||
ClipboardTimeout: time.Second,
|
||||
},
|
||||
Notifications: NotificationsConfig{
|
||||
Type: "log",
|
||||
},
|
||||
}
|
||||
|
||||
err := config.Validate()
|
||||
if err == nil {
|
||||
t.Errorf("Validate() should have failed with invalid recording buffer sizes")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user