chromium/chrome/browser/autocomplete/search_provider_unittest.cc

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "components/omnibox/browser/search_provider.h"

#include <stddef.h>

#include <memory>
#include <string>

#include "base/base64.h"
#include "base/command_line.h"
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/field_trial.h"
#include "base/run_loop.h"
#include "base/strings/escape.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "chrome/browser/autocomplete/autocomplete_classifier_factory.h"
#include "chrome/browser/autocomplete/chrome_autocomplete_provider_client.h"
#include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h"
#include "chrome/browser/autocomplete/document_suggestions_service_factory.h"
#include "chrome/browser/autocomplete/remote_suggestions_service_factory.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/signin/chrome_signin_client_factory.h"
#include "chrome/browser/signin/chrome_signin_client_test_util.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "components/google/core/common/google_switches.h"
#include "components/history/core/browser/history_service.h"
#include "components/lens/proto/server/lens_overlay_response.pb.h"
#include "components/omnibox/browser/autocomplete_controller.h"
#include "components/omnibox/browser/autocomplete_input.h"
#include "components/omnibox/browser/autocomplete_match.h"
#include "components/omnibox/browser/autocomplete_provider.h"
#include "components/omnibox/browser/autocomplete_provider_listener.h"
#include "components/omnibox/browser/history_url_provider.h"
#include "components/omnibox/browser/omnibox_feature_configs.h"
#include "components/omnibox/browser/omnibox_field_trial.h"
#include "components/omnibox/browser/remote_suggestions_service.h"
#include "components/omnibox/browser/suggestion_answer.h"
#include "components/omnibox/common/omnibox_features.h"
#include "components/prefs/pref_service.h"
#include "components/search_engines/search_engine_type.h"
#include "components/search_engines/search_engines_switches.h"
#include "components/search_engines/search_terms_data.h"
#include "components/search_engines/template_url.h"
#include "components/search_engines/template_url_service.h"
#include "components/variations/scoped_variations_ids_provider.h"
#include "components/variations/variations_associated_data.h"
#include "content/public/test/browser_task_environment.h"
#include "net/http/http_util.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/metrics_proto/omnibox_event.pb.h"
#include "third_party/metrics_proto/omnibox_focus_type.pb.h"
#include "third_party/omnibox_proto/navigational_intent.pb.h"
#include "ui/base/device_form_factor.h"

ASCIIToUTF16;
_;

namespace {

// Returns the first match in |matches| with |allowed_to_be_default_match|
// set to true.
ACMatches::const_iterator FindDefaultMatch(const ACMatches& matches) {}

class SearchProviderForTest : public SearchProvider {};

SearchProviderForTest::SearchProviderForTest(
    AutocompleteProviderClient* client,
    AutocompleteProviderListener* listener,
    Profile* profile)
    :{}

SearchProviderForTest::~SearchProviderForTest() = default;

void SearchProviderForTest::RecordDeletionResult(bool success) {}

class TestAutocompleteProviderClient : public ChromeAutocompleteProviderClient {};

std::unique_ptr<KeyedService> BuildRemoteSuggestionsServiceWithURLLoader(
    network::TestURLLoaderFactory* test_url_loader_factory,
    content::BrowserContext* context) {}

std::string SerializeAndEncodeEntityInfo(
    const omnibox::EntityInfo& entity_info) {}

}  // namespace

// SearchProviderFeatureTestComponent -----------------------------------------
// Handles field trial, feature flag, and command line state for SearchProvider
// tests. This is done as a base class, so that it runs before
// BrowserTaskEnvironment is initialized.

class SearchProviderFeatureTestComponent {};

SearchProviderFeatureTestComponent::SearchProviderFeatureTestComponent(
    const bool command_line_overrides) {}

// BaseSearchProviderTest -----------------------------------------------------

// Base class that configures following environment:
// . The TemplateURL default_t_url_ is set as the default provider.
// . The TemplateURL keyword_t_url_ is added to the TemplateURLService.
//   TemplateURL values are set by subclasses. Most tests use SearchProviderTest
//   with valid ones.
// . The URL created by using the search term term1_ with default_t_url_ is
//   added to history.
// . The URL created by using the search term keyword_term_ with keyword_t_url_
//   is added to history.
// . test_url_loader_factory_ is set as the URLLoaderFactory.
//
// Most tests use SearchProviderTest subclass, see below.
class BaseSearchProviderTest : public testing::Test,
                               public AutocompleteProviderListener {};

