package client import ( "bytes" "context" "net/http/httptest" "os" "path/filepath" "testing" "time" "scout/internal/httpapi" "scout/internal/registry" ) func TestClientUploadQueryCheckAndDownload(t *testing.T) { store, err := registry.New(t.TempDir()) if err != nil { t.Fatal(err) } server := httptest.NewServer((&httpapi.Server{Registry: store, DeveloperToken: "测试令牌"}).Handler()) defer server.Close() api, err := New(server.URL, WithDeveloperToken("测试令牌")) if err != nil { t.Fatal(err) } ctx := context.Background() uploaded, err := api.Upload(ctx, UploadRequest{ Name: "client-demo", Version: "1.0.0", FileName: "demo.pkg", File: bytes.NewBufferString("client package"), }) if err != nil { t.Fatal(err) } if uploaded.SHA256 == "" { t.Fatal("上传结果缺少 SHA-256") } packages, err := api.ListPackages(ctx) if err != nil || len(packages) != 1 { t.Fatalf("包列表错误: %v, %d", err, len(packages)) } latest, available, err := api.CheckUpdate(ctx, "client-demo", "0.9.0") if err != nil || !available || latest.Version != "1.0.0" { t.Fatalf("更新检查错误: %+v, %t, %v", latest, available, err) } versions, err := api.ListVersions(ctx, "client-demo") if err != nil || len(versions) != 1 { t.Fatalf("版本列表错误: %v, %d", err, len(versions)) } output := filepath.Join(t.TempDir(), "download.pkg") downloaded, err := api.Download(ctx, "client-demo", "", output) if err != nil { t.Fatal(err) } if downloaded.SHA256 != uploaded.SHA256 { t.Fatalf("下载校验值不一致: %s != %s", downloaded.SHA256, uploaded.SHA256) } content, err := os.ReadFile(output) if err != nil || string(content) != "client package" { t.Fatalf("下载内容错误: %q, %v", content, err) } } func TestClientWatchUpdates(t *testing.T) { store, err := registry.New(t.TempDir()) if err != nil { t.Fatal(err) } server := httptest.NewServer((&httpapi.Server{Registry: store, DeveloperToken: "测试令牌"}).Handler()) defer server.Close() api, err := New(server.URL, WithDeveloperToken("测试令牌")) if err != nil { t.Fatal(err) } ctx, cancel := context.WithCancel(context.Background()) defer cancel() updates, err := api.WatchUpdates(ctx, "client-demo") if err != nil { t.Fatal(err) } go func() { _, _ = api.Upload(context.Background(), UploadRequest{ Name: "client-demo", Version: "2.0.0", FileName: "demo.pkg", File: bytes.NewBufferString("new package"), }) }() select { case update := <-updates: if update.Package.Name != "client-demo" || update.Package.Version != "2.0.0" { t.Fatalf("通知内容错误: %+v", update) } case <-time.After(2 * time.Second): t.Fatal("等待更新通知超时") } } func TestCompareVersions(t *testing.T) { cases := []struct { left string right string want int }{ {left: "1.10.0", right: "1.9.0", want: 1}, {left: "v1.0.0", right: "1.0.0", want: 0}, {left: "1.0.0", right: "2.0.0", want: -1}, } for _, item := range cases { if got := CompareVersions(item.left, item.right); got != item.want { t.Fatalf("CompareVersions(%q, %q) = %d, want %d", item.left, item.right, got, item.want) } } }