package gitea import ( "fmt" "net/http" "net/http/httptest" "strings" "testing" "software-station/internal/models" ) func TestFetchRepoInfo(t *testing.T) { mockSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Header.Get("Authorization") != "token test-token" { w.WriteHeader(http.StatusUnauthorized) return } w.Write([]byte(`{"description": "Test Repo", "topics": ["test"], "licenses": ["MIT"], "private": false, "avatar_url": "https://example.com/avatar.png"}`)) })) defer mockSrv.Close() desc, topics, license, isPrivate, avatarURL, err := FetchRepoInfo(mockSrv.URL, "test-token", "owner", "repo") if err != nil { t.Fatalf("unexpected error: %v", err) } if desc != "Test Repo" || len(topics) != 1 || topics[0] != "test" || license != "MIT" || isPrivate || avatarURL != "https://example.com/avatar.png" { t.Errorf("unexpected results: %s, %v, %s, %v, %s", desc, topics, license, isPrivate, avatarURL) } _, _, _, _, _, err = FetchRepoInfo(mockSrv.URL, "wrong-token", "owner", "repo") if err == nil { t.Error("expected error for unauthorized request") } } func TestFetchReleases(t *testing.T) { var srv *httptest.Server srv = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if strings.Contains(r.URL.Path, "releases") { w.Write([]byte(fmt.Sprintf(`[{"tag_name": "v1.0.0", "assets": [{"name": "test.exe", "size": 100, "browser_download_url": "%s/test.exe"}, {"name": "SHA256SUMS", "size": 50, "browser_download_url": "%s/SHA256SUMS"}]}]`, srv.URL, srv.URL))) } else if strings.Contains(r.URL.Path, "SHA256SUMS") { w.Write([]byte(`hash123 test.exe`)) } })) defer srv.Close() releases, err := FetchReleases(srv.URL, "", "owner", "repo") if err != nil { t.Fatalf("unexpected error: %v", err) } if len(releases) != 1 || releases[0].TagName != "v1.0.0" { t.Errorf("unexpected releases: %v", releases) } if len(releases[0].Assets) != 1 || releases[0].Assets[0].Name != "test.exe" || releases[0].Assets[0].SHA256 != "hash123" { t.Errorf("unexpected assets: %v", releases[0].Assets) } } func TestDetectOS(t *testing.T) { tests := []struct { filename string expected string }{ {"app.exe", models.OSWindows}, {"app.msi", models.OSWindows}, {"app_linux", models.OSLinux}, {"app.deb", models.OSLinux}, {"app.rpm", models.OSLinux}, {"app.dmg", models.OSMacOS}, {"app.pkg", models.OSMacOS}, {"app_freebsd", models.OSFreeBSD}, {"app_openbsd", models.OSOpenBSD}, {"app.apk", models.OSAndroid}, {"app_arm64", models.OSARM}, {"app_aarch64", models.OSARM}, {"unknown", models.OSUnknown}, } for _, tt := range tests { got := DetectOS(tt.filename) if got != tt.expected { t.Errorf("DetectOS(%s) = %s, expected %s", tt.filename, got, tt.expected) } } } func TestIsSBOM(t *testing.T) { tests := []struct { filename string expected bool }{ {"sbom.json", true}, {"cyclonedx.json", true}, {"spdx.json", true}, {"app.exe", false}, {"app.cdx.json", true}, {"app.spdx.json", true}, } for _, tt := range tests { if got := IsSBOM(tt.filename); got != tt.expected { t.Errorf("IsSBOM(%s) = %v, expected %v", tt.filename, got, tt.expected) } } } func TestFetchAndParseChecksumsError(t *testing.T) { mockSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotFound) })) defer mockSrv.Close() _, err := fetchAndParseChecksums(mockSrv.URL, "") if err == nil { t.Error("expected error for 404") } }