// SearchProviderTest ---------------------------------------------------------

// Test environment with valid suggest and search URL.
class SearchProviderTest : public BaseSearchProviderTest {};

// InvalidSearchProviderTest --------------------------------------------------

// Test environment without valid suggest and search URL.
class InvalidSearchProviderTest : public BaseSearchProviderTest {};

// Implementation of classes --------------------------------------------------

// static
const char BaseSearchProviderTest::kNotApplicable[] =;
const BaseSearchProviderTest::ExpectedMatch
    BaseSearchProviderTest::kEmptyExpectedMatch =;

void BaseSearchProviderTest::CustomizableSetUp(
    const std::string& search_url,
    const std::string& suggestions_url) {}

void BaseSearchProviderTest::TearDown() {}

void BaseSearchProviderTest::RunTest(TestData* cases,
                                     int num_cases,
                                     bool prefer_keyword) {}

void BaseSearchProviderTest::OnProviderUpdate(
    bool updated_matches,
    const AutocompleteProvider* provider) {}

void BaseSearchProviderTest::RunTillProviderDone() {}

void BaseSearchProviderTest::QueryForInput(const AutocompleteInput& input) {}

void BaseSearchProviderTest::QueryForInput(const std::u16string& text,
                                           bool prevent_inline_autocomplete,
                                           bool prefer_keyword) {}

void BaseSearchProviderTest::QueryForInputAndSetWYTMatch(
    const std::u16string& text,
    AutocompleteMatch* wyt_match) {}

void BaseSearchProviderTest::QueryForInputAndWaitForFetcherResponses(
    const std::u16string& text,
    const bool prefer_keyword,
    const std::string& default_fetcher_response,
    const std::string& keyword_fetcher_response) {}

GURL BaseSearchProviderTest::AddSearchToHistory(TemplateURL* t_url,
                                                std::u16string term,
                                                int visit_count) {}

bool BaseSearchProviderTest::FindMatchWithContents(
    const std::u16string& contents,
    AutocompleteMatch* match) {}

bool BaseSearchProviderTest::FindMatchWithDestination(
    const GURL& url,
    AutocompleteMatch* match) {}

void BaseSearchProviderTest::FinishDefaultSuggestQuery(
    const std::u16string& query_text) {}

void BaseSearchProviderTest::CheckMatches(
    const std::string& description,
    const size_t num_expected_matches,
    const ExpectedMatch expected_matches[],
    const ACMatches& matches) {}

void BaseSearchProviderTest::ClearAllResults() {}

// Actual Tests ---------------------------------------------------------------

// Make sure we query history for the default provider and a URLFetcher is
// created for the default provider suggest results.
TEST_F(SearchProviderTest, QueryDefaultProvider) {}

// Make sure we do NOT query history for the default provider. However a
// URLFetcher is created for the default provider suggest results.
TEST_F(SearchProviderTest, QueryDefaultProvider_LensSearchbox) {}

// Make sure we get a query-what-you-typed result from the default search
// provider even if the default search provider's keyword is renamed in the
// middle of processing the query.
TEST_F(SearchProviderTest, HasQueryWhatYouTypedIfDefaultKeywordChanges) {}

TEST_F(SearchProviderTest, HonorPreventInlineAutocomplete) {}

// Issues a query that matches the registered keyword and makes sure history
// is queried as well as URLFetchers getting created.
TEST_F(SearchProviderTest, QueryKeywordProvider) {}

TEST_F(SearchProviderTest, SendDataToSuggestAtAppropriateTimes) {}

TEST_F(SearchProviderTest, DontAutocompleteURLLikeTerms) {}

// A multiword search with one visit should not autocomplete until multiple
// words are typed.
TEST_F(SearchProviderTest, DontAutocompleteUntilMultipleWordsTyped) {}

// A multiword search with more than one visit should autocomplete immediately.
TEST_F(SearchProviderTest, AutocompleteMultipleVisitsImmediately) {}

