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