blob: 584a9c5d8769c9c3201b48933a7d02e04aaaba60 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/omnibox/browser/zero_suggest_provider.h"
#include <list>
#include <map>
#include <memory>
#include <string>
#include "base/metrics/field_trial.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "build/build_config.h"
#include "components/history/core/browser/top_sites.h"
#include "components/omnibox/browser/autocomplete_provider_listener.h"
#include "components/omnibox/browser/mock_autocomplete_provider_client.h"
#include "components/omnibox/browser/omnibox_field_trial.h"
#include "components/omnibox/browser/omnibox_prefs.h"
#include "components/omnibox/browser/test_scheme_classifier.h"
#include "components/omnibox/common/omnibox_features.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "components/search_engines/omnibox_focus_type.h"
#include "components/search_engines/template_url.h"
#include "components/search_engines/template_url_service.h"
#include "components/variations/entropy_provider.h"
#include "components/variations/scoped_variations_ids_provider.h"
#include "components/variations/variations_associated_data.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"
namespace {
class FakeAutocompleteProviderClient : public MockAutocompleteProviderClient {
public:
FakeAutocompleteProviderClient()
: template_url_service_(new TemplateURLService(nullptr, 0)),
pref_service_(new TestingPrefServiceSimple()) {
pref_service_->registry()->RegisterStringPref(
omnibox::kZeroSuggestCachedResults, "");
}
FakeAutocompleteProviderClient(const FakeAutocompleteProviderClient&) =
delete;
FakeAutocompleteProviderClient& operator=(
const FakeAutocompleteProviderClient&) = delete;
bool SearchSuggestEnabled() const override { return true; }
TemplateURLService* GetTemplateURLService() override {
return template_url_service_.get();
}
TemplateURLService* GetTemplateURLService() const override {
return template_url_service_.get();
}
PrefService* GetPrefs() const override { return pref_service_.get(); }
bool IsPersonalizedUrlDataCollectionActive() const override { return true; }
void Classify(
const std::u16string& text,
bool prefer_keyword,
bool allow_exact_keyword_match,
metrics::OmniboxEventProto::PageClassification page_classification,
AutocompleteMatch* match,
GURL* alternate_nav_url) override {
// Populate enough of |match| to keep the ZeroSuggestProvider happy.
match->type = AutocompleteMatchType::URL_WHAT_YOU_TYPED;
match->destination_url = GURL(text);
}
const AutocompleteSchemeClassifier& GetSchemeClassifier() const override {
return scheme_classifier_;
}
private:
std::unique_ptr<TemplateURLService> template_url_service_;
std::unique_ptr<TestingPrefServiceSimple> pref_service_;
TestSchemeClassifier scheme_classifier_;
};
} // namespace
class ZeroSuggestProviderTest : public testing::TestWithParam<std::string>,
public AutocompleteProviderListener {
public:
ZeroSuggestProviderTest() = default;
ZeroSuggestProviderTest(const ZeroSuggestProviderTest&) = delete;
ZeroSuggestProviderTest& operator=(const ZeroSuggestProviderTest&) = delete;
void SetUp() override;
protected:
// AutocompleteProviderListener:
void OnProviderUpdate(bool updated_matches,
const AutocompleteProvider* provider) override;
network::TestURLLoaderFactory* test_loader_factory() {
return client_->test_url_loader_factory();
}
GURL GetSuggestURL(
metrics::OmniboxEventProto::PageClassification page_classification) {
TemplateURLRef::SearchTermsArgs search_terms_args;
search_terms_args.page_classification = page_classification;
search_terms_args.focus_type = OmniboxFocusType::ON_FOCUS;
return RemoteSuggestionsService::EndpointUrl(
search_terms_args, client_->GetTemplateURLService());
}
AutocompleteInput OnFocusInputForNTP() {
AutocompleteInput input(u"", metrics::OmniboxEventProto::NTP_REALBOX,
TestSchemeClassifier());
input.set_focus_type(OmniboxFocusType::ON_FOCUS);
return input;
}
AutocompleteInput PrefetchingInputForNTP() {
AutocompleteInput input(u"", metrics::OmniboxEventProto::NTP_ZPS_PREFETCH,
TestSchemeClassifier());
input.set_focus_type(OmniboxFocusType::ON_FOCUS);
return input;
}
AutocompleteInput PrefixInputForNTP() {
AutocompleteInput input(u"foobar", metrics::OmniboxEventProto::NTP_REALBOX,
TestSchemeClassifier());
input.set_focus_type(OmniboxFocusType::DEFAULT);
return input;
}
AutocompleteInput OnFocusInputForWeb() {
std::string input_url = "https://example.com/";
AutocompleteInput input(base::ASCIIToUTF16(input_url),
metrics::OmniboxEventProto::OTHER,
TestSchemeClassifier());
input.set_current_url(GURL(input_url));
input.set_focus_type(OmniboxFocusType::ON_FOCUS);
return input;
}
AutocompleteInput OnClobberInputForWeb() {
AutocompleteInput input(u"", metrics::OmniboxEventProto::OTHER,
TestSchemeClassifier());
input.set_current_url(GURL("https://example.com/"));
input.set_focus_type(OmniboxFocusType::DELETED_PERMANENT_TEXT);
return input;
}
AutocompleteInput PrefixInputForWeb() {
std::string input_url = "https://example.com/";
AutocompleteInput input(base::ASCIIToUTF16(input_url),
metrics::OmniboxEventProto::OTHER,
TestSchemeClassifier());
input.set_current_url(GURL(input_url));
input.set_focus_type(OmniboxFocusType::DEFAULT);
return input;
}
AutocompleteInput OnFocusInputForSRP() {
std::string input_url = "https://example.com/";
AutocompleteInput input(base::ASCIIToUTF16(input_url),
metrics::OmniboxEventProto::
SEARCH_RESULT_PAGE_NO_SEARCH_TERM_REPLACEMENT,
TestSchemeClassifier());
input.set_current_url(GURL(input_url));
input.set_focus_type(OmniboxFocusType::ON_FOCUS);
return input;
}
AutocompleteInput OnClobberInputForSRP() {
AutocompleteInput input(u"",
metrics::OmniboxEventProto::
SEARCH_RESULT_PAGE_NO_SEARCH_TERM_REPLACEMENT,
TestSchemeClassifier());
input.set_current_url(GURL("https://example.com/"));
input.set_focus_type(OmniboxFocusType::DELETED_PERMANENT_TEXT);
return input;
}
AutocompleteInput PrefixInputForSRP() {
std::string input_url = "https://example.com/";
AutocompleteInput input(base::ASCIIToUTF16(input_url),
metrics::OmniboxEventProto::
SEARCH_RESULT_PAGE_NO_SEARCH_TERM_REPLACEMENT,
TestSchemeClassifier());
input.set_current_url(GURL(input_url));
input.set_focus_type(OmniboxFocusType::DEFAULT);
return input;
}
base::test::SingleThreadTaskEnvironment task_environment_;
std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_list_;
variations::ScopedVariationsIdsProvider scoped_variations_ids_provider_{
variations::VariationsIdsProvider::Mode::kUseSignedInState};
std::unique_ptr<FakeAutocompleteProviderClient> client_;
scoped_refptr<ZeroSuggestProvider> provider_;
bool provider_did_notify_;
};
void ZeroSuggestProviderTest::SetUp() {
client_ = std::make_unique<FakeAutocompleteProviderClient>();
TemplateURLService* template_url_service = client_->GetTemplateURLService();
template_url_service->Load();
// Verify that Google is the default search provider.
ASSERT_EQ(SEARCH_ENGINE_GOOGLE,
template_url_service->GetDefaultSearchProvider()->GetEngineType(
template_url_service->search_terms_data()));
provider_ = ZeroSuggestProvider::Create(client_.get(), this);
provider_did_notify_ = false;
// Ensure the cache is empty.
PrefService* prefs = client_->GetPrefs();
prefs->SetString(omnibox::kZeroSuggestCachedResults, "");
scoped_feature_list_ = std::make_unique<base::test::ScopedFeatureList>();
scoped_feature_list_->InitAndEnableFeature(omnibox::kZeroSuggestPrefetching);
}
void ZeroSuggestProviderTest::OnProviderUpdate(
bool updated_matches,
const AutocompleteProvider* provider) {
provider_did_notify_ = true;
}
TEST_F(ZeroSuggestProviderTest, AllowZeroPrefixSuggestions_NTP) {
AutocompleteInput onfocus_ntp_input = OnFocusInputForNTP();
EXPECT_CALL(*client_, IsAuthenticated())
.WillRepeatedly(testing::Return(false));
// Enable on-focus zero-suggest for signed-out users.
{
base::test::ScopedFeatureList features;
features.InitAndEnableFeature(omnibox::kZeroSuggestOnNTPForSignedOutUsers);
ZeroSuggestProvider::ResultType result_type = ZeroSuggestProvider::NONE;
ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), onfocus_ntp_input, &result_type);
EXPECT_EQ(ZeroSuggestProvider::REMOTE_NO_URL, result_type);
}
// Disable on-focus zero-suggest for signed-out users.
{
base::test::ScopedFeatureList features;
features.InitAndDisableFeature(omnibox::kZeroSuggestOnNTPForSignedOutUsers);
EXPECT_CALL(*client_, IsAuthenticated())
.WillRepeatedly(testing::Return(false));
ZeroSuggestProvider::ResultType result_type = ZeroSuggestProvider::NONE;
ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), onfocus_ntp_input, &result_type);
EXPECT_EQ(ZeroSuggestProvider::NONE, result_type);
}
}
TEST_F(ZeroSuggestProviderTest,
AllowZeroPrefixSuggestions_ContextualWebAndSRP) {
AutocompleteInput prefix_web_input = PrefixInputForWeb();
AutocompleteInput prefix_srp_input = PrefixInputForSRP();
AutocompleteInput on_focus_web_input = OnFocusInputForWeb();
AutocompleteInput on_focus_srp_input = OnFocusInputForSRP();
AutocompleteInput on_clobber_web_input = OnClobberInputForWeb();
AutocompleteInput on_clobber_srp_input = OnClobberInputForSRP();
ZeroSuggestProvider::ResultType result_type;
// Disable on-clobber for OTHER and SRP.
// Enable on-focus for OTHER and SRP.
{
base::test::ScopedFeatureList features;
features.InitWithFeatures(
/*enabled_features=*/
{omnibox::kFocusTriggersContextualWebZeroSuggest,
omnibox::kFocusTriggersSRPZeroSuggest},
/*disabled_features=*/{
omnibox::kClobberTriggersContextualWebZeroSuggest,
omnibox::kClobberTriggersSRPZeroSuggest,
});
EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), prefix_web_input, &result_type));
EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), prefix_srp_input, &result_type));
EXPECT_TRUE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), on_focus_web_input, &result_type));
EXPECT_TRUE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), on_focus_srp_input, &result_type));
EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), on_clobber_web_input, &result_type));
EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), on_clobber_srp_input, &result_type));
}
// Enable on-clobber and on-focus for OTHER.
// Disable on-clobber and on-focus for SRP.
{
base::test::ScopedFeatureList features;
features.InitWithFeatures(
/*enabled_features=*/{omnibox::kClobberTriggersContextualWebZeroSuggest,
omnibox::kFocusTriggersContextualWebZeroSuggest},
/*disabled_features=*/{omnibox::kClobberTriggersSRPZeroSuggest,
omnibox::kFocusTriggersSRPZeroSuggest});
EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), prefix_web_input, &result_type));
EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), prefix_srp_input, &result_type));
EXPECT_TRUE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), on_focus_web_input, &result_type));
EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), on_focus_srp_input, &result_type));
EXPECT_TRUE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), on_clobber_web_input, &result_type));
EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), on_clobber_srp_input, &result_type));
}
// Enable on-clobber and on-focus for SRP.
// Disable on-clobber and on-focus for OTHER.
{
base::test::ScopedFeatureList features;
features.InitWithFeatures(
/*enabled_features=*/{omnibox::kClobberTriggersSRPZeroSuggest,
omnibox::kFocusTriggersSRPZeroSuggest},
/*disabled_features=*/{
omnibox::kClobberTriggersContextualWebZeroSuggest,
omnibox::kFocusTriggersContextualWebZeroSuggest});
EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), prefix_web_input, &result_type));
EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), prefix_srp_input, &result_type));
EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), on_focus_web_input, &result_type));
EXPECT_TRUE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), on_focus_srp_input, &result_type));
EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), on_clobber_web_input, &result_type));
EXPECT_TRUE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), on_clobber_srp_input, &result_type));
}
}
TEST_F(ZeroSuggestProviderTest, AllowZeroPrefixSuggestions_RequestEligibility) {
base::HistogramTester histogram_tester;
// Enable on-focus for SRP.
base::test::ScopedFeatureList features;
features.InitAndEnableFeature(omnibox::kFocusTriggersSRPZeroSuggest);
AutocompleteInput on_focus_srp_input = OnFocusInputForSRP();
ZeroSuggestProvider::ResultType result_type = ZeroSuggestProvider::NONE;
EXPECT_TRUE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), on_focus_srp_input, &result_type));
histogram_tester.ExpectBucketCount("Omnibox.ZeroSuggest.Eligible.OnFocusV2",
0 /*ELIGIBLE*/, 1);
AutocompleteInput on_focus_srp_input_ineligible_url = OnFocusInputForSRP();
on_focus_srp_input_ineligible_url.set_current_url(GURL("chrome://history"));
EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), on_focus_srp_input_ineligible_url, &result_type));
histogram_tester.ExpectBucketCount("Omnibox.ZeroSuggest.Eligible.OnFocusV2",
1 /*URL_INELIGIBLE*/, 1);
// zero-suggest is not allowed for non-Google default search providers.
TemplateURLService* template_url_service = client_->GetTemplateURLService();
TemplateURLData data;
data.SetURL("https://www.example.com/?q={searchTerms}");
data.suggestions_url = "https://www.example.com/suggest/?q={searchTerms}";
auto* other_search_provider =
template_url_service->Add(std::make_unique<TemplateURL>(data));
template_url_service->SetUserSelectedDefaultSearchProvider(
other_search_provider);
EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), on_focus_srp_input, &result_type));
histogram_tester.ExpectBucketCount("Omnibox.ZeroSuggest.Eligible.OnFocusV2",
2 /*GENERALLY_INELIGIBLE*/, 1);
// zero-suggest is not allowed for non-empty inputs.
AutocompleteInput prefix_srp_input = PrefixInputForSRP();
EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
client_.get(), prefix_srp_input, &result_type));
// The last case is not taken into account for eligibility metrics.
histogram_tester.ExpectTotalCount("Omnibox.ZeroSuggest.Eligible.OnFocusV2",
3);
}
TEST_F(ZeroSuggestProviderTest, TypeOfResultToRun_NTP) {
AutocompleteInput onfocus_ntp_input = OnFocusInputForNTP();
EXPECT_EQ(ZeroSuggestProvider::REMOTE_NO_URL,
ZeroSuggestProvider::TypeOfResultToRun(
client_.get(), onfocus_ntp_input,
/*bypass_request_eligibility_checks=*/true));
}
TEST_F(ZeroSuggestProviderTest, TypeOfResultToRun_ContextualWeb) {
AutocompleteInput on_focus_input = OnFocusInputForWeb();
AutocompleteInput on_clobber_input = OnClobberInputForWeb();
// Disable on-focus and on-clobber.
{
base::test::ScopedFeatureList features;
features.InitWithFeatures(
/*enabled_features=*/{},
/*disabled_features=*/{
omnibox::kFocusTriggersContextualWebZeroSuggest,
omnibox::kClobberTriggersContextualWebZeroSuggest});
EXPECT_EQ(ZeroSuggestProvider::NONE,
ZeroSuggestProvider::TypeOfResultToRun(
client_.get(), on_focus_input,
/*bypass_request_eligibility_checks=*/true));
EXPECT_EQ(ZeroSuggestProvider::NONE,
ZeroSuggestProvider::TypeOfResultToRun(
client_.get(), on_clobber_input,
/*bypass_request_eligibility_checks=*/true));
}
// Enable on-focus only.
{
base::test::ScopedFeatureList features;
features.InitWithFeatures(
/*enabled_features=*/{omnibox::kFocusTriggersContextualWebZeroSuggest},
/*disabled_features=*/{
omnibox::kClobberTriggersContextualWebZeroSuggest});
EXPECT_EQ(ZeroSuggestProvider::REMOTE_SEND_URL,
ZeroSuggestProvider::TypeOfResultToRun(
client_.get(), on_focus_input,
/*bypass_request_eligibility_checks=*/true));
EXPECT_EQ(ZeroSuggestProvider::NONE,
ZeroSuggestProvider::TypeOfResultToRun(
client_.get(), on_clobber_input,
/*bypass_request_eligibility_checks=*/true));
}
// Enable on-clobber only.
{
base::test::ScopedFeatureList features;
features.InitWithFeatures(
/*enabled_features=*/{omnibox::
kClobberTriggersContextualWebZeroSuggest},
/*disabled_features=*/
{omnibox::kFocusTriggersContextualWebZeroSuggest});
EXPECT_EQ(ZeroSuggestProvider::NONE,
ZeroSuggestProvider::TypeOfResultToRun(
client_.get(), on_focus_input,
/*bypass_request_eligibility_checks=*/true));
EXPECT_EQ(ZeroSuggestProvider::REMOTE_SEND_URL,
ZeroSuggestProvider::TypeOfResultToRun(
client_.get(), on_clobber_input,
/*bypass_request_eligibility_checks=*/true));
}
// Enable on-focus and on-clobber.
{
base::test::ScopedFeatureList features;
features.InitWithFeatures(
/*enabled_features=*/
{omnibox::kFocusTriggersContextualWebZeroSuggest,
omnibox::kClobberTriggersContextualWebZeroSuggest},
/*disabled_features=*/{});
EXPECT_EQ(ZeroSuggestProvider::REMOTE_SEND_URL,
ZeroSuggestProvider::TypeOfResultToRun(
client_.get(), on_focus_input,
/*bypass_request_eligibility_checks=*/true));
EXPECT_EQ(ZeroSuggestProvider::REMOTE_SEND_URL,
ZeroSuggestProvider::TypeOfResultToRun(
client_.get(), on_clobber_input,
/*bypass_request_eligibility_checks=*/true));
}
}
TEST_F(ZeroSuggestProviderTest, TypeOfResultToRun_SRP) {
AutocompleteInput on_focus_input = OnFocusInputForSRP();
AutocompleteInput on_clobber_input = OnClobberInputForSRP();
// Disable on-focus and on-clobber.
{
base::test::ScopedFeatureList features;
features.InitWithFeatures(
/*enabled_features=*/{},
/*disabled_features=*/{omnibox::kFocusTriggersSRPZeroSuggest,
omnibox::kClobberTriggersSRPZeroSuggest});
EXPECT_EQ(ZeroSuggestProvider::NONE,
ZeroSuggestProvider::TypeOfResultToRun(
client_.get(), on_focus_input,
/*bypass_request_eligibility_checks=*/true));
EXPECT_EQ(ZeroSuggestProvider::NONE,
ZeroSuggestProvider::TypeOfResultToRun(
client_.get(), on_clobber_input,
/*bypass_request_eligibility_checks=*/true));
}
// Enable on-focus only.
{
base::test::ScopedFeatureList features;
features.InitWithFeatures(
/*enabled_features=*/{omnibox::kFocusTriggersSRPZeroSuggest},
/*disabled_features=*/{omnibox::kClobberTriggersSRPZeroSuggest});
EXPECT_EQ(ZeroSuggestProvider::REMOTE_SEND_URL,
ZeroSuggestProvider::TypeOfResultToRun(
client_.get(), on_focus_input,
/*bypass_request_eligibility_checks=*/true));
EXPECT_EQ(ZeroSuggestProvider::NONE,
ZeroSuggestProvider::TypeOfResultToRun(
client_.get(), on_clobber_input,
/*bypass_request_eligibility_checks=*/true));
}
// Enable on-clobber only.
{
base::test::ScopedFeatureList features;
features.InitWithFeatures(
/*enabled_features=*/{omnibox::kClobberTriggersSRPZeroSuggest},
/*disabled_features=*/
{omnibox::kFocusTriggersSRPZeroSuggest});
EXPECT_EQ(ZeroSuggestProvider::NONE,
ZeroSuggestProvider::TypeOfResultToRun(
client_.get(), on_focus_input,
/*bypass_request_eligibility_checks=*/true));
EXPECT_EQ(ZeroSuggestProvider::REMOTE_SEND_URL,
ZeroSuggestProvider::TypeOfResultToRun(
client_.get(), on_clobber_input,
/*bypass_request_eligibility_checks=*/true));
}
// Enable on-focus and on-clobber.
{
base::test::ScopedFeatureList features;
features.InitWithFeatures(
/*enabled_features=*/
{omnibox::kFocusTriggersSRPZeroSuggest,
omnibox::kClobberTriggersSRPZeroSuggest},
/*disabled_features=*/{});
EXPECT_EQ(ZeroSuggestProvider::REMOTE_SEND_URL,
ZeroSuggestProvider::TypeOfResultToRun(
client_.get(), on_focus_input,
/*bypass_request_eligibility_checks=*/true));
EXPECT_EQ(ZeroSuggestProvider::REMOTE_SEND_URL,
ZeroSuggestProvider::TypeOfResultToRun(
client_.get(), on_clobber_input,
/*bypass_request_eligibility_checks=*/true));
}
}
TEST_F(ZeroSuggestProviderTest, StartStop) {
EXPECT_CALL(*client_, IsAuthenticated())
.WillRepeatedly(testing::Return(true));
// Set up the pref to cache the response from the previous run.
std::string json_response(
"[\"\",[\"search1\", \"search2\", \"search3\"],"
"[],[],{\"google:suggestrelevance\":[602, 601, 600],"
"\"google:verbatimrelevance\":1300}]");
PrefService* prefs = client_->GetPrefs();
prefs->SetString(omnibox::kZeroSuggestCachedResults, json_response);
GURL suggest_url = GetSuggestURL(metrics::OmniboxEventProto::NTP_REALBOX);
// Make sure valid input starts the provider.
AutocompleteInput input = OnFocusInputForNTP();
provider_->Start(input, false);
EXPECT_FALSE(provider_->done());
// Expect that matches got populated out of cache.
EXPECT_FALSE(provider_->matches().empty());
// Expect that network request was sent.
EXPECT_TRUE(test_loader_factory()->IsPending(suggest_url.spec()));
// Expect the provider to not have notified the provider listener yet.
EXPECT_FALSE(provider_did_notify_);
// Make sure valid input restarts the provider.
provider_->Start(input, false);
EXPECT_FALSE(provider_->done());
// Expect that matches got populated out of cache.
EXPECT_FALSE(provider_->matches().empty());
// Expect that network request was sent.
EXPECT_TRUE(test_loader_factory()->IsPending(suggest_url.spec()));
// Expect the provider to not have notified the provider listener yet.
EXPECT_FALSE(provider_did_notify_);
// Make sure invalid input stops the provider.
AutocompleteInput prefix_input = PrefixInputForNTP();
provider_->Start(prefix_input, false);
EXPECT_TRUE(provider_->done());
// Expect that matches did not get populated out of cache.
EXPECT_TRUE(provider_->matches().empty());
// Expect that network request was not sent.
EXPECT_FALSE(test_loader_factory()->IsPending(suggest_url.spec()));
// Expect the provider to not have notified the provider listener since the
// request was invalidated.
EXPECT_FALSE(provider_did_notify_);
// Make sure valid input restarts the provider.
provider_->Start(input, false);
EXPECT_FALSE(provider_->done());
// Expect that matches got populated out of cache.
EXPECT_FALSE(provider_->matches().empty());
// Expect that network request was sent.
EXPECT_TRUE(test_loader_factory()->IsPending(suggest_url.spec()));
// Expect the provider to not have notified the provider listener yet.
EXPECT_FALSE(provider_did_notify_);
}
TEST_F(ZeroSuggestProviderTest, TestPsuggestZeroSuggestCachingFirstRun) {
base::HistogramTester histogram_tester;
EXPECT_CALL(*client_, IsAuthenticated())
.WillRepeatedly(testing::Return(true));
AutocompleteInput input = OnFocusInputForNTP();
provider_->Start(input, false);
ASSERT_EQ(ZeroSuggestProvider::REMOTE_NO_URL,
provider_->GetResultTypeRunningForTesting());
EXPECT_TRUE(provider_->matches().empty());
GURL suggest_url = GetSuggestURL(metrics::OmniboxEventProto::NTP_REALBOX);
EXPECT_TRUE(test_loader_factory()->IsPending(suggest_url.spec()));
std::string json_response("[\"\",[\"search1\", \"search2\", \"search3\"],"
"[],[],{\"google:suggestrelevance\":[602, 601, 600],"
"\"google:verbatimrelevance\":1300}]");
test_loader_factory()->AddResponse(suggest_url.spec(), json_response);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(provider_->done());
// Expect correct histograms to have been logged.
histogram_tester.ExpectTotalCount(
"Omnibox.ZeroSuggestProvider.URLBased.Prefetch", 0);
histogram_tester.ExpectTotalCount(
"Omnibox.ZeroSuggestProvider.URLBased.NonPrefetch", 0);
histogram_tester.ExpectTotalCount(
"Omnibox.ZeroSuggestProvider.NoURL.Prefetch", 0);
histogram_tester.ExpectTotalCount(
"Omnibox.ZeroSuggestProvider.NoURL.NonPrefetch", 4);
histogram_tester.ExpectBucketCount(
"Omnibox.ZeroSuggestProvider.NoURL.NonPrefetch", 1 /*REQUEST_SENT*/, 1);
histogram_tester.ExpectBucketCount(
"Omnibox.ZeroSuggestProvider.NoURL.NonPrefetch",
3 /*REMOTE_RESPONSE_RECEIVED*/, 1);
histogram_tester.ExpectBucketCount(
"Omnibox.ZeroSuggestProvider.NoURL.NonPrefetch",
4 /*REMOTE_RESPONSE_CACHED*/, 1);
histogram_tester.ExpectBucketCount(
"Omnibox.ZeroSuggestProvider.NoURL.NonPrefetch",
5 /*REMOTE_RESPONSE_CONVERTED_TO_MATCHES*/, 1);
// Expect the provider to have notified the provider listener.
EXPECT_TRUE(provider_did_notify_);
EXPECT_EQ(3U, provider_->matches().size()); // 3 results, no verbatim match
PrefService* prefs = client_->GetPrefs();
EXPECT_EQ(json_response,
prefs->GetString(omnibox::kZeroSuggestCachedResults));
}
TEST_F(ZeroSuggestProviderTest,
TestPsuggestZeroSuggestWantAsynchronousMatchesFalse) {
EXPECT_CALL(*client_, IsAuthenticated())
.WillRepeatedly(testing::Return(true));
AutocompleteInput input = OnFocusInputForNTP();
input.set_omit_asynchronous_matches(true);
GURL suggest_url = GetSuggestURL(metrics::OmniboxEventProto::NTP_REALBOX);
provider_->Start(input, false);
ASSERT_EQ(ZeroSuggestProvider::REMOTE_NO_URL,
provider_->GetResultTypeRunningForTesting());
EXPECT_TRUE(provider_->done());
EXPECT_TRUE(provider_->matches().empty());
// There should be no pending network requests, given that asynchronous logic
// has been explicitly disabled (`omit_asynchronous_matches_ == true`).
ASSERT_FALSE(test_loader_factory()->IsPending(suggest_url.spec()));
// Expect the provider to not have notified the provider listener since the
// request was not sent.
EXPECT_FALSE(provider_did_notify_);
}
TEST_F(ZeroSuggestProviderTest, TestPsuggestZeroSuggestHasCachedResults) {
base::HistogramTester histogram_tester;
EXPECT_CALL(*client_, IsAuthenticated())
.WillRepeatedly(testing::Return(true));
// Set up the pref to cache the response from the previous run.
std::string json_response("[\"\",[\"search1\", \"search2\", \"search3\"],"
"[],[],{\"google:suggestrelevance\":[602, 601, 600],"
"\"google:verbatimrelevance\":1300}]");
PrefService* prefs = client_->GetPrefs();
prefs->SetString(omnibox::kZeroSuggestCachedResults, json_response);
AutocompleteInput input = OnFocusInputForNTP();
provider_->Start(input, false);
ASSERT_EQ(ZeroSuggestProvider::REMOTE_NO_URL,
provider_->GetResultTypeRunningForTesting());
// Expect that matches get populated synchronously out of the cache.
ASSERT_EQ(3U, provider_->matches().size()); // 3 results, no verbatim match
EXPECT_EQ(u"search1", provider_->matches()[0].contents);
EXPECT_EQ(u"search2", provider_->matches()[1].contents);
EXPECT_EQ(u"search3", provider_->matches()[2].contents);
GURL suggest_url = GetSuggestURL(metrics::OmniboxEventProto::NTP_REALBOX);
EXPECT_TRUE(test_loader_factory()->IsPending(suggest_url.spec()));
std::string json_response2(
"[\"\",[\"search4\", \"search5\", \"search6\"],"
"[],[],{\"google:suggestrelevance\":[602, 601, 600],"
"\"google:verbatimrelevance\":1300}]");
test_loader_factory()->AddResponse(suggest_url.spec(), json_response2);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(provider_->done());
// Expect the provider to not have notified the provider listener when using
// the cached response.
EXPECT_FALSE(provider_did_notify_);
// Expect correct histograms to have been logged.
histogram_tester.ExpectTotalCount(
"Omnibox.ZeroSuggestProvider.URLBased.Prefetch", 0);
histogram_tester.ExpectTotalCount(
"Omnibox.ZeroSuggestProvider.URLBased.NonPrefetch", 0);
histogram_tester.ExpectTotalCount(
"Omnibox.ZeroSuggestProvider.NoURL.Prefetch", 0);
histogram_tester.ExpectTotalCount(
"Omnibox.ZeroSuggestProvider.NoURL.NonPrefetch", 4);
histogram_tester.ExpectBucketCount(
"Omnibox.ZeroSuggestProvider.NoURL.NonPrefetch",
0 /*CACHED_RESPONSE_CONVERTED_TO_MATCHES*/, 1);
histogram_tester.ExpectBucketCount(
"Omnibox.ZeroSuggestProvider.NoURL.NonPrefetch", 1 /*REQUEST_SENT*/, 1);
histogram_tester.ExpectBucketCount(
"Omnibox.ZeroSuggestProvider.NoURL.NonPrefetch",
3 /*REMOTE_RESPONSE_RECEIVED*/, 1);
histogram_tester.ExpectBucketCount(
"Omnibox.ZeroSuggestProvider.NoURL.NonPrefetch",
4 /*REMOTE_RESPONSE_CACHED*/, 1);
// Expect the same results after the response has been handled.
ASSERT_EQ(3U, provider_->matches().size()); // 3 results, no verbatim match
EXPECT_EQ(u"search1", provider_->matches()[0].contents);
EXPECT_EQ(u"search2", provider_->matches()[1].contents);
EXPECT_EQ(u"search3", provider_->matches()[2].contents);
// Expect the new results to have been stored.
EXPECT_EQ(json_response2,
prefs->GetString(omnibox::kZeroSuggestCachedResults));
}
TEST_F(ZeroSuggestProviderTest, TestPsuggestZeroSuggestReceivedEmptyResults) {
base::HistogramTester histogram_tester;
EXPECT_CALL(*client_, IsAuthenticated())
.WillRepeatedly(testing::Return(true));
// Set up the pref to cache the response from the previous run.
std::string json_response("[\"\",[\"search1\", \"search2\", \"search3\"],"
"[],[],{\"google:suggestrelevance\":[602, 601, 600],"
"\"google:verbatimrelevance\":1300}]");
PrefService* prefs = client_->GetPrefs();
prefs->SetString(omnibox::kZeroSuggestCachedResults, json_response);
AutocompleteInput input = OnFocusInputForNTP();
provider_->Start(input, false);
ASSERT_EQ(ZeroSuggestProvider::REMOTE_NO_URL,
provider_->GetResultTypeRunningForTesting());
// Expect that matches get populated synchronously out of the cache.
ASSERT_EQ(3U, provider_->matches().size()); // 3 results, no verbatim match
EXPECT_EQ(u"search1", provider_->matches()[0].contents);
EXPECT_EQ(u"search2", provider_->matches()[1].contents);
EXPECT_EQ(u"search3", provider_->matches()[2].contents);
GURL suggest_url = GetSuggestURL(metrics::OmniboxEventProto::NTP_REALBOX);
EXPECT_TRUE(test_loader_factory()->IsPending(suggest_url.spec()));
std::string empty_response("[\"\",[],[],[],{}]");
test_loader_factory()->AddResponse(suggest_url.spec(), empty_response);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(provider_->done());
// Expect correct histograms to have been logged.
histogram_tester.ExpectTotalCount(
"Omnibox.ZeroSuggestProvider.URLBased.Prefetch", 0);
histogram_tester.ExpectTotalCount(
"Omnibox.ZeroSuggestProvider.URLBased.NonPrefetch", 0);
histogram_tester.ExpectTotalCount(
"Omnibox.ZeroSuggestProvider.NoURL.Prefetch", 0);
histogram_tester.ExpectTotalCount(
"Omnibox.ZeroSuggestProvider.NoURL.NonPrefetch", 5);
histogram_tester.ExpectBucketCount(
"Omnibox.ZeroSuggestProvider.NoURL.NonPrefetch",
0 /*CACHED_RESPONSE_CONVERTED_TO_MATCHES*/, 1);
histogram_tester.ExpectBucketCount(
"Omnibox.ZeroSuggestProvider.NoURL.NonPrefetch", 1 /*REQUEST_SENT*/, 1);
histogram_tester.ExpectBucketCount(
"Omnibox.ZeroSuggestProvider.NoURL.NonPrefetch",
3 /*REMOTE_RESPONSE_RECEIVED*/, 1);
histogram_tester.ExpectBucketCount(
"Omnibox.ZeroSuggestProvider.NoURL.NonPrefetch",
4 /*REMOTE_RESPONSE_CACHED*/, 1);
histogram_tester.ExpectBucketCount(
"Omnibox.ZeroSuggestProvider.NoURL.NonPrefetch",
5 /*REMOTE_RESPONSE_CONVERTED_TO_MATCHES*/, 1);
// Expect the provider to have notified the provider listener.
EXPECT_TRUE(provider_did_notify_);
// Expect that the matches have been cleared.
ASSERT_TRUE(provider_->matches().empty());
// Expect the new results to have been stored.
EXPECT_EQ(empty_response,
prefs->GetString(omnibox::kZeroSuggestCachedResults));
}
TEST_F(ZeroSuggestProviderTest, TestPsuggestZeroSuggestPrefetchThenNTPOnFocus) {
EXPECT_CALL(*client_, IsAuthenticated())
.WillRepeatedly(testing::Return(true));
// Set up the pref to cache the response from the previous run.
std::string json_response(
"[\"\",[\"search1\", \"search2\", \"search3\"],"
"[],[],{\"google:suggestrelevance\":[602, 601, 600],"
"\"google:verbatimrelevance\":1300}]");
PrefService* prefs = client_->GetPrefs();
prefs->SetString(omnibox::kZeroSuggestCachedResults, json_response);
{
base::HistogramTester histogram_tester;
// Start a prefetch request.
AutocompleteInput input = PrefetchingInputForNTP();
provider_->StartPrefetch(input);
EXPECT_TRUE(provider_->done());
// Expect the results to be empty.
ASSERT_EQ(0U, provider_->matches().size());
GURL suggest_url =
GetSuggestURL(metrics::OmniboxEventProto::NTP_ZPS_PREFETCH);
EXPECT_TRUE(test_loader_factory()->IsPending(suggest_url.spec()));
std::string json_response2(
"[\"\",[\"search4\", \"search5\", \"search6\"],"
"[],[],{\"google:suggestrelevance\":[602, 601, 600],"
"\"google:verbatimrelevance\":1300}]");
test_loader_factory()->AddResponse(suggest_url.spec(), json_response2);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(provider_->done());
// Expect correct histograms to have been logged.
histogram_tester.ExpectTotalCount(
"Omnibox.ZeroSuggestProvider.URLBased.Prefetch", 0);
histogram_tester.ExpectTotalCount(
"Omnibox.ZeroSuggestProvider.URLBased.NonPrefetch", 0);
histogram_tester.ExpectTotalCount(
"Omnibox.ZeroSuggestProvider.NoURL.NonPrefetch", 0);
histogram_tester.ExpectTotalCount(
"Omnibox.ZeroSuggestProvider.NoURL.Prefetch", 3);
histogram_tester.ExpectBucketCount(
"Omnibox.ZeroSuggestProvider.NoURL.Prefetch", 1 /*REQUEST_SENT*/, 1);
histogram_tester.ExpectBucketCount(
"Omnibox.ZeroSuggestProvider.NoURL.Prefetch",
3 /*REMOTE_RESPONSE_RECEIVED*/, 1);
histogram_tester.ExpectBucketCount(
"Omnibox.ZeroSuggestProvider.NoURL.Prefetch",
4 /*REMOTE_RESPONSE_CACHED*/, 1);
// Expect the provider to not have notified the provider listener since the
// matches were not updated.
EXPECT_FALSE(provider_did_notify_);
// Expect the same empty results after the response has been handled.
ASSERT_EQ(0U, provider_->matches().size()); // 3 results, no verbatim match
// Expect the new response to have been stored in the pref.
EXPECT_EQ(json_response2,
prefs->GetString(omnibox::kZeroSuggestCachedResults));
}
{
base::HistogramTester histogram_tester;
// Start a non-prefetch request.
AutocompleteInput input = OnFocusInputForNTP();
provider_->Start(input, false);
EXPECT_FALSE(provider_->done());
ASSERT_EQ(ZeroSuggestProvider::REMOTE_NO_URL,
provider_->GetResultTypeRunningForTesting());
// Expect the results from the cached response.
ASSERT_EQ(3U, provider_->matches().size()); // 3 results, no verbatim match
EXPECT_EQ(u"search4", provider_->matches()[0].contents);
EXPECT_EQ(u"search5", provider_->matches()[1].contents);
EXPECT_EQ(u"search6", provider_->matches()[2].contents);
GURL suggest_url = GetSuggestURL(metrics::OmniboxEventProto::NTP_REALBOX);
EXPECT_TRUE(test_loader_factory()->IsPending(suggest_url.spec()));
std::string json_response3(
"[\"\",[\"search7\", \"search8\", \"search9\"],"
"[],[],{\"google:suggestrelevance\":[602, 601, 600],"
"\"google:verbatimrelevance\":1300}]");
test_loader_factory()->AddResponse(suggest_url.spec(), json_response3);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(provider_->done());
// Expect correct histograms to have been logged.
histogram_tester.ExpectTotalCount(
"Omnibox.ZeroSuggestProvider.URLBased.Prefetch", 0);
histogram_tester.ExpectTotalCount(
"Omnibox.ZeroSuggestProvider.URLBased.NonPrefetch", 0);
histogram_tester.ExpectTotalCount(
"Omnibox.ZeroSuggestProvider.NoURL.Prefetch", 0);
histogram_tester.ExpectTotalCount(
"Omnibox.ZeroSuggestProvider.NoURL.NonPrefetch", 4);
histogram_tester.ExpectBucketCount(
"Omnibox.ZeroSuggestProvider.NoURL.NonPrefetch",
0 /*CACHED_RESPONSE_CONVERTED_TO_MATCHES*/, 1);
histogram_tester.ExpectBucketCount(
"Omnibox.ZeroSuggestProvider.NoURL.NonPrefetch", 1 /*REQUEST_SENT*/, 1);
histogram_tester.ExpectBucketCount(
"Omnibox.ZeroSuggestProvider.NoURL.NonPrefetch",
3 /*REMOTE_RESPONSE_RECEIVED*/, 1);
histogram_tester.ExpectBucketCount(
"Omnibox.ZeroSuggestProvider.NoURL.NonPrefetch",
4 /*REMOTE_RESPONSE_CACHED*/, 1);
// Expect the provider to not have notified the provider listener since the
// matches were not updated.
EXPECT_FALSE(provider_did_notify_);
// Expect the same results after the response has been handled.
ASSERT_EQ(3U, provider_->matches().size()); // 3 results, no verbatim match
EXPECT_EQ(u"search4", provider_->matches()[0].contents);
EXPECT_EQ(u"search5", provider_->matches()[1].contents);
EXPECT_EQ(u"search6", provider_->matches()[2].contents);
// Expect the new response to have been stored in the pref.
EXPECT_EQ(json_response3,
prefs->GetString(omnibox::kZeroSuggestCachedResults));
}
}