Files
ai-operator/internal/config/config_test.go
T

161 lines
4.6 KiB
Go

package config
import (
"os"
"path/filepath"
"testing"
)
func TestLoadConfigAllowsOptionalEmptyValues(t *testing.T) {
path := filepath.Join(t.TempDir(), "app.env")
content := `APP_ENV=dev
LOG_LEVEL=debug
ASTERISK_ARI_URL=http://127.0.0.1:8088/ari
ASTERISK_ARI_WS_URL=ws://127.0.0.1:8088/ari/events
ASTERISK_ARI_USER=ai_operator
ASTERISK_ARI_PASSWORD=test-password
ASTERISK_ARI_APP=ai-operator
ASTERISK_MEDIA_MODE=chan_websocket
ASTERISK_MEDIA_CODEC=slin16
OPENAI_API_KEY=
OPENAI_REALTIME_MODEL=
DATABASE_URL=
`
if err := os.WriteFile(path, []byte(content), 0600); err != nil {
t.Fatal(err)
}
cfg, resolved, err := Load(path)
if err != nil {
t.Fatalf("Load() error = %v", err)
}
if resolved != path {
t.Fatalf("resolved path = %q, want %q", resolved, path)
}
if cfg.OpenAI.APIKey != "" {
t.Fatal("OpenAI API key should be optional and empty")
}
if cfg.Database.URL != "" {
t.Fatal("Database URL should be optional and empty")
}
}
func TestLoadConfigRequiresCriticalFields(t *testing.T) {
path := filepath.Join(t.TempDir(), "bad.env")
if err := os.WriteFile(path, []byte("APP_ENV=dev\n"), 0600); err != nil {
t.Fatal(err)
}
if _, _, err := Load(path); err == nil {
t.Fatal("Load() error = nil, want validation error")
}
}
func TestMasking(t *testing.T) {
if got := MaskSecret("password"); got != "***MASKED***" {
t.Fatalf("MaskSecret() = %q", got)
}
if got := MaskOpenAIKey(""); got != "***EMPTY***" {
t.Fatalf("MaskOpenAIKey(empty) = %q", got)
}
if got := MaskOpenAIKey("sk-test"); got != "sk-***MASKED***" {
t.Fatalf("MaskOpenAIKey(non-empty) = %q", got)
}
got := MaskURLCredentials("postgres://user:pass@localhost/db")
want := "postgres://%2A%2A%2AMASKED%2A%2A%2A:%2A%2A%2AMASKED%2A%2A%2A@localhost/db"
if got != want {
t.Fatalf("MaskURLCredentials() = %q, want %q", got, want)
}
}
func TestDialogueConfigDefaults(t *testing.T) {
path := filepath.Join(t.TempDir(), "dialogue.env")
content := `APP_ENV=dev
LOG_LEVEL=debug
ASTERISK_ARI_URL=http://127.0.0.1:8088/ari
ASTERISK_ARI_WS_URL=ws://127.0.0.1:8088/ari/events
ASTERISK_ARI_USER=ai_operator
ASTERISK_ARI_PASSWORD=test-password
ASTERISK_ARI_APP=ai-operator
ASTERISK_MEDIA_MODE=chan_websocket
ASTERISK_MEDIA_CODEC=slin16
`
if err := os.WriteFile(path, []byte(content), 0600); err != nil {
t.Fatal(err)
}
cfg, _, err := Load(path)
if err != nil {
t.Fatal(err)
}
if !cfg.Dialogue.EnforceLanguageAndRegion {
t.Fatal("dialogue enforcement should default true")
}
if cfg.Dialogue.DefaultLanguage != "" || cfg.Dialogue.DefaultRegionCode != "" {
t.Fatal("dialogue defaults should be empty")
}
}
func TestDialogueEnforcementCannotBeDisabledInProd(t *testing.T) {
path := filepath.Join(t.TempDir(), "prod.env")
content := `APP_ENV=prod
LOG_LEVEL=info
ASTERISK_ARI_URL=http://127.0.0.1:8088/ari
ASTERISK_ARI_WS_URL=ws://127.0.0.1:8088/ari/events
ASTERISK_ARI_USER=ai_operator
ASTERISK_ARI_PASSWORD=test-password
ASTERISK_ARI_APP=ai-operator
ASTERISK_MEDIA_MODE=chan_websocket
ASTERISK_MEDIA_CODEC=slin16
DIALOGUE_ENFORCE_LANGUAGE_REGION=false
`
if err := os.WriteFile(path, []byte(content), 0600); err != nil {
t.Fatal(err)
}
if _, _, err := Load(path); err == nil {
t.Fatal("expected prod validation error")
}
}
func TestLanguageConfigDefaults(t *testing.T) {
path := filepath.Join(t.TempDir(), "language.env")
content := `APP_ENV=dev
LOG_LEVEL=debug
ASTERISK_ARI_URL=http://127.0.0.1:8088/ari
ASTERISK_ARI_WS_URL=ws://127.0.0.1:8088/ari/events
ASTERISK_ARI_USER=ai_operator
ASTERISK_ARI_PASSWORD=test-password
ASTERISK_ARI_APP=ai-operator
ASTERISK_MEDIA_MODE=chan_websocket
ASTERISK_MEDIA_CODEC=slin16
`
if err := os.WriteFile(path, []byte(content), 0600); err != nil {
t.Fatal(err)
}
cfg, _, err := Load(path)
if err != nil {
t.Fatal(err)
}
if !cfg.Dialogue.LanguageSelectionEnabled || cfg.Dialogue.LanguageConfidenceThreshold != 0.70 || cfg.Dialogue.LanguageChangeConfidenceThreshold != 0.90 || !cfg.Dialogue.LanguageAllowChangeAfterSelection || cfg.Dialogue.LanguageDefaultOnTimeout != "" {
t.Fatalf("bad language defaults: %+v", cfg.Dialogue)
}
}
func TestLanguageSelectionCannotBeDisabledInProd(t *testing.T) {
path := filepath.Join(t.TempDir(), "prod-language.env")
content := `APP_ENV=prod
LOG_LEVEL=info
ASTERISK_ARI_URL=http://127.0.0.1:8088/ari
ASTERISK_ARI_WS_URL=ws://127.0.0.1:8088/ari/events
ASTERISK_ARI_USER=ai_operator
ASTERISK_ARI_PASSWORD=test-password
ASTERISK_ARI_APP=ai-operator
ASTERISK_MEDIA_MODE=chan_websocket
ASTERISK_MEDIA_CODEC=slin16
LANGUAGE_SELECTION_ENABLED=false
`
if err := os.WriteFile(path, []byte(content), 0600); err != nil {
t.Fatal(err)
}
if _, _, err := Load(path); err == nil {
t.Fatal("expected prod language validation error")
}
}