Files
arcrun-collector/cloud_version_test.go
Leo 779a1b801e feat(t215): 每個知識庫顯示是否要更新,落後就給 install 頁連結
leo 08-08:「在每個知識庫會看到其他需要更新的,在每個知識庫上顯示是否要更新,
如果要,加開啓 install 頁的連結」。小幫手以前只提示自己(daemon 本體)要不要
更新,使用者連著多個雲端知識庫時完全看不出哪一個落後。

- collector/cloud_latest.go:EvalCloudUpdate + FetchLatestCloudRelease(30 分鐘節流),
  判準與 portal 版本卡 loadVersion() 同一套(bundle_version vs install.arcrun.dev/
  api/latest 的 release,semver 逐段整數比較),不是 t103 minCloudRelease 那把相容
  底線,避免同一個知識庫在兩處得到相反答案。
- direct.go/sync_status.go:每輪同步順帶算好每個帳號的 CloudUpdateKnown/
  CloudUpdateStale/CloudLatest,寫進 status.json。
- app.go:GetState 把這些欄位接進 UIAccount,供前端讀。
- main.js/style.css:首頁新增「知識庫版本」卡(每庫一行,落後才出現「前往安裝頁
  更新」按鈕,帶 email 預填);側邊欄庫名旁加警示點;各庫頁也顯示同一行版本狀態。
  查不到版本(連不上/latest 暫時查不到)一律誠實說「查不到」,不當成「已最新」。

已用假 window.go 在瀏覽器實測四種情境(落後/已最新/連不上/查得到 mine 但查不到
latest)+零知識庫的 onboarding 頁+深色模式,畫面與按鈕行為皆符合預期。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 00:21:40 +08:00

76 lines
3.0 KiB
Go
Raw Permalink 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.
// cloud_version_test.go — t103 雲端版本判定函式 4 案單元測試。
package collector
import (
"os"
"testing"
)
// TestMain 在所有測試執行前把 fetchCloudVersion 換成 stub(回 ("", false)),
// 避免各測試的假 httptest.Server 或離線環境因真實 /health 呼叫炸掉測試。
// TestCloudVersionStale 直接測 cloudVersionStale 邏輯,不受此 stub 影響。
func TestMain(m *testing.M) {
fetchCloudVersion = func(string) (string, bool) { return "", false }
// t215:同一個理由——避免 EvalCloudUpdate 相關測試因為真的打了
// install.arcrun.dev 而變成看網路臉色的測試。
fetchLatestCloudReleaseRaw = func() (string, bool) { return "", false }
os.Exit(m.Run())
}
// TestCloudVersionStale 驗證四種判定情境:空版本/過舊/正常/解析失敗。
func TestCloudVersionStale(t *testing.T) {
cases := []struct {
name string
version string
checkOK bool
wantStale bool
}{
{
// 老實例:/health 可達但 bundle_version 為空字串 → 需要更新
name: "空版本(老實例)", version: "", checkOK: true, wantStale: true,
},
{
// 日期早於 minCloudBuilt → 需要更新
name: "過舊日期", version: "2026-07-27+abc1234", checkOK: true, wantStale: true,
},
{
// 日期等於 minCloudBuilt → 正常(剛好達標)
name: "正常(剛好達標)", version: "2026-07-28+abc1234", checkOK: true, wantStale: false,
},
{
// /health 不可達(解析失敗/逾時)→ 靜默不判定
name: "解析失敗(/health 不可達)", version: "", checkOK: false, wantStale: false,
},
// 🔴 2026-08-02 迴歸守衛(leo 實撞:兩帳號都更新到 1.4.1,卻**都**顯示需要更新且消不掉)。
// 病根:舊實作 `head < minCloudBuilt` 是**字串比較**semver 進來後
// "1.4.1" < "2026-07-28" 恆為真 ⇒ 最新版被判過舊。
// 這幾則若變紅,代表版本比較又退回字串比較,或新格式沒被辨識。
{
name: "semver 最新版(1.4.1)不該被判過舊", version: "1.4.1", checkOK: true, wantStale: false,
},
{
name: "semver 剛好達標(1.4.0", version: "1.4.0", checkOK: true, wantStale: false,
},
{
name: "semver 過舊(1.3.9)需要更新", version: "1.3.9", checkOK: true, wantStale: true,
},
{
// 字串比較會誤判成 "1.10.0" < "1.9.0";整數逐段比較才對
name: "semver 1.10.0 比 1.9.0 新(防字串比較)", version: "1.10.0", checkOK: true, wantStale: false,
},
{
// 舊格式仍須正確辨識——兩種格式並存期間,老實例不可被誤判成最新而收不到提示
name: "舊格式過舊仍要判過舊(相容)", version: "2026-07-01+deadbee", checkOK: true, wantStale: true,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
got := cloudVersionStale(tc.version, tc.checkOK)
if got != tc.wantStale {
t.Errorf("cloudVersionStale(%q, %v) = %vwant %v", tc.version, tc.checkOK, got, tc.wantStale)
}
})
}
}