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 := `
  1. Bing answer

    Bing answer text.

    Source snippet

    Source
  2. People also ask

  3. Organic result

    Snippet

` 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 := `
  1. Organic result

    Snippet

` 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 := `
  1. Organic result

    Snippet

` 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 := `
  1. Organic result

    Snippet

` 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) } } }