package scraper import ( "fmt" "net/http" "net/http/httptest" "testing" ) // newDetectServer serves a robots.txt that allows /api/ plus the given // version paths. Returns the server's fqdn (host:port). func newDetectServer(t *testing.T, versionPaths ...string) string { t.Helper() mux := http.NewServeMux() mux.HandleFunc("/robots.txt", func(w http.ResponseWriter, r *http.Request) { _, _ = fmt.Fprintln(w, "User-agent: *") _, _ = fmt.Fprintln(w, "Allow: /") }) for _, p := range versionPaths { p := p mux.HandleFunc(p, func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") _, _ = fmt.Fprintln(w, `{"version":"16.0.5"}`) }) } srv := httptest.NewServer(mux) t.Cleanup(srv.Close) return srv.Listener.Addr().String() } func TestDetectForgejo(t *testing.T) { // Forgejo serves BOTH endpoints; the Forgejo-native one must win. fqdn := newDetectServer(t, "/api/forgejo/v1/version", "/api/v1/version") typ, version, err := detectAt("http://" + fqdn) if err != nil { t.Fatalf("detect: %v", err) } if typ != TypeForgejo { t.Errorf("expected TypeForgejo, got %q", typ) } if version != "16.0.5" { t.Errorf("expected version 16.0.5, got %q", version) } } func TestDetectGitea(t *testing.T) { // Gitea serves only the shared /api/v1/version endpoint. fqdn := newDetectServer(t, "/api/v1/version") typ, version, err := detectAt("http://" + fqdn) if err != nil { t.Fatalf("detect: %v", err) } if typ != TypeGitea { t.Errorf("expected TypeGitea, got %q", typ) } if version != "16.0.5" { t.Errorf("expected version 16.0.5, got %q", version) } } func TestDetectUnknown(t *testing.T) { // A server that serves robots but no version endpoint. fqdn := newDetectServer(t) typ, version, err := detectAt("http://" + fqdn) if err != nil { t.Fatalf("detect: %v", err) } if typ != TypeUnknown { t.Errorf("expected TypeUnknown, got %q", typ) } if version != "" { t.Errorf("expected empty version, got %q", version) } } func TestDetectHonorsRobotsDisallow(t *testing.T) { mux := http.NewServeMux() mux.HandleFunc("/robots.txt", func(w http.ResponseWriter, r *http.Request) { _, _ = fmt.Fprintln(w, "User-agent: *") _, _ = fmt.Fprintln(w, "Disallow: /api/") }) mux.HandleFunc("/api/forgejo/v1/version", func(w http.ResponseWriter, r *http.Request) { _, _ = fmt.Fprintln(w, `{"version":"16.0.5"}`) }) srv := httptest.NewServer(mux) t.Cleanup(srv.Close) fqdn := srv.Listener.Addr().String() typ, version, err := detectAt("http://" + fqdn) if err != nil { t.Fatalf("detect: %v", err) } if typ != TypeUnknown { t.Errorf("expected TypeUnknown when /api/ is disallowed, got %q", typ) } if version != "" { t.Errorf("expected empty version when disallowed, got %q", version) } }