Implement an API-first Go rewrite with local engine adapters, upstream fallback, and Nix-based tooling so searches can run without matching the original UI while preserving response compatibility. Made-with: Cursor
92 lines
2.4 KiB
Go
92 lines
2.4 KiB
Go
package engines
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"testing"
|
|
|
|
"github.com/ashie/gosearch/internal/contracts"
|
|
)
|
|
|
|
func TestBraveEngine_GatingAndHeader(t *testing.T) {
|
|
wantToken := "letmein"
|
|
wantAPIKey := "api-key"
|
|
|
|
transport := roundTripperFunc(func(r *http.Request) (*http.Response, error) {
|
|
if r.Header.Get("X-Subscription-Token") != wantAPIKey {
|
|
t.Fatalf("missing/incorrect X-Subscription-Token header: got %q", r.Header.Get("X-Subscription-Token"))
|
|
}
|
|
if r.URL.Host != "api.search.brave.com" {
|
|
t.Fatalf("unexpected host: %s", r.URL.Host)
|
|
}
|
|
if r.URL.Path != "/res/v1/web/search" {
|
|
t.Fatalf("unexpected path: %s", r.URL.Path)
|
|
}
|
|
// basic query assertions
|
|
q := r.URL.Query().Get("q")
|
|
if q != "hugo" {
|
|
t.Fatalf("unexpected q: %q", q)
|
|
}
|
|
|
|
body := `{
|
|
"web": {
|
|
"results": [
|
|
{"url":"https://example.com/a","title":"A","description":"B","age":"2024-06-03T00:00:00Z","thumbnail":{"src":"x"}}
|
|
]
|
|
}
|
|
}`
|
|
return httpResponse(http.StatusOK, body, "application/json"), nil
|
|
})
|
|
|
|
client := &http.Client{Transport: transport}
|
|
engine := &BraveEngine{
|
|
client: client,
|
|
apiKey: wantAPIKey,
|
|
accessGateToken: wantToken,
|
|
resultsPerPage: 20,
|
|
}
|
|
|
|
// Wrong token => no upstream call / unresponsive engine.
|
|
{
|
|
resp, err := engine.Search(context.Background(), contracts.SearchRequest{
|
|
Query: "hugo",
|
|
Pageno: 1,
|
|
Safesearch: 0,
|
|
Language: "en",
|
|
AccessToken: "wrong",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if len(resp.Results) != 0 {
|
|
t.Fatalf("expected no results on unauthorized, got %d", len(resp.Results))
|
|
}
|
|
if len(resp.UnresponsiveEngines) != 1 {
|
|
t.Fatalf("expected 1 unresponsive engine entry, got %v", resp.UnresponsiveEngines)
|
|
}
|
|
}
|
|
|
|
// Correct token => upstream call.
|
|
{
|
|
resp, err := engine.Search(context.Background(), contracts.SearchRequest{
|
|
Query: "hugo",
|
|
Pageno: 1,
|
|
Safesearch: 0,
|
|
Language: "en",
|
|
AccessToken: wantToken,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if len(resp.Results) != 1 {
|
|
t.Fatalf("expected 1 result, got %d", len(resp.Results))
|
|
}
|
|
if resp.Results[0].Title != "A" {
|
|
t.Fatalf("unexpected title: %q", resp.Results[0].Title)
|
|
}
|
|
if resp.Results[0].URL == nil || *resp.Results[0].URL != "https://example.com/a" {
|
|
t.Fatalf("unexpected url: %v", resp.Results[0].URL)
|
|
}
|
|
}
|
|
}
|
|
|