2026-05-11 14:30:58 +08:00
|
|
|
package app
|
|
|
|
|
|
|
|
|
|
import (
|
2026-05-11 19:48:21 +08:00
|
|
|
"errors"
|
2026-05-11 14:30:58 +08:00
|
|
|
"fmt"
|
|
|
|
|
"net/http"
|
|
|
|
|
"strings"
|
|
|
|
|
"testing"
|
2026-05-11 19:48:21 +08:00
|
|
|
|
|
|
|
|
"github.com/geo-platform/tenant-api/internal/shared/config"
|
2026-05-11 14:30:58 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestBrowserFetchDomainAllowedMatchesSubdomain(t *testing.T) {
|
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
|
|
if !browserFetchDomainAllowed("https://mbd.baidu.com/bh/m/detail/ar_10234112381636647949", []string{"baidu.com"}) {
|
|
|
|
|
t.Fatalf("expected baidu.com to allow mbd.baidu.com")
|
|
|
|
|
}
|
|
|
|
|
if browserFetchDomainAllowed("https://notbaidu.com/article", []string{"baidu.com"}) {
|
|
|
|
|
t.Fatalf("expected baidu.com not to allow notbaidu.com")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-11 19:48:21 +08:00
|
|
|
func TestShouldTryBrowserFetchFallbackIgnoresAllowedDomains(t *testing.T) {
|
2026-05-11 14:30:58 +08:00
|
|
|
t.Parallel()
|
|
|
|
|
|
2026-05-11 19:48:21 +08:00
|
|
|
svc := &KnowledgeService{
|
|
|
|
|
cfg: knowledgeRuntimeConfig{
|
|
|
|
|
BrowserFetch: config.BrowserFetchConfig{
|
|
|
|
|
Enabled: true,
|
|
|
|
|
Provider: "lightpanda",
|
|
|
|
|
ServiceURL: "http://browser-fetch:8082",
|
|
|
|
|
TriggerStatus: []int{500},
|
|
|
|
|
AllowedDomains: nil,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err := fmt.Errorf("webpage parser failed: status=%d body=invalid link", http.StatusInternalServerError)
|
|
|
|
|
if !svc.shouldTryBrowserFetchFallback("https://m.baidu.com/bh/m/detail/ar_x", err) {
|
|
|
|
|
t.Fatalf("expected fallback to trigger on status=500 regardless of allowed_domains")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
svc.cfg.BrowserFetch.Enabled = false
|
|
|
|
|
if svc.shouldTryBrowserFetchFallback("https://m.baidu.com/bh/m/detail/ar_x", err) {
|
|
|
|
|
t.Fatalf("expected fallback to be skipped when browser_fetch.enabled=false")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
svc.cfg.BrowserFetch.Enabled = true
|
|
|
|
|
svc.cfg.BrowserFetch.TriggerStatus = []int{502}
|
|
|
|
|
if svc.shouldTryBrowserFetchFallback("https://m.baidu.com/bh/m/detail/ar_x", err) {
|
|
|
|
|
t.Fatalf("expected fallback to be skipped when status not in trigger_status")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestSourceFetchExhaustedErrorIsFriendly(t *testing.T) {
|
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
|
|
primary := fmt.Errorf("webpage parser failed: status=500 body=invalid link")
|
|
|
|
|
fallback := fmt.Errorf("browser fetch timeout")
|
|
|
|
|
err := sourceFetchExhaustedError{URL: "https://m.baidu.com/x", Primary: primary, Fallback: fallback}
|
|
|
|
|
|
|
|
|
|
msg := err.Error()
|
|
|
|
|
if !strings.Contains(msg, "源文章解析失败") {
|
|
|
|
|
t.Fatalf("error message %q should contain friendly Chinese prompt", msg)
|
|
|
|
|
}
|
|
|
|
|
if strings.Contains(msg, "status=500") || strings.Contains(msg, "invalid link") {
|
|
|
|
|
t.Fatalf("error message %q should not leak technical details", msg)
|
|
|
|
|
}
|
|
|
|
|
if !errors.Is(err, primary) {
|
|
|
|
|
t.Fatalf("expected errors.Is(err, primary) to be true")
|
2026-05-11 14:30:58 +08:00
|
|
|
}
|
|
|
|
|
}
|