Files
arcrun-collector/cmd/arcrun-tray/t184_test.go
T
Leo 0021c274e8 t184:自更新蓋回「正在跑的那個 .app」——修 Oscar 更新完又跳回舊版
leo 08-04 實撞(Oscar 截圖):托盤顯示「🟢 新版 v0.15.6 已就緒」,
點下去重啟後**版本又是 v0.15.4**。同一套機制在 leo 機器正常。

真兇=`selfupdate.go` 寫死 `/Applications/Arcrun RAG.app`:
  · leo 有把 app 放進 /Applications ⇒ 剛好蓋對他正在跑的那份 ⇒ 一直正常
  · Oscar 從下載資料夾直接跑 ⇒ 蓋到一個他沒在跑的路徑
  · 而且 **ditto 會自動建出該目錄並回傳成功**(實測 exit 0,非報錯)
    ⇒ 畫面說「更新完成」、版本卻永遠是舊的=**靜默失敗**
  ⇒ 不是新舊 Mac 的差別,是 **app 放置位置**的差別(leo 機器實查證實)。

修法:改用 os.Executable() 往上推 .app(runningAppBundlePath),
更新**當前真的在跑的那份**——放哪都能更新,也不再無中生有 /Applications 副本。
找不到 .app 結構時誠實回錯,不猜路徑亂蓋(蓋錯比不更新更難查)。

⚠️ 「檢查更新」這條路**保留且必須修好**——leo:「這是我解決每次都要撞
沒簽章問題的解法,不能說它無用」。本次是修它,不是繞過它。

測試:新增 t184_test.go(不得回傳寫死 /Applications/.app 推導對三種放置位置
/ditto 靜默建目錄的認知回歸);順手把 t182 的 TestAccountEngineLabel 改寫成
新判準(explicit 決定,非 config 殘留字串)。兩模組全綠。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 17:57:46 +08:00

56 lines
2.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package main
import (
"os"
"path/filepath"
"strings"
"testing"
)
// t184:更新必須蓋在「正在跑的那個 .app」,不是寫死 /Applications。
// leo 08-04 實撞:Oscar 從下載資料夾跑 → ditto 自動建 /Applications 副本並回成功
// → 他重開仍是舊版,畫面卻說更新完成(靜默失敗)。
func TestRunningAppBundlePathNotHardcoded(t *testing.T) {
got, err := runningAppBundlePath()
// 測試執行檔不在 .app 裡 → 應誠實回錯,**不可**回傳寫死的 /Applications 路徑
if err == nil && strings.HasPrefix(got, "/Applications/") {
t.Errorf("不該回寫死的 /Applications 路徑:%q", got)
}
if err == nil && !strings.HasSuffix(got, ".app") {
t.Errorf("回傳的不是 .app%q", got)
}
}
// 模擬真實 .app 結構:<dir>/Arcrun RAG.app/Contents/MacOS/arcrun-tray
// 驗證「往上三層」的推導正確——放在哪個目錄都要算得出來。
func TestAppBundleDerivationFromExePath(t *testing.T) {
for _, base := range []string{"/Applications", "/Users/oscar/Downloads", "/Volumes/USB"} {
exe := filepath.Join(base, "Arcrun RAG.app", "Contents", "MacOS", "arcrun-tray")
app := filepath.Dir(filepath.Dir(filepath.Dir(exe)))
want := filepath.Join(base, "Arcrun RAG.app")
if app != want {
t.Errorf("從 %s 推導錯:got %q want %q", base, app, want)
}
}
}
// ditto 對不存在的目標會自動建目錄且回成功——這正是靜默失敗的成因,留測防回歸認知。
func TestDittoCreatesMissingTargetSilently(t *testing.T) {
dir := t.TempDir()
src := filepath.Join(dir, "Fake.app", "Contents")
if err := os.MkdirAll(src, 0o755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(src, "x"), []byte("hi"), 0o644); err != nil {
t.Fatal(err)
}
dst := filepath.Join(dir, "nowhere", "Fake.app")
if _, err := runCmd("ditto", filepath.Join(dir, "Fake.app"), dst); err != nil {
t.Skipf("此環境沒有 ditto%v", err)
}
if _, err := os.Stat(dst); err != nil {
t.Fatal("前提失效:ditto 應自動建出目標")
}
t.Log("確認:ditto 蓋到不存在的路徑會成功建出 ⇒ 寫死路徑必然靜默失敗")
}