// Autocompletion should work at a word boundary after a space, and should
// offer a suggestion for the trimmed search query.
TEST_F(SearchProviderTest, AutocompleteAfterSpace) {}

// Newer multiword searches should score more highly than older ones.
TEST_F(SearchProviderTest, ScoreNewerSearchesHigher) {}

// If ScoreHistoryResults doesn't properly clear its output vector it can skip
// scoring the actual results and just return results from a previous run.
TEST_F(SearchProviderTest, ResetResultsBetweenRuns) {}

// An autocompleted multiword search should not be replaced by a different
// autocompletion while the user is still typing a valid prefix unless the
// user has typed the prefix as a query before.
TEST_F(SearchProviderTest, DontReplacePreviousAutocompletion) {}

// Non-completable multiword searches should not crowd out single-word searches.
TEST_F(SearchProviderTest, DontCrowdOutSingleWords) {}

// Inline autocomplete matches regardless of case differences from the input.
TEST_F(SearchProviderTest, InlineMixedCaseMatches) {}

// Verifies AutocompleteControllers return results (including keyword
// results) in the right order and set descriptions for them correctly.
TEST_F(SearchProviderTest, KeywordOrderingAndDescriptions) {}

TEST_F(SearchProviderTest, KeywordVerbatim) {}

// Verifies Navsuggest results don't set a TemplateURL, which Instant relies on.
// Also verifies that just the *first* navigational result is listed as a match
// if suggested relevance scores were not sent.
TEST_F(SearchProviderTest, NavSuggestNoSuggestedRelevanceScores) {}

// Verifies that the most relevant suggest results are added properly.
TEST_F(SearchProviderTest, SuggestRelevance) {}

// Verifies that the default provider abandons suggested relevance scores
// when in keyword mode.  This should happen regardless of whether the
// keyword provider returns suggested relevance scores.
TEST_F(SearchProviderTest, DefaultProviderNoSuggestRelevanceInKeywordMode) {}

// Verifies that suggest results with relevance scores are added
// properly when using the default fetcher.  When adding a new test
// case to this test, please consider adding it to the tests in
// KeywordFetcherSuggestRelevance below.
TEST_F(SearchProviderTest, DefaultFetcherSuggestRelevance) {}

// Verifies that suggest results with relevance scores are added
// properly when using the keyword fetcher.  This is similar to the
// test DefaultFetcherSuggestRelevance above but this uses inputs that
// trigger keyword suggestions (i.e., "k a" rather than "a") and has
// different expectations (because now the results are a mix of
// keyword suggestions and default provider suggestions).  When a new
// test is added to this TEST_F, please consider if it would be
// appropriate to add to DefaultFetcherSuggestRelevance as well.
TEST_F(SearchProviderTest, KeywordFetcherSuggestRelevance) {}

TEST_F(SearchProviderTest, DontInlineAutocompleteAsynchronously) {}

TEST_F(SearchProviderTest, DontCacheCalculatorSuggestions) {}

TEST_F(SearchProviderTest, LocalAndRemoteRelevances) {}

// Verifies suggest relevance behavior for URL input.
TEST_F(SearchProviderTest, DefaultProviderSuggestRelevanceScoringUrlInput) {}

// A basic test that verifies the field trial triggered parsing logic.
TEST_F(SearchProviderTest, FieldTrialTriggeredParsing) {}

// A basic test that verifies the specific type identifier parsing logic.
TEST_F(SearchProviderTest, SpecificTypeIdentifierParsing) {}

// Verifies inline autocompletion of navigational results.
TEST_F(SearchProviderTest, NavigationInline) {}

// Verifies that "http://" is not trimmed for input that is a leading substring.
TEST_F(SearchProviderTest, NavigationInlineSchemeSubstring) {}

// Verifies that input "h" matches navsuggest "http://www.[h]ttp.com/http" and
// "http://www." is trimmed.
TEST_F(SearchProviderTest, NavigationInlineDomainClassify) {}

// Verifies navsuggests prefer prefix matching even when a URL prefix prevents
// the input from being a perfect prefix of the suggest text; e.g., the input
// 'moon.com', matches 'http://[moon.com]/moon' and the 2nd 'moon' is unmatched.
TEST_F(SearchProviderTest, NavigationPrefixClassify) {}

// Verifies navsuggests prohibit mid-word matches; e.g., 'f[acebook].com'.
TEST_F(SearchProviderTest, NavigationMidWordClassify) {}

// Verifies navsuggests break user and suggest texts on words;
// e.g., the input 'duck', matches 'yellow-animals.com/[duck]'
TEST_F(SearchProviderTest, NavigationWordBreakClassify) {}

// Verifies that "http://" is trimmed in the general case.
TEST_F(SearchProviderTest, DoTrimHttpScheme) {}

// Verifies that "http://" is not trimmed for input that has a scheme, even if
// the input doesn't match the URL.
TEST_F(SearchProviderTest, DontTrimHttpSchemeIfInputHasScheme) {}

// Verifies that "https://" is not trimmed for input that has a (non-matching)
// scheme.
TEST_F(SearchProviderTest, DontTrimHttpsSchemeIfInputHasScheme) {}

// Verifies that "https://" is trimmed in the general case.
TEST_F(SearchProviderTest, DoTrimHttpsScheme) {}

// Verify entity suggestion parsing.
TEST_F(SearchProviderTest, ParseEntitySuggestion) {}

// A basic test that verifies the prefetch metadata parsing logic.
TEST_F(SearchProviderTest, PrefetchMetadataParsing) {}

TEST_F(SearchProviderTest, XSSIGuardedJSONParsing_InvalidResponse) {}

// A basic test that verifies that the XSSI guarded JSON response is parsed
// correctly.
TEST_F(SearchProviderTest, XSSIGuardedJSONParsing_ValidResponses) {}

// Test that deletion url gets set on an AutocompleteMatch when available for a
// personalized query or a personalized URL.
TEST_F(SearchProviderTest, ParseDeletionUrl) {}

// Tests that all conditions must be met to send the current page URL in the
// suggest requests.
TEST_F(SearchProviderTest, CanSendRequestWithURL) {}

// SearchProviderRequestTest ---------------------------------------------------

class MockSearchProviderForTest
    : public testing::NiceMock<SearchProviderForTest> {};

MockSearchProviderForTest::MockSearchProviderForTest(
    AutocompleteProviderClient* client,
    AutocompleteProviderListener* listener,
    Profile* profile)
    :{}

// Test environment to verify whether the current page URL is sent in the
// suggest requests when all the conditions are met or not.
class SearchProviderRequestTest : public SearchProviderTest {};

TEST_F(SearchProviderRequestTest, SendRequestWithoutURL) {}

TEST_F(SearchProviderRequestTest, SendRequestWithURL) {}

TEST_F(SearchProviderRequestTest, SendRequestWithoutLensInteractionResponse) {}

TEST_F(SearchProviderRequestTest, SendRequestWithLensInteractionResponse) {}

TEST_F(SearchProviderTest, TestDeleteMatch) {}

TEST_F(SearchProviderTest, TestDeleteHistoryQueryMatch) {}

// Verifies that duplicates are preserved in AddMatchToMap().
TEST_F(SearchProviderTest, CheckDuplicateMatchesSaved) {}

TEST_F(SearchProviderTest, SuggestQueryUsesToken) {}

TEST_F(SearchProviderTest, AnswersCache) {}

TEST_F(SearchProviderTest, RemoveExtraAnswers) {}

TEST_F(SearchProviderTest, DuplicateCardAnswer) {}

TEST_F(SearchProviderTest, CopyAnswerToVerbatim) {}

TEST_F(SearchProviderTest, DoesNotProvideOnFocus) {}

TEST_F(InvalidSearchProviderTest, DoesNotSendSuggestRequests) {}

TEST_F(SearchProviderTest, SendsWarmUpRequestOnFocus) {}

// SearchProviderCommandLineOverrideTest -------------------------------------
//
// Like SearchProviderTest.  The only addition is that it sets additional
// command line flags in SearchProviderFeatureTestComponent.
class SearchProviderCommandLineOverrideTest : public SearchProviderTest {};

TEST_F(SearchProviderCommandLineOverrideTest, CommandLineOverrides) {}