| // 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 "chrome/browser/autocomplete/zero_suggest_provider.h" |
| |
| #include "base/metrics/field_trial.h" |
| #include "base/prefs/pref_service.h" |
| #include "base/run_loop.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h" |
| #include "chrome/browser/autocomplete/autocomplete_provider_listener.h" |
| #include "chrome/browser/search_engines/template_url.h" |
| #include "chrome/browser/search_engines/template_url_service.h" |
| #include "chrome/browser/search_engines/template_url_service_factory.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/test/base/testing_profile.h" |
| #include "components/metrics/proto/omnibox_event.pb.h" |
| #include "components/variations/entropy_provider.h" |
| #include "components/variations/variations_associated_data.h" |
| #include "content/public/test/test_browser_thread_bundle.h" |
| #include "net/url_request/test_url_fetcher_factory.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| class ZeroSuggestProviderTest : public testing::Test, |
| public AutocompleteProviderListener { |
| public: |
| ZeroSuggestProviderTest(); |
| |
| virtual void SetUp() OVERRIDE; |
| virtual void TearDown() OVERRIDE; |
| |
| protected: |
| // AutocompleteProviderListener: |
| virtual void OnProviderUpdate(bool updated_matches) OVERRIDE; |
| |
| void ResetFieldTrialList(); |
| |
| // Set up threads for testing; this needs to be instantiated before |
| // |profile_|. |
| content::TestBrowserThreadBundle thread_bundle_; |
| |
| // Needed for OmniboxFieldTrial::ActivateStaticTrials(). |
| scoped_ptr<base::FieldTrialList> field_trial_list_; |
| |
| // URLFetcherFactory implementation registered. |
| net::TestURLFetcherFactory test_factory_; |
| |
| // Profile we use. |
| TestingProfile profile_; |
| |
| // ZeroSuggestProvider object under test. |
| scoped_refptr<ZeroSuggestProvider> provider_; |
| |
| // Default template URL. |
| TemplateURL* default_t_url_; |
| }; |
| |
| ZeroSuggestProviderTest::ZeroSuggestProviderTest() { |
| ResetFieldTrialList(); |
| } |
| |
| void ZeroSuggestProviderTest::SetUp() { |
| // Make sure that fetchers are automatically ungregistered upon destruction. |
| test_factory_.set_remove_fetcher_on_delete(true); |
| TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse( |
| &profile_, &TemplateURLServiceFactory::BuildInstanceFor); |
| AutocompleteClassifierFactory::GetInstance()->SetTestingFactoryAndUse( |
| &profile_, &AutocompleteClassifierFactory::BuildInstanceFor); |
| |
| TemplateURLService* turl_model = |
| TemplateURLServiceFactory::GetForProfile(&profile_); |
| turl_model->Load(); |
| |
| TemplateURLData data; |
| data.short_name = base::ASCIIToUTF16("t"); |
| data.SetURL("https://www.google.com/?q={searchTerms}"); |
| data.suggestions_url = "https://www.google.com/complete/?q={searchTerms}"; |
| data.instant_url = "https://does/not/exist?strk=1"; |
| data.search_terms_replacement_key = "strk"; |
| default_t_url_ = new TemplateURL(data); |
| turl_model->Add(default_t_url_); |
| turl_model->SetUserSelectedDefaultSearchProvider(default_t_url_); |
| |
| provider_ = ZeroSuggestProvider::Create(this, &profile_); |
| } |
| |
| void ZeroSuggestProviderTest::TearDown() { |
| // Shutdown the provider before the profile. |
| provider_ = NULL; |
| } |
| |
| void ZeroSuggestProviderTest::OnProviderUpdate(bool updated_matches) { |
| } |
| |
| void ZeroSuggestProviderTest::ResetFieldTrialList() { |
| // Destroy the existing FieldTrialList before creating a new one to avoid |
| // a DCHECK. |
| field_trial_list_.reset(); |
| field_trial_list_.reset(new base::FieldTrialList( |
| new metrics::SHA1EntropyProvider("foo"))); |
| chrome_variations::testing::ClearAllVariationParams(); |
| } |
| |
| TEST_F(ZeroSuggestProviderTest, TestPsuggestZeroSuggestCachingFirstRun) { |
| base::FieldTrialList::CreateFieldTrial( |
| "AutocompleteDynamicTrial_2", "EnableZeroSuggestPersonalizedExperiment"); |
| |
| // Ensure the cache is empty. |
| PrefService* prefs = profile_.GetPrefs(); |
| prefs->SetString(prefs::kZeroSuggestCachedResults, std::string()); |
| |
| std::string url("http://www.cnn.com"); |
| AutocompleteInput input( |
| base::ASCIIToUTF16(url), base::string16::npos, base::string16(), |
| GURL(url), metrics::OmniboxEventProto::INVALID_SPEC, true, false, true, |
| true); |
| |
| provider_->Start(input, false); |
| |
| EXPECT_TRUE(prefs->GetString(prefs::kZeroSuggestCachedResults).empty()); |
| EXPECT_TRUE(provider_->matches().empty()); |
| |
| net::TestURLFetcher* fetcher = test_factory_.GetFetcherByID(1); |
| ASSERT_TRUE(fetcher); |
| fetcher->set_response_code(200); |
| std::string json_response("[\"\",[\"search1\", \"search2\", \"search3\"]," |
| "[],[],{\"google:suggestrelevance\":[602, 601, 600]," |
| "\"google:verbatimrelevance\":1300}]"); |
| fetcher->SetResponseString(json_response); |
| fetcher->delegate()->OnURLFetchComplete(fetcher); |
| |
| base::RunLoop().RunUntilIdle(); |
| |
| EXPECT_EQ(4U, provider_->matches().size()); // 3 results + verbatim |
| EXPECT_EQ(json_response, prefs->GetString(prefs::kZeroSuggestCachedResults)); |
| } |
| |
| TEST_F(ZeroSuggestProviderTest, TestPsuggestZeroSuggestHasCachedResults) { |
| base::FieldTrialList::CreateFieldTrial( |
| "AutocompleteDynamicTrial_2", "EnableZeroSuggestPersonalizedExperiment"); |
| |
| std::string url("http://www.cnn.com"); |
| AutocompleteInput input( |
| base::ASCIIToUTF16(url), base::string16::npos, base::string16(), |
| GURL(url), metrics::OmniboxEventProto::INVALID_SPEC, true, false, true, |
| 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 = profile_.GetPrefs(); |
| prefs->SetString(prefs::kZeroSuggestCachedResults, json_response); |
| |
| provider_->Start(input, false); |
| |
| // Expect that matches get populated synchronously out of the cache. |
| ASSERT_EQ(4U, provider_->matches().size()); |
| EXPECT_EQ(base::ASCIIToUTF16("search1"), provider_->matches()[1].contents); |
| EXPECT_EQ(base::ASCIIToUTF16("search2"), provider_->matches()[2].contents); |
| EXPECT_EQ(base::ASCIIToUTF16("search3"), provider_->matches()[3].contents); |
| |
| net::TestURLFetcher* fetcher = test_factory_.GetFetcherByID(1); |
| ASSERT_TRUE(fetcher); |
| fetcher->set_response_code(200); |
| std::string json_response2("[\"\",[\"search4\", \"search5\", \"search6\"]," |
| "[],[],{\"google:suggestrelevance\":[602, 601, 600]," |
| "\"google:verbatimrelevance\":1300}]"); |
| fetcher->SetResponseString(json_response2); |
| fetcher->delegate()->OnURLFetchComplete(fetcher); |
| |
| base::RunLoop().RunUntilIdle(); |
| |
| // Expect the same 4 results after the response has been handled. |
| ASSERT_EQ(4U, provider_->matches().size()); |
| EXPECT_EQ(base::ASCIIToUTF16("search1"), provider_->matches()[1].contents); |
| EXPECT_EQ(base::ASCIIToUTF16("search2"), provider_->matches()[2].contents); |
| EXPECT_EQ(base::ASCIIToUTF16("search3"), provider_->matches()[3].contents); |
| |
| // Expect the new results have been stored. |
| EXPECT_EQ(json_response2, |
| prefs->GetString(prefs::kZeroSuggestCachedResults)); |
| } |
| |
| TEST_F(ZeroSuggestProviderTest, TestPsuggestZeroSuggestReceivedEmptyResults) { |
| base::FieldTrialList::CreateFieldTrial( |
| "AutocompleteDynamicTrial_2", "EnableZeroSuggestPersonalizedExperiment"); |
| |
| std::string url("http://www.cnn.com"); |
| AutocompleteInput input( |
| base::ASCIIToUTF16(url), base::string16::npos, base::string16(), |
| GURL(url), metrics::OmniboxEventProto::INVALID_SPEC, true, false, true, |
| 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 = profile_.GetPrefs(); |
| prefs->SetString(prefs::kZeroSuggestCachedResults, json_response); |
| |
| provider_->Start(input, false); |
| |
| // Expect that matches get populated synchronously out of the cache. |
| ASSERT_EQ(4U, provider_->matches().size()); |
| EXPECT_EQ(base::ASCIIToUTF16("search1"), provider_->matches()[1].contents); |
| EXPECT_EQ(base::ASCIIToUTF16("search2"), provider_->matches()[2].contents); |
| EXPECT_EQ(base::ASCIIToUTF16("search3"), provider_->matches()[3].contents); |
| |
| net::TestURLFetcher* fetcher = test_factory_.GetFetcherByID(1); |
| ASSERT_TRUE(fetcher); |
| fetcher->set_response_code(200); |
| std::string empty_response("[\"\",[],[],[],{}]"); |
| fetcher->SetResponseString(empty_response); |
| fetcher->delegate()->OnURLFetchComplete(fetcher); |
| |
| base::RunLoop().RunUntilIdle(); |
| |
| // Expect that the matches have been cleared. |
| ASSERT_TRUE(provider_->matches().empty()); |
| |
| // Expect the new results have been stored. |
| EXPECT_EQ(empty_response, |
| prefs->GetString(prefs::kZeroSuggestCachedResults)); |
| } |