zero_suggest_provider_unittest.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/autocomplete/zero_suggest_provider.h" 6 7#include "base/metrics/field_trial.h" 8#include "base/prefs/pref_service.h" 9#include "base/run_loop.h" 10#include "base/strings/utf_string_conversions.h" 11#include "chrome/browser/autocomplete/autocomplete_classifier_factory.h" 12#include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h" 13#include "chrome/browser/search_engines/template_url_service_factory.h" 14#include "chrome/common/pref_names.h" 15#include "chrome/test/base/testing_profile.h" 16#include "components/metrics/proto/omnibox_event.pb.h" 17#include "components/omnibox/autocomplete_provider_listener.h" 18#include "components/omnibox/omnibox_field_trial.h" 19#include "components/search_engines/template_url.h" 20#include "components/search_engines/template_url_service.h" 21#include "components/variations/entropy_provider.h" 22#include "components/variations/variations_associated_data.h" 23#include "content/public/test/test_browser_thread_bundle.h" 24#include "net/url_request/test_url_fetcher_factory.h" 25#include "testing/gtest/include/gtest/gtest.h" 26 27class ZeroSuggestProviderTest : public testing::Test, 28 public AutocompleteProviderListener { 29 public: 30 ZeroSuggestProviderTest(); 31 32 virtual void SetUp() OVERRIDE; 33 virtual void TearDown() OVERRIDE; 34 35 protected: 36 // AutocompleteProviderListener: 37 virtual void OnProviderUpdate(bool updated_matches) OVERRIDE; 38 39 void ResetFieldTrialList(); 40 41 void CreatePersonalizedFieldTrial(); 42 43 // Set up threads for testing; this needs to be instantiated before 44 // |profile_|. 45 content::TestBrowserThreadBundle thread_bundle_; 46 47 // Needed for OmniboxFieldTrial::ActivateStaticTrials(). 48 scoped_ptr<base::FieldTrialList> field_trial_list_; 49 50 // URLFetcherFactory implementation registered. 51 net::TestURLFetcherFactory test_factory_; 52 53 // Profile we use. 54 TestingProfile profile_; 55 56 // ZeroSuggestProvider object under test. 57 scoped_refptr<ZeroSuggestProvider> provider_; 58 59 // Default template URL. 60 TemplateURL* default_t_url_; 61}; 62 63ZeroSuggestProviderTest::ZeroSuggestProviderTest() { 64 ResetFieldTrialList(); 65} 66 67void ZeroSuggestProviderTest::SetUp() { 68 // Make sure that fetchers are automatically ungregistered upon destruction. 69 test_factory_.set_remove_fetcher_on_delete(true); 70 TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse( 71 &profile_, &TemplateURLServiceFactory::BuildInstanceFor); 72 AutocompleteClassifierFactory::GetInstance()->SetTestingFactoryAndUse( 73 &profile_, &AutocompleteClassifierFactory::BuildInstanceFor); 74 75 TemplateURLService* turl_model = 76 TemplateURLServiceFactory::GetForProfile(&profile_); 77 turl_model->Load(); 78 79 TemplateURLData data; 80 data.short_name = base::ASCIIToUTF16("t"); 81 data.SetURL("https://www.google.com/?q={searchTerms}"); 82 data.suggestions_url = "https://www.google.com/complete/?q={searchTerms}"; 83 data.instant_url = "https://does/not/exist?strk=1"; 84 data.search_terms_replacement_key = "strk"; 85 default_t_url_ = new TemplateURL(data); 86 turl_model->Add(default_t_url_); 87 turl_model->SetUserSelectedDefaultSearchProvider(default_t_url_); 88 89 provider_ = ZeroSuggestProvider::Create(this, turl_model, &profile_); 90} 91 92void ZeroSuggestProviderTest::TearDown() { 93 // Shutdown the provider before the profile. 94 provider_ = NULL; 95} 96 97void ZeroSuggestProviderTest::OnProviderUpdate(bool updated_matches) { 98} 99 100void ZeroSuggestProviderTest::ResetFieldTrialList() { 101 // Destroy the existing FieldTrialList before creating a new one to avoid 102 // a DCHECK. 103 field_trial_list_.reset(); 104 field_trial_list_.reset(new base::FieldTrialList( 105 new metrics::SHA1EntropyProvider("foo"))); 106 variations::testing::ClearAllVariationParams(); 107} 108 109void ZeroSuggestProviderTest::CreatePersonalizedFieldTrial() { 110 std::map<std::string, std::string> params; 111 params[std::string(OmniboxFieldTrial::kZeroSuggestRule)] = "true"; 112 params[std::string(OmniboxFieldTrial::kZeroSuggestVariantRule)] = 113 "Personalized"; 114 variations::AssociateVariationParams( 115 OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params); 116 base::FieldTrialList::CreateFieldTrial( 117 OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A"); 118} 119 120TEST_F(ZeroSuggestProviderTest, TestPsuggestZeroSuggestCachingFirstRun) { 121 CreatePersonalizedFieldTrial(); 122 123 // Ensure the cache is empty. 124 PrefService* prefs = profile_.GetPrefs(); 125 prefs->SetString(prefs::kZeroSuggestCachedResults, std::string()); 126 127 std::string url("http://www.cnn.com"); 128 AutocompleteInput input(base::ASCIIToUTF16(url), base::string16::npos, 129 base::string16(), GURL(url), 130 metrics::OmniboxEventProto::INVALID_SPEC, true, false, 131 true, true, 132 ChromeAutocompleteSchemeClassifier(&profile_)); 133 134 provider_->Start(input, false); 135 136 EXPECT_TRUE(prefs->GetString(prefs::kZeroSuggestCachedResults).empty()); 137 EXPECT_TRUE(provider_->matches().empty()); 138 139 net::TestURLFetcher* fetcher = test_factory_.GetFetcherByID(1); 140 ASSERT_TRUE(fetcher); 141 fetcher->set_response_code(200); 142 std::string json_response("[\"\",[\"search1\", \"search2\", \"search3\"]," 143 "[],[],{\"google:suggestrelevance\":[602, 601, 600]," 144 "\"google:verbatimrelevance\":1300}]"); 145 fetcher->SetResponseString(json_response); 146 fetcher->delegate()->OnURLFetchComplete(fetcher); 147 148 base::RunLoop().RunUntilIdle(); 149 150 EXPECT_EQ(4U, provider_->matches().size()); // 3 results + verbatim 151 EXPECT_EQ(json_response, prefs->GetString(prefs::kZeroSuggestCachedResults)); 152} 153 154TEST_F(ZeroSuggestProviderTest, TestPsuggestZeroSuggestHasCachedResults) { 155 CreatePersonalizedFieldTrial(); 156 157 std::string url("http://www.cnn.com"); 158 AutocompleteInput input(base::ASCIIToUTF16(url), base::string16::npos, 159 base::string16(), GURL(url), 160 metrics::OmniboxEventProto::INVALID_SPEC, true, false, 161 true, true, 162 ChromeAutocompleteSchemeClassifier(&profile_)); 163 164 // Set up the pref to cache the response from the previous run. 165 std::string json_response("[\"\",[\"search1\", \"search2\", \"search3\"]," 166 "[],[],{\"google:suggestrelevance\":[602, 601, 600]," 167 "\"google:verbatimrelevance\":1300}]"); 168 PrefService* prefs = profile_.GetPrefs(); 169 prefs->SetString(prefs::kZeroSuggestCachedResults, json_response); 170 171 provider_->Start(input, false); 172 173 // Expect that matches get populated synchronously out of the cache. 174 ASSERT_EQ(4U, provider_->matches().size()); 175 EXPECT_EQ(base::ASCIIToUTF16("search1"), provider_->matches()[1].contents); 176 EXPECT_EQ(base::ASCIIToUTF16("search2"), provider_->matches()[2].contents); 177 EXPECT_EQ(base::ASCIIToUTF16("search3"), provider_->matches()[3].contents); 178 179 net::TestURLFetcher* fetcher = test_factory_.GetFetcherByID(1); 180 ASSERT_TRUE(fetcher); 181 fetcher->set_response_code(200); 182 std::string json_response2("[\"\",[\"search4\", \"search5\", \"search6\"]," 183 "[],[],{\"google:suggestrelevance\":[602, 601, 600]," 184 "\"google:verbatimrelevance\":1300}]"); 185 fetcher->SetResponseString(json_response2); 186 fetcher->delegate()->OnURLFetchComplete(fetcher); 187 188 base::RunLoop().RunUntilIdle(); 189 190 // Expect the same 4 results after the response has been handled. 191 ASSERT_EQ(4U, provider_->matches().size()); 192 EXPECT_EQ(base::ASCIIToUTF16("search1"), provider_->matches()[1].contents); 193 EXPECT_EQ(base::ASCIIToUTF16("search2"), provider_->matches()[2].contents); 194 EXPECT_EQ(base::ASCIIToUTF16("search3"), provider_->matches()[3].contents); 195 196 // Expect the new results have been stored. 197 EXPECT_EQ(json_response2, 198 prefs->GetString(prefs::kZeroSuggestCachedResults)); 199} 200 201TEST_F(ZeroSuggestProviderTest, TestPsuggestZeroSuggestReceivedEmptyResults) { 202 CreatePersonalizedFieldTrial(); 203 204 std::string url("http://www.cnn.com"); 205 AutocompleteInput input(base::ASCIIToUTF16(url), base::string16::npos, 206 base::string16(), GURL(url), 207 metrics::OmniboxEventProto::INVALID_SPEC, true, false, 208 true, true, 209 ChromeAutocompleteSchemeClassifier(&profile_)); 210 211 // Set up the pref to cache the response from the previous run. 212 std::string json_response("[\"\",[\"search1\", \"search2\", \"search3\"]," 213 "[],[],{\"google:suggestrelevance\":[602, 601, 600]," 214 "\"google:verbatimrelevance\":1300}]"); 215 PrefService* prefs = profile_.GetPrefs(); 216 prefs->SetString(prefs::kZeroSuggestCachedResults, json_response); 217 218 provider_->Start(input, false); 219 220 // Expect that matches get populated synchronously out of the cache. 221 ASSERT_EQ(4U, provider_->matches().size()); 222 EXPECT_EQ(base::ASCIIToUTF16("search1"), provider_->matches()[1].contents); 223 EXPECT_EQ(base::ASCIIToUTF16("search2"), provider_->matches()[2].contents); 224 EXPECT_EQ(base::ASCIIToUTF16("search3"), provider_->matches()[3].contents); 225 226 net::TestURLFetcher* fetcher = test_factory_.GetFetcherByID(1); 227 ASSERT_TRUE(fetcher); 228 fetcher->set_response_code(200); 229 std::string empty_response("[\"\",[],[],[],{}]"); 230 fetcher->SetResponseString(empty_response); 231 fetcher->delegate()->OnURLFetchComplete(fetcher); 232 233 base::RunLoop().RunUntilIdle(); 234 235 // Expect that the matches have been cleared. 236 ASSERT_TRUE(provider_->matches().empty()); 237 238 // Expect the new results have been stored. 239 EXPECT_EQ(empty_response, 240 prefs->GetString(prefs::kZeroSuggestCachedResults)); 241} 242