使用者:local-agent 啟動不需自動開網頁、桌面 GUI 為主。DefaultPreferences 的 AutoOpenBrowser 從 runtime.GOOS!="linux"(mac/win=true)改為所有平台 false。 只影響全新安裝(既有 preferences.json 有明確 autoOpenBrowser 值、Unmarshal 保留,尊重既有設定)。false 分支既有邏輯(SkipStage5 / 不檢查 timeout)未動。 codebase 本就無桌面「Open in Browser」按鈕(DEPRECATED、雲端 UI 遠端設計), 改預設沒弄丟任何手動能力。 reviewer 通過(0C/0M)。build/vet/test 全綠。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
113 lines
2.9 KiB
Go
113 lines
2.9 KiB
Go
package main
|
||
|
||
// preferences_test.go — M8-4 Preferences 持久化單元測試
|
||
|
||
import (
|
||
"encoding/json"
|
||
"os"
|
||
"path/filepath"
|
||
"runtime"
|
||
"testing"
|
||
)
|
||
|
||
func TestDefaultPreferences_PlatformSpecific(t *testing.T) {
|
||
p := DefaultPreferences()
|
||
// 桌面 GUI 為主要介面,所有平台一律預設不自動開瀏覽器。
|
||
if p.AutoOpenBrowser != false {
|
||
t.Fatalf("DefaultPreferences.AutoOpenBrowser=%v on %s, want false", p.AutoOpenBrowser, runtime.GOOS)
|
||
}
|
||
if p.Locale != "" {
|
||
t.Fatalf("default Locale=%q, want empty", p.Locale)
|
||
}
|
||
if p.LogRingSize != 0 {
|
||
t.Fatalf("default LogRingSize=%d, want 0", p.LogRingSize)
|
||
}
|
||
}
|
||
|
||
func TestLoadPreferences_MissingFile(t *testing.T) {
|
||
dir := t.TempDir()
|
||
p := LoadPreferences(dir)
|
||
want := DefaultPreferences()
|
||
if p != want {
|
||
t.Fatalf("LoadPreferences on empty dir=%+v, want default %+v", p, want)
|
||
}
|
||
}
|
||
|
||
func TestLoadPreferences_CorruptJSON(t *testing.T) {
|
||
dir := t.TempDir()
|
||
path := preferencesPath(dir)
|
||
if err := os.WriteFile(path, []byte("{not json"), 0o644); err != nil {
|
||
t.Fatalf("prep: %v", err)
|
||
}
|
||
p := LoadPreferences(dir)
|
||
want := DefaultPreferences()
|
||
if p != want {
|
||
t.Fatalf("LoadPreferences on corrupt json=%+v, want default %+v", p, want)
|
||
}
|
||
}
|
||
|
||
func TestSaveAndLoadPreferences_Roundtrip(t *testing.T) {
|
||
dir := t.TempDir()
|
||
|
||
orig := Preferences{
|
||
AutoOpenBrowser: false,
|
||
Locale: "zh-TW",
|
||
LogRingSize: 1000,
|
||
}
|
||
if err := SavePreferences(dir, orig); err != nil {
|
||
t.Fatalf("Save: %v", err)
|
||
}
|
||
|
||
// 確認 .tmp 不存在(rename 已完成)
|
||
if _, err := os.Stat(preferencesPath(dir) + ".tmp"); !os.IsNotExist(err) {
|
||
t.Fatalf("tmp file should not exist after rename, got err=%v", err)
|
||
}
|
||
|
||
// 檢查檔案內容是合法 JSON
|
||
raw, err := os.ReadFile(preferencesPath(dir))
|
||
if err != nil {
|
||
t.Fatalf("read file: %v", err)
|
||
}
|
||
var check Preferences
|
||
if err := json.Unmarshal(raw, &check); err != nil {
|
||
t.Fatalf("unmarshal: %v", err)
|
||
}
|
||
if check != orig {
|
||
t.Fatalf("on-disk=%+v, want %+v", check, orig)
|
||
}
|
||
|
||
// Load 回來應該一致
|
||
loaded := LoadPreferences(dir)
|
||
if loaded != orig {
|
||
t.Fatalf("loaded=%+v, want %+v", loaded, orig)
|
||
}
|
||
}
|
||
|
||
func TestSavePreferences_AtomicRename(t *testing.T) {
|
||
dir := t.TempDir()
|
||
// 預先寫一個舊 preferences.json
|
||
oldData := `{"autoOpenBrowser":true,"locale":"en-US"}`
|
||
if err := os.WriteFile(preferencesPath(dir), []byte(oldData), 0o644); err != nil {
|
||
t.Fatalf("prep: %v", err)
|
||
}
|
||
|
||
// 寫新的
|
||
newPref := Preferences{AutoOpenBrowser: false, Locale: "zh-TW"}
|
||
if err := SavePreferences(dir, newPref); err != nil {
|
||
t.Fatalf("Save: %v", err)
|
||
}
|
||
|
||
loaded := LoadPreferences(dir)
|
||
if loaded != newPref {
|
||
t.Fatalf("loaded=%+v, want %+v", loaded, newPref)
|
||
}
|
||
|
||
// tmp cleanup 後 data dir 只該有 preferences.json
|
||
entries, _ := os.ReadDir(dir)
|
||
for _, e := range entries {
|
||
if filepath.Ext(e.Name()) == ".tmp" {
|
||
t.Fatalf("leftover tmp file: %s", e.Name())
|
||
}
|
||
}
|
||
}
|