package bing
import (
"bytes"
"os"
"strings"
"testing"
"github.com/karust/openserp/core"
)
// TestParseHTMLFixtureExtractsRealFeatures guards the live SERP fixture.
func TestParseHTMLFixtureExtractsRealFeatures(t *testing.T) {
t.Parallel()
f, err := os.Open("testdata/search_results.html")
if err != nil {
t.Fatalf("open fixture: %v", err)
}
defer f.Close()
results, err := ParseHTML(f)
if err != nil {
t.Fatalf("ParseHTML() error = %v", err)
}
related := findFeature(results, core.ResultTypeRelatedSearches)
if related == nil {
t.Fatalf("expected related_searches feature in fixture")
}
if len(related.Items) == 0 {
t.Fatalf("related_searches feature has no items: %#v", related)
}
for _, r := range results {
for _, feature := range r.Features {
if feature.Type == core.ResultTypeAnswerBox && strings.Contains(feature.Title, "searches you might like") {
t.Fatalf("related-search module leaked into answer_box: %#v", feature)
}
}
}
for i, r := range results {
if strings.ContainsAny(r.Description, "\n\t") {
t.Fatalf("result %d description has raw whitespace: %q", i, r.Description)
}
}
}
func TestParseHTMLExtractsSerpFeatures(t *testing.T) {
t.Parallel()
html := `
-
Bing answer
Bing answer text.
Source
-
People also ask
-
`
results, err := ParseHTML(bytes.NewReader([]byte(html)))
if err != nil {
t.Fatalf("ParseHTML() error = %v", err)
}
assertFeatureType(t, results, core.ResultTypeAnswerBox)
assertFeatureType(t, results, core.ResultTypeRelatedQuestions)
}
// TestParseHTMLExtractsRelatedSearchesFromBrsContainer guards the classic footer.
func TestParseHTMLExtractsRelatedSearchesFromBrsContainer(t *testing.T) {
t.Parallel()
html := `
-
`
results, err := ParseHTML(bytes.NewReader([]byte(html)))
if err != nil {
t.Fatalf("ParseHTML() error = %v", err)
}
assertFeatureType(t, results, core.ResultTypeRelatedSearches)
}
// TestParseHTMLExtractsSimilarSearchesFromInlineRail guards the inline rail.
func TestParseHTMLExtractsSimilarSearchesFromInlineRail(t *testing.T) {
t.Parallel()
html := `
-
-
`
results, err := ParseHTML(bytes.NewReader([]byte(html)))
if err != nil {
t.Fatalf("ParseHTML() error = %v", err)
}
related := findFeature(results, core.ResultTypeRelatedSearches)
if related == nil {
t.Fatalf("expected related_searches from inline rail")
}
if len(related.Items) != 2 {
t.Fatalf("expected 2 rail items (header chrome excluded), got %d: %#v", len(related.Items), related.Items)
}
for _, it := range related.Items {
if strings.Contains(it.Text, "Users also search") || it.Text == "Close" {
t.Fatalf("rail header chrome leaked as item: %q", it.Text)
}
}
}
func TestParseHTMLOrganicOnlyHasNoSerpFeatures(t *testing.T) {
t.Parallel()
html := `
-
`
results, err := ParseHTML(bytes.NewReader([]byte(html)))
if err != nil {
t.Fatalf("ParseHTML() error = %v", err)
}
assertNoFeatures(t, results)
}
func findFeature(results []core.SearchResult, want core.ResultType) *core.SerpFeature {
for _, result := range results {
for i := range result.Features {
if result.Features[i].Type == want {
return &result.Features[i]
}
}
}
return nil
}
func assertFeatureType(t *testing.T, results []core.SearchResult, want core.ResultType) {
t.Helper()
for _, result := range results {
for _, feature := range result.Features {
if feature.Type == want {
return
}
}
}
t.Fatalf("expected feature type %q in %#v", want, results)
}
func assertNoFeatures(t *testing.T, results []core.SearchResult) {
t.Helper()
for _, result := range results {
if len(result.Features) > 0 {
t.Fatalf("expected no features, got %#v", result.Features)
}
}
}