package antigravity import ( "context" "net/http" "net/http/httptest" "strings" "sync/atomic" "testing" "time" ) func TestFetchLatestAntigravityVersion(t *testing.T) { cases := []struct { name string body string status int wantVer string wantErr bool }{ { name: "正常响应_取首个版本", body: `[{"version":"1.23.2","execution_id":"x"},{"version":"1.22.2","execution_id":"y"}]`, status: http.StatusOK, wantVer: "1.23.2", }, { name: "首个版本号无效_退回到第二个有效项", body: `[{"version":"not-a-version"},{"version":"1.21.9"}]`, status: http.StatusOK, wantVer: "1.21.9", }, { name: "空数组_报错", body: `[]`, status: http.StatusOK, wantErr: true, }, { name: "5xx_报错", body: `internal error`, status: http.StatusInternalServerError, wantErr: true, }, { name: "非 JSON_报错", body: ``, status: http.StatusOK, wantErr: true, }, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if !strings.Contains(r.Header.Get("User-Agent"), "antigravity-updater/") { t.Errorf("UA 不符合预期: %s", r.Header.Get("User-Agent")) } w.WriteHeader(tc.status) _, _ = w.Write([]byte(tc.body)) })) defer ts.Close() ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() version, err := fetchVersionFromURL(ctx, ts.Client(), ts.URL) if tc.wantErr { if err == nil { t.Fatalf("期望错误,但成功: %s", version) } return } if err != nil { t.Fatalf("意外错误: %v", err) } if version != tc.wantVer { t.Errorf("版本号不匹配: got %s, want %s", version, tc.wantVer) } }) } } func TestIsPlausibleAntigravityVersion(t *testing.T) { cases := []struct { in string want bool }{ {"1.23.2", true}, {"1.21.9", true}, {"1.20", true}, {"1.20.6.0", true}, {"", false}, {"1", false}, {"1.2.3.4.5", false}, {"1.x.3", false}, {"100000.1.1", false}, } for _, tc := range cases { if got := isPlausibleAntigravityVersion(tc.in); got != tc.want { t.Errorf("isPlausibleAntigravityVersion(%q) = %v, want %v", tc.in, got, tc.want) } } } func TestVersionFetcher_Overridden_不刷新(t *testing.T) { var hits int32 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { atomic.AddInt32(&hits, 1) w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte(`[{"version":"9.9.9"}]`)) })) defer ts.Close() f := newVersionFetcherForTest(ts.URL) f.MarkOverridden() f.refreshOnce() if got := atomic.LoadInt32(&hits); got != 0 { t.Errorf("Overridden 时应跳过拉取,但收到 %d 次请求", got) } if v := f.Current(); v != "" { t.Errorf("Overridden 时不应写入版本号,但 Current=%s", v) } } func TestVersionFetcher_Refresh_更新版本号(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte(`[{"version":"1.99.0"}]`)) })) defer ts.Close() prev := currentUserAgentVersion() defer setDefaultUserAgentVersion(prev) f := newVersionFetcherForTest(ts.URL) f.refreshOnce() if got := f.Current(); got != "1.99.0" { t.Errorf("Current=%s, want 1.99.0", got) } if got := currentUserAgentVersion(); got != "1.99.0" { t.Errorf("setDefaultUserAgentVersion 未生效: %s", got) } }