package releases import ( "net/http/httptest" "os" "path/filepath" "strings" "testing" "ymhut-box/server/unified-management/internal/config" "ymhut-box/server/unified-management/internal/db" ) func TestCompareVersion(t *testing.T) { cases := []struct { a string b string want int }{ {"2.0.6.31", "2.0.6.2", 1}, {"2.0.10", "2.0.9", 1}, {"2.0.6.2", "2.0.6.31", -1}, {"2.0.6", "2.0.6.0", 0}, } for _, tc := range cases { if got := compareVersion(tc.a, tc.b); got != tc.want { t.Fatalf("compareVersion(%q, %q) = %d, want %d", tc.a, tc.b, got, tc.want) } } } func TestDetectPackageMetadata(t *testing.T) { platform, arch := detectPlatform("YMhutBox_2.0.6.31_x64.msix") if platform != "windows" || arch != "x64" { t.Fatalf("detectPlatform returned %s/%s", platform, arch) } if version := detectVersion("YMhut_Box_WinUI_Setup_2.0.6.31.exe"); version != "2.0.6.31" { t.Fatalf("detectVersion returned %q", version) } } func TestSaveUploadedPackageWritesFileAndUpdatesManifest(t *testing.T) { dir := t.TempDir() cfg := &config.Config{ BaseDir: dir, StorageDir: filepath.Join(dir, "storage"), DataDir: filepath.Join(dir, "data"), UpdatePublicDir: filepath.Join(dir, "data", "update", "public"), DownloadsDir: filepath.Join(dir, "data", "update", "public", "downloads"), BaseURL: "https://update.ymhut.cn", Database: config.DatabaseConfig{ Provider: "sqlite", SQLitePath: filepath.Join(dir, "storage", "unified.sqlite"), HealthIntervalSec: 30, }, } store, err := db.Open(cfg) if err != nil { t.Fatal(err) } defer store.Close() service := NewService(cfg, store) req := httptest.NewRequest("POST", "https://update.ymhut.cn/api/admin/releases/packages", nil) pkg, err := service.SaveUploadedPackage(req, strings.NewReader("package bytes"), UploadOptions{ FileName: "YMhut_Box_WinUI_Setup_2.0.6.31.exe", UpdateManifest: true, }, "admin") if err != nil { t.Fatal(err) } if pkg.Version != "2.0.6.31" || pkg.SHA256 == "" || pkg.Size == 0 { t.Fatalf("unexpected package metadata: %#v", pkg) } if _, err := os.Stat(filepath.Join(cfg.DownloadsDir, pkg.FileName)); err != nil { t.Fatal(err) } manifest := readJSON(filepath.Join(cfg.UpdatePublicDir, "update-info.json")) if manifest["download_url"] != pkg.URL || manifest["package_sha256"] != pkg.SHA256 { t.Fatalf("manifest not updated: %#v", manifest) } } func TestSaveUploadedPackageRejectsUnsafeName(t *testing.T) { dir := t.TempDir() cfg := &config.Config{ BaseDir: dir, StorageDir: filepath.Join(dir, "storage"), DataDir: filepath.Join(dir, "data"), UpdatePublicDir: filepath.Join(dir, "data", "update", "public"), DownloadsDir: filepath.Join(dir, "data", "update", "public", "downloads"), Database: config.DatabaseConfig{ Provider: "sqlite", SQLitePath: filepath.Join(dir, "storage", "unified.sqlite"), HealthIntervalSec: 30, }, } store, err := db.Open(cfg) if err != nil { t.Fatal(err) } defer store.Close() service := NewService(cfg, store) _, err = service.SaveUploadedPackage(httptest.NewRequest("POST", "/", nil), strings.NewReader("x"), UploadOptions{FileName: "../evil.exe"}, "admin") if err == nil { t.Fatal("expected unsafe filename to be rejected") } }