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.
5 #include "chrome/browser/autocomplete/zero_suggest_provider.h"
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/autocomplete_provider_listener.h"
13 #include "chrome/browser/search_engines/template_url.h"
14 #include "chrome/browser/search_engines/template_url_service.h"
15 #include "chrome/browser/search_engines/template_url_service_factory.h"
16 #include "chrome/common/pref_names.h"
17 #include "chrome/test/base/testing_profile.h"
18 #include "components/variations/entropy_provider.h"
19 #include "components/variations/variations_associated_data.h"
20 #include "content/public/test/test_browser_thread_bundle.h"
21 #include "net/url_request/test_url_fetcher_factory.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 class ZeroSuggestProviderTest
: public testing::Test
,
25 public AutocompleteProviderListener
{
27 ZeroSuggestProviderTest();
29 virtual void SetUp() OVERRIDE
;
30 virtual void TearDown() OVERRIDE
;
33 // AutocompleteProviderListener:
34 virtual void OnProviderUpdate(bool updated_matches
) OVERRIDE
;
36 void ResetFieldTrialList();
38 // Set up threads for testing; this needs to be instantiated before
40 content::TestBrowserThreadBundle thread_bundle_
;
42 // Needed for OmniboxFieldTrial::ActivateStaticTrials().
43 scoped_ptr
<base::FieldTrialList
> field_trial_list_
;
45 // URLFetcherFactory implementation registered.
46 net::TestURLFetcherFactory test_factory_
;
49 TestingProfile profile_
;
51 // ZeroSuggestProvider object under test.
52 scoped_refptr
<ZeroSuggestProvider
> provider_
;
54 // Default template URL.
55 TemplateURL
* default_t_url_
;
58 ZeroSuggestProviderTest::ZeroSuggestProviderTest() {
59 ResetFieldTrialList();
62 void ZeroSuggestProviderTest::SetUp() {
63 // Make sure that fetchers are automatically ungregistered upon destruction.
64 test_factory_
.set_remove_fetcher_on_delete(true);
65 TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
66 &profile_
, &TemplateURLServiceFactory::BuildInstanceFor
);
67 AutocompleteClassifierFactory::GetInstance()->SetTestingFactoryAndUse(
68 &profile_
, &AutocompleteClassifierFactory::BuildInstanceFor
);
70 TemplateURLService
* turl_model
=
71 TemplateURLServiceFactory::GetForProfile(&profile_
);
75 data
.short_name
= base::ASCIIToUTF16("t");
76 data
.SetURL("https://www.google.com/?q={searchTerms}");
77 data
.suggestions_url
= "https://www.google.com/complete/?q={searchTerms}";
78 data
.instant_url
= "https://does/not/exist?strk=1";
79 data
.search_terms_replacement_key
= "strk";
80 default_t_url_
= new TemplateURL(&profile_
, data
);
81 turl_model
->Add(default_t_url_
);
82 turl_model
->SetUserSelectedDefaultSearchProvider(default_t_url_
);
84 provider_
= ZeroSuggestProvider::Create(this, &profile_
);
87 void ZeroSuggestProviderTest::TearDown() {
88 // Shutdown the provider before the profile.
92 void ZeroSuggestProviderTest::OnProviderUpdate(bool updated_matches
) {
95 void ZeroSuggestProviderTest::ResetFieldTrialList() {
96 // Destroy the existing FieldTrialList before creating a new one to avoid
98 field_trial_list_
.reset();
99 field_trial_list_
.reset(new base::FieldTrialList(
100 new metrics::SHA1EntropyProvider("foo")));
101 chrome_variations::testing::ClearAllVariationParams();
104 TEST_F(ZeroSuggestProviderTest
, TestPsuggestZeroSuggestCachingFirstRun
) {
105 base::FieldTrialList::CreateFieldTrial(
106 "AutocompleteDynamicTrial_2", "EnableZeroSuggestPersonalizedExperiment");
108 // Ensure the cache is empty.
109 PrefService
* prefs
= profile_
.GetPrefs();
110 prefs
->SetString(prefs::kZeroSuggestCachedResults
, std::string());
112 std::string
url("http://www.cnn.com");
113 AutocompleteInput
input(
114 base::ASCIIToUTF16(url
), base::string16::npos
, base::string16(),
115 GURL(url
), AutocompleteInput::INVALID_SPEC
, true, false, true, true);
117 provider_
->Start(input
, false);
119 EXPECT_TRUE(prefs
->GetString(prefs::kZeroSuggestCachedResults
).empty());
120 EXPECT_TRUE(provider_
->matches().empty());
122 net::TestURLFetcher
* fetcher
= test_factory_
.GetFetcherByID(1);
123 ASSERT_TRUE(fetcher
);
124 fetcher
->set_response_code(200);
125 std::string
json_response("[\"\",[\"search1\", \"search2\", \"search3\"],"
126 "[],[],{\"google:suggestrelevance\":[602, 601, 600],"
127 "\"google:verbatimrelevance\":1300}]");
128 fetcher
->SetResponseString(json_response
);
129 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
131 base::RunLoop().RunUntilIdle();
133 EXPECT_EQ(4U, provider_
->matches().size()); // 3 results + verbatim
134 EXPECT_EQ(json_response
, prefs
->GetString(prefs::kZeroSuggestCachedResults
));
137 TEST_F(ZeroSuggestProviderTest
, TestPsuggestZeroSuggestHasCachedResults
) {
138 base::FieldTrialList::CreateFieldTrial(
139 "AutocompleteDynamicTrial_2", "EnableZeroSuggestPersonalizedExperiment");
141 std::string
url("http://www.cnn.com");
142 AutocompleteInput
input(
143 base::ASCIIToUTF16(url
), base::string16::npos
, base::string16(),
144 GURL(url
), AutocompleteInput::INVALID_SPEC
, true, false, true, true);
146 // Set up the pref to cache the response from the previous run.
147 std::string
json_response("[\"\",[\"search1\", \"search2\", \"search3\"],"
148 "[],[],{\"google:suggestrelevance\":[602, 601, 600],"
149 "\"google:verbatimrelevance\":1300}]");
150 PrefService
* prefs
= profile_
.GetPrefs();
151 prefs
->SetString(prefs::kZeroSuggestCachedResults
, json_response
);
153 provider_
->Start(input
, false);
155 // Expect that matches get populated synchronously out of the cache.
156 ASSERT_EQ(4U, provider_
->matches().size());
157 EXPECT_EQ(base::ASCIIToUTF16("search1"), provider_
->matches()[1].contents
);
158 EXPECT_EQ(base::ASCIIToUTF16("search2"), provider_
->matches()[2].contents
);
159 EXPECT_EQ(base::ASCIIToUTF16("search3"), provider_
->matches()[3].contents
);
161 net::TestURLFetcher
* fetcher
= test_factory_
.GetFetcherByID(1);
162 ASSERT_TRUE(fetcher
);
163 fetcher
->set_response_code(200);
164 std::string
json_response2("[\"\",[\"search4\", \"search5\", \"search6\"],"
165 "[],[],{\"google:suggestrelevance\":[602, 601, 600],"
166 "\"google:verbatimrelevance\":1300}]");
167 fetcher
->SetResponseString(json_response2
);
168 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
170 base::RunLoop().RunUntilIdle();
172 // Expect the same 4 results after the response has been handled.
173 ASSERT_EQ(4U, provider_
->matches().size());
174 EXPECT_EQ(base::ASCIIToUTF16("search1"), provider_
->matches()[1].contents
);
175 EXPECT_EQ(base::ASCIIToUTF16("search2"), provider_
->matches()[2].contents
);
176 EXPECT_EQ(base::ASCIIToUTF16("search3"), provider_
->matches()[3].contents
);
178 // Expect the new results have been stored.
179 EXPECT_EQ(json_response2
,
180 prefs
->GetString(prefs::kZeroSuggestCachedResults
));
183 TEST_F(ZeroSuggestProviderTest
, TestPsuggestZeroSuggestReceivedEmptyResults
) {
184 base::FieldTrialList::CreateFieldTrial(
185 "AutocompleteDynamicTrial_2", "EnableZeroSuggestPersonalizedExperiment");
187 std::string
url("http://www.cnn.com");
188 AutocompleteInput
input(
189 base::ASCIIToUTF16(url
), base::string16::npos
, base::string16(),
190 GURL(url
), AutocompleteInput::INVALID_SPEC
, true, false, true, true);
192 // Set up the pref to cache the response from the previous run.
193 std::string
json_response("[\"\",[\"search1\", \"search2\", \"search3\"],"
194 "[],[],{\"google:suggestrelevance\":[602, 601, 600],"
195 "\"google:verbatimrelevance\":1300}]");
196 PrefService
* prefs
= profile_
.GetPrefs();
197 prefs
->SetString(prefs::kZeroSuggestCachedResults
, json_response
);
199 provider_
->Start(input
, false);
201 // Expect that matches get populated synchronously out of the cache.
202 ASSERT_EQ(4U, provider_
->matches().size());
203 EXPECT_EQ(base::ASCIIToUTF16("search1"), provider_
->matches()[1].contents
);
204 EXPECT_EQ(base::ASCIIToUTF16("search2"), provider_
->matches()[2].contents
);
205 EXPECT_EQ(base::ASCIIToUTF16("search3"), provider_
->matches()[3].contents
);
207 net::TestURLFetcher
* fetcher
= test_factory_
.GetFetcherByID(1);
208 ASSERT_TRUE(fetcher
);
209 fetcher
->set_response_code(200);
210 std::string
empty_response("[\"\",[],[],[],{}]");
211 fetcher
->SetResponseString(empty_response
);
212 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
214 base::RunLoop().RunUntilIdle();
216 // Expect that the matches have been cleared.
217 ASSERT_TRUE(provider_
->matches().empty());
219 // Expect the new results have been stored.
220 EXPECT_EQ(empty_response
,
221 prefs
->GetString(prefs::kZeroSuggestCachedResults
));