package research_test import ( "context" "encoding/json" "net/http" "net/http/httptest" "testing" "git.georgsen.dk/hwlab/internal/research" ) func TestSearXNGSearch_ValidResponse(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/search" { t.Errorf("unexpected path: %s", r.URL.Path) } if r.URL.Query().Get("format") != "json" { t.Errorf("expected format=json, got %s", r.URL.Query().Get("format")) } if r.URL.Query().Get("q") == "" { t.Error("expected non-empty q param") } resp := map[string]interface{}{ "results": []map[string]interface{}{ {"title": "Intel i350 NIC", "url": "https://ark.intel.com/i350", "content": "Quad-port Gigabit Ethernet adapter"}, {"title": "Intel i350 Datasheet", "url": "https://intel.com/datasheet", "content": "Technical specs for i350 series"}, }, } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(resp) })) defer srv.Close() client := research.NewSearXNGClient(srv.URL) results, err := client.Search(context.Background(), "Intel NIC i350") if err != nil { t.Fatalf("unexpected error: %v", err) } if len(results) != 2 { t.Fatalf("expected 2 results, got %d", len(results)) } if results[0].Title != "Intel i350 NIC" { t.Errorf("unexpected title: %s", results[0].Title) } if results[0].URL != "https://ark.intel.com/i350" { t.Errorf("unexpected URL: %s", results[0].URL) } if results[0].Snippet != "Quad-port Gigabit Ethernet adapter" { t.Errorf("unexpected snippet (content): %s", results[0].Snippet) } } func TestSearXNGSearch_HTTP500(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) })) defer srv.Close() client := research.NewSearXNGClient(srv.URL) _, err := client.Search(context.Background(), "test query") if err == nil { t.Fatal("expected error for HTTP 500, got nil") } } func TestSearXNGSearch_EmptyResults(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { resp := map[string]interface{}{"results": []interface{}{}} w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(resp) })) defer srv.Close() client := research.NewSearXNGClient(srv.URL) results, err := client.Search(context.Background(), "something obscure") if err != nil { t.Fatalf("unexpected error: %v", err) } if len(results) != 0 { t.Errorf("expected 0 results, got %d", len(results)) } } func TestSearXNGSearch_QueryEncoding(t *testing.T) { var capturedQuery string srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { capturedQuery = r.URL.Query().Get("q") resp := map[string]interface{}{"results": []interface{}{}} w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(resp) })) defer srv.Close() client := research.NewSearXNGClient(srv.URL) _, err := client.Search(context.Background(), "Intel NIC i350 2.5G") if err != nil { t.Fatalf("unexpected error: %v", err) } if capturedQuery != "Intel NIC i350 2.5G" { t.Errorf("unexpected decoded query: %q", capturedQuery) } } func TestNewSearXNGClient_DefaultURL(t *testing.T) { // Empty baseURL should use the default LAN address client := research.NewSearXNGClient("") if client == nil { t.Fatal("expected non-nil client") } }