777 lines
20 KiB
Go
777 lines
20 KiB
Go
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")
|
|
}
|
|
}
|