package checker import ( "context" "net/http" "net/http/httptest" "testing" "time" sdk "git.happydns.org/checker-sdk-go/checker" ) const disconnectFakeFeed = `{ "categories": { "Advertising": [ { "Evil Corp": { "https://evilcorp.com": ["tracker.com", "sub.example.org"] } } ], "Analytics": [ { "Metrics Inc": { "https://metrics.io": ["analytics.net"] } } ] } }` func newDisconnectTestSource(srv *httptest.Server) *disconnectSource { return &disconnectSource{ cache: newFeedCache(time.Hour, disconnectFetch(srv.URL)), } } func TestDisconnectSource_Listed(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { _, _ = w.Write([]byte(disconnectFakeFeed)) })) defer srv.Close() s := newDisconnectTestSource(srv) r := s.Query(context.Background(), "tracker.com", "tracker.com", sdk.CheckerOptions{"enable_disconnect": true})[0] if !r.Enabled || r.Error != "" { t.Fatalf("expected enabled with no error, got %+v", r) } if len(r.Evidence) == 0 { t.Fatalf("expected evidence, got none") } found := false for _, e := range r.Evidence { if e.Value == "Advertising" { found = true if e.Extra["company"] != "Evil Corp" { t.Errorf("expected company 'Evil Corp', got %q", e.Extra["company"]) } } } if !found { t.Errorf("expected Advertising evidence, got %+v", r.Evidence) } if listed, sev := s.Evaluate(r); !listed || sev != SeverityWarn { t.Errorf("expected (true, warn), got (%v, %q)", listed, sev) } } func TestDisconnectSource_SubdomainInFeed(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { _, _ = w.Write([]byte(disconnectFakeFeed)) })) defer srv.Close() // Feed has "sub.example.org"; querying registered domain "example.org" should match. s := newDisconnectTestSource(srv) r := s.Query(context.Background(), "example.org", "example.org", sdk.CheckerOptions{"enable_disconnect": true})[0] if !r.Enabled || r.Error != "" { t.Fatalf("expected enabled with no error, got %+v", r) } if len(r.Evidence) == 0 { t.Errorf("expected subdomain match evidence, got none") } } func TestDisconnectSource_NotListed(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { _, _ = w.Write([]byte(disconnectFakeFeed)) })) defer srv.Close() s := newDisconnectTestSource(srv) r := s.Query(context.Background(), "clean.example.com", "clean.example.com", sdk.CheckerOptions{"enable_disconnect": true})[0] if !r.Enabled || r.Error != "" { t.Fatalf("expected enabled with no error, got %+v", r) } if len(r.Evidence) != 0 { t.Errorf("expected no evidence for clean domain, got %+v", r.Evidence) } if listed, _ := s.Evaluate(r); listed { t.Errorf("expected not listed for clean domain") } } func TestDisconnectSource_Disabled(t *testing.T) { s := &disconnectSource{cache: newFeedCache(time.Hour, disconnectFetch("http://nope"))} r := s.Query(context.Background(), "tracker.com", "tracker.com", sdk.CheckerOptions{"enable_disconnect": false})[0] if r.Enabled { t.Errorf("expected disabled result, got %+v", r) } } func TestDisconnectSource_HTTPError(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusInternalServerError) })) defer srv.Close() s := newDisconnectTestSource(srv) r := s.Query(context.Background(), "tracker.com", "tracker.com", sdk.CheckerOptions{"enable_disconnect": true})[0] if r.Error == "" { t.Errorf("expected error on HTTP 500, got empty error") } }