Some checks failed
Security Scan / backend-security (push) Failing after 3s
Security Scan / frontend-security (push) Failing after 5s
CI / test (push) Failing after 3s
CI / frontend (push) Failing after 3s
CI / golangci-lint (push) Failing after 3s
CI / windsurf-platform (macos-latest) (push) Has been cancelled
CI / windsurf-platform (windows-latest) (push) Has been cancelled
145 lines
3.5 KiB
Go
145 lines
3.5 KiB
Go
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: `<html>`,
|
|
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)
|
|
}
|
|
}
|