package runtimeconfig import ( "errors" "os" "path/filepath" "testing" ) // TestLoadVoiceTTSTuning 锁定 voice-tts.json 的四条读取口径: // 缺失 = 没配过(不是错误)、全空白 = 没配过、合法 = 逐键读出、坏文件 = 可分类错误。 func TestLoadVoiceTTSTuning(t *testing.T) { dir := t.TempDir() path := filepath.Join(dir, "voice-tts.json") // ① 缺失 if tuning, err := LoadVoiceTTSTuning(path); err != nil || tuning.EnabledOn() { t.Fatalf("缺失: tuning=%+v err=%v, want 零值 + nil", tuning, err) } // ② 全空白 if err := os.WriteFile(path, []byte(" \n\t "), 0o600); err != nil { t.Fatalf("write: %v", err) } if tuning, err := LoadVoiceTTSTuning(path); err != nil || tuning.EnabledOn() { t.Fatalf("空白: tuning=%+v err=%v, want 零值 + nil", tuning, err) } // ③ 合法 body := `{"enabled":true,"baseUrl":"http://127.0.0.1:9880","character":"char_84fb88a3", "format":"wav","timeoutSec":45}` if err := os.WriteFile(path, []byte(body), 0o600); err != nil { t.Fatalf("write: %v", err) } tuning, err := LoadVoiceTTSTuning(path) if err != nil { t.Fatalf("合法文件: %v", err) } if !tuning.EnabledOn() || tuning.Character != "char_84fb88a3" || tuning.Format != "wav" || tuning.TimeoutSec != 45 { t.Fatalf("读取结果不对: %+v", tuning) } // ④ 显式 false 与"没配"同效,但指针让它在读取侧可区分。 if err := os.WriteFile(path, []byte(`{"enabled":false}`), 0o600); err != nil { t.Fatalf("write: %v", err) } if tuning, err = LoadVoiceTTSTuning(path); err != nil || tuning.EnabledOn() || tuning.Enabled == nil { t.Fatalf("显式 false: tuning=%+v err=%v", tuning, err) } // ⑤ 坏文件 ⇒ 可分类错误(调用方据此回落"不启用",且绝不覆盖原文件) if err := os.WriteFile(path, []byte(`{"enabled":`), 0o600); err != nil { t.Fatalf("write: %v", err) } if _, err := LoadVoiceTTSTuning(path); !errors.Is(err, ErrInvalidVoiceTTS) { t.Fatalf("坏文件 err = %v, want ErrInvalidVoiceTTS", err) } if raw, err := os.ReadFile(path); err != nil || string(raw) != `{"enabled":` { t.Fatalf("坏文件被覆盖了: %q err=%v", string(raw), err) } } // TestDefaultVoiceTTSPath 钉住落点:`$DATA_DIR/config/voice-tts.json`(零新 .env 键)。 func TestDefaultVoiceTTSPath(t *testing.T) { got := DefaultVoiceTTSPath(filepath.Join("data", "root")) want := filepath.Join("data", "root", "config", "voice-tts.json") if got != want { t.Fatalf("path = %q, want %q", got, want) } if VoiceTTSConfigRelPath != "config/voice-tts.json" { t.Fatalf("RelPath = %q", VoiceTTSConfigRelPath) } }