checker-blacklist/checker/botvrij_test.go
Pierre-Olivier Mercier c3cda1f104
All checks were successful
continuous-integration/drone/tag Build is passing
continuous-integration/drone/push Build is passing
Replace per-source enable booleans with SourcePrecheck and bump SDK to v1.9.0
Sources that always work (botvrij, disconnect, oisd, openphish, phishtank, quad9) drop their user-facing enable_* option; the rule's enabled/disabled state is now solely controlled by the SDK rule toggle. Sources that require credentials (criminalip, malwarebazaar, otx, pulsedive, safebrowsing, threatfox, urlhaus, virustotal) instead implement the new SourcePrecheck interface so the host UI can surface "not configured" before attempting a query.
2026-05-20 14:26:42 +08:00

84 lines
2.5 KiB
Go

package checker
import (
"context"
"net/http"
"net/http/httptest"
"testing"
)
const botvrijFakeFeed = `# Botvrij.eu IOC list - domains
# comment line
evil.com
malware.example.org
c2.badactor.net
`
func TestBotvrijSource_Listed_ExactMatch(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
_, _ = w.Write([]byte(botvrijFakeFeed))
}))
defer srv.Close()
s := &botvrijSource{cache: newBotvrijCache(srv.URL)}
r := s.Query(context.Background(), "evil.com", "evil.com", nil)[0]
if !r.Enabled || r.Error != "" {
t.Fatalf("expected enabled and no error, got %+v", r)
}
if len(r.Evidence) != 1 || r.Evidence[0].Value != "evil.com" {
t.Errorf("expected evidence [evil.com], got %+v", r.Evidence)
}
if listed, sev := s.Evaluate(r); !listed || sev != SeverityCrit {
t.Errorf("expected (true, crit), got (%v, %q)", listed, sev)
}
}
func TestBotvrijSource_Listed_SubdomainInFeed(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
_, _ = w.Write([]byte(botvrijFakeFeed))
}))
defer srv.Close()
// Feed has "malware.example.org"; querying registered "example.org" should match.
s := &botvrijSource{cache: newBotvrijCache(srv.URL)}
r := s.Query(context.Background(), "sub.example.org", "example.org", nil)[0]
if len(r.Evidence) != 1 || r.Evidence[0].Value != "malware.example.org" {
t.Errorf("expected subdomain match, got %+v", r.Evidence)
}
if listed, _ := s.Evaluate(r); !listed {
t.Error("expected listed=true")
}
}
func TestBotvrijSource_NotListed(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
_, _ = w.Write([]byte(botvrijFakeFeed))
}))
defer srv.Close()
s := &botvrijSource{cache: newBotvrijCache(srv.URL)}
r := s.Query(context.Background(), "safe.com", "safe.com", nil)[0]
if !r.Enabled || r.Error != "" || len(r.Evidence) != 0 {
t.Fatalf("expected clean result, got %+v", r)
}
if listed, _ := s.Evaluate(r); listed {
t.Error("expected listed=false")
}
}
func TestBotvrijSource_HTTPError(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
}))
defer srv.Close()
s := &botvrijSource{cache: newBotvrijCache(srv.URL)}
r := s.Query(context.Background(), "evil.com", "evil.com", nil)[0]
if r.Error == "" || r.Error != "botvrij HTTP 500" {
t.Errorf("expected HTTP 500 error, got %q", r.Error)
}
}