Files
openserp/core/query_extract_param_test.go
Rustem Kamalov 9cc69da758 feat(cli): clean search, add extract/format flags; harden engines & proxy rotation; fix bugs; update docs
- Add structured `search [engine] [query]` CLI: --limit/--lang/--region/--site/--file, --format (json|text|markdown|ndjson), --extract N, --search-timeout; Envelope and route logs to stderr with a --quiet default (fixes stdout pollution)
- Unify engines behind a single engineSpec registry (CLI + serve share it)
- Unify the extract knob to bool-or-int `extract=N` (drop extract_top); CLI and HTTP share core batch extraction, raw/rendered fetch, and clamp helpers
- Engines: Ecosia CF captcha detection (raw + browser), Yandex progressive-result wait, Google PAA poll + Has() existence probes, Bing title/desc attribute fallbacks
- Proxy: rotate challenged proxies out of the tag pool for one retry (X-Proxy-Attempts); browser health-ping skip window; opt-in WaitStable
2026-06-16 03:51:37 +03:00

74 lines
2.4 KiB
Go

package core
import (
"net/http"
"net/http/httptest"
"strconv"
"testing"
"github.com/gofiber/fiber/v2"
)
// TestInitFromContextExtractParams verifies how the unified extract knob and its
// tuning params map onto Query.Extract / Query.ExtractTop. Key behaviors:
// - extract is bool-or-int: extract=0/false off, extract=true/1 → top 1,
// extract=N → top N (clamped to [1,5]).
// - extract_mode/min_runes imply extraction (top defaults to 1), but an
// explicit extract=0 still wins over them.
func TestInitFromContextExtractParams(t *testing.T) {
t.Parallel()
tests := []struct {
name string
query string
wantExtract bool
wantTop int
}{
{"no params defaults off", "?text=q", false, 1},
{"extract=true means top 1", "?text=q&extract=true", true, 1},
{"extract=1 means top 1", "?text=q&extract=1", true, 1},
{"extract=3 means top 3", "?text=q&extract=3", true, 3},
{"extract=N clamps high", "?text=q&extract=99", true, 5},
{"extract=0 disables", "?text=q&extract=0", false, 1},
{"extract=false disables", "?text=q&extract=false", false, 1},
{"extract_mode implies extract", "?text=q&extract_mode=fast", true, 1},
{"min_runes implies extract", "?text=q&min_runes=200", true, 1},
{"explicit extract=0 overrides tuning", "?text=q&extract=0&extract_mode=fast", false, 1},
}
app := fiber.New()
app.Get("/probe", func(c *fiber.Ctx) error {
q := Query{}
if err := q.InitFromContext(c); err != nil {
return c.Status(http.StatusBadRequest).SendString(err.Error())
}
extract := "0"
if q.Extract {
extract = "1"
}
c.Set("X-Extract", extract)
c.Set("X-Extract-Top", strconv.Itoa(q.ExtractTop))
return c.SendStatus(http.StatusOK)
})
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/probe"+tt.query, nil)
resp, err := app.Test(req, -1)
if err != nil {
t.Fatalf("request failed: %v", err)
}
if resp.StatusCode != http.StatusOK {
t.Fatalf("unexpected status %d for %s", resp.StatusCode, tt.query)
}
gotExtract := resp.Header.Get("X-Extract") == "1"
if gotExtract != tt.wantExtract {
t.Errorf("%s: Extract = %v, want %v", tt.query, gotExtract, tt.wantExtract)
}
if got := resp.Header.Get("X-Extract-Top"); got != strconv.Itoa(tt.wantTop) {
t.Errorf("%s: ExtractTop = %s, want %d", tt.query, got, tt.wantTop)
}
})
}
}