zero_suggest_provider_unittest.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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/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"
23
24class ZeroSuggestProviderTest : public testing::Test,
25                                public AutocompleteProviderListener {
26 public:
27  ZeroSuggestProviderTest();
28
29  virtual void SetUp() OVERRIDE;
30  virtual void TearDown() OVERRIDE;
31
32 protected:
33  // AutocompleteProviderListener:
34  virtual void OnProviderUpdate(bool updated_matches) OVERRIDE;
35
36  void ResetFieldTrialList();
37
38  // Set up threads for testing; this needs to be instantiated before
39  // |profile_|.
40  content::TestBrowserThreadBundle thread_bundle_;
41
42  // Needed for OmniboxFieldTrial::ActivateStaticTrials().
43  scoped_ptr<base::FieldTrialList> field_trial_list_;
44
45  // URLFetcherFactory implementation registered.
46  net::TestURLFetcherFactory test_factory_;
47
48  // Profile we use.
49  TestingProfile profile_;
50
51  // ZeroSuggestProvider object under test.
52  scoped_refptr<ZeroSuggestProvider> provider_;
53
54  // Default template URL.
55  TemplateURL* default_t_url_;
56};
57
58ZeroSuggestProviderTest::ZeroSuggestProviderTest() {
59  ResetFieldTrialList();
60}
61
62void 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);
69
70  TemplateURLService* turl_model =
71      TemplateURLServiceFactory::GetForProfile(&profile_);
72  turl_model->Load();
73
74  TemplateURLData data;
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_);
83
84  provider_ = ZeroSuggestProvider::Create(this, &profile_);
85}
86
87void ZeroSuggestProviderTest::TearDown() {
88  // Shutdown the provider before the profile.
89  provider_ = NULL;
90}
91
92void ZeroSuggestProviderTest::OnProviderUpdate(bool updated_matches) {
93}
94
95void ZeroSuggestProviderTest::ResetFieldTrialList() {
96  // Destroy the existing FieldTrialList before creating a new one to avoid
97  // a DCHECK.
98  field_trial_list_.reset();
99  field_trial_list_.reset(new base::FieldTrialList(
100      new metrics::SHA1EntropyProvider("foo")));
101  chrome_variations::testing::ClearAllVariationParams();
102}
103
104TEST_F(ZeroSuggestProviderTest, TestPsuggestZeroSuggestCachingFirstRun) {
105  base::FieldTrialList::CreateFieldTrial(
106      "AutocompleteDynamicTrial_2", "EnableZeroSuggestPersonalizedExperiment");
107
108  // Ensure the cache is empty.
109  PrefService* prefs = profile_.GetPrefs();
110  prefs->SetString(prefs::kZeroSuggestCachedResults, std::string());
111
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);
116
117  provider_->Start(input, false);
118
119  EXPECT_TRUE(prefs->GetString(prefs::kZeroSuggestCachedResults).empty());
120  EXPECT_TRUE(provider_->matches().empty());
121
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);
130
131  base::RunLoop().RunUntilIdle();
132
133  EXPECT_EQ(4U, provider_->matches().size());  // 3 results + verbatim
134  EXPECT_EQ(json_response, prefs->GetString(prefs::kZeroSuggestCachedResults));
135}
136
137TEST_F(ZeroSuggestProviderTest, TestPsuggestZeroSuggestHasCachedResults) {
138  base::FieldTrialList::CreateFieldTrial(
139      "AutocompleteDynamicTrial_2", "EnableZeroSuggestPersonalizedExperiment");
140
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);
145
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);
152
153  provider_->Start(input, false);
154
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);
160
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);
169
170  base::RunLoop().RunUntilIdle();
171
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);
177
178  // Expect the new results have been stored.
179  EXPECT_EQ(json_response2,
180            prefs->GetString(prefs::kZeroSuggestCachedResults));
181}
182
183TEST_F(ZeroSuggestProviderTest, TestPsuggestZeroSuggestReceivedEmptyResults) {
184  base::FieldTrialList::CreateFieldTrial(
185      "AutocompleteDynamicTrial_2", "EnableZeroSuggestPersonalizedExperiment");
186
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);
191
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);
198
199  provider_->Start(input, false);
200
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);
206
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);
213
214  base::RunLoop().RunUntilIdle();
215
216  // Expect that the matches have been cleared.
217  ASSERT_TRUE(provider_->matches().empty());
218
219  // Expect the new results have been stored.
220  EXPECT_EQ(empty_response,
221            prefs->GetString(prefs::kZeroSuggestCachedResults));
222}
223