search_provider_install_data_unittest.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
1// Copyright (c) 2012 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 <string>
6
7#include "base/basictypes.h"
8#include "base/bind.h"
9#include "base/memory/ref_counted.h"
10#include "base/message_loop.h"
11#include "base/strings/utf_string_conversions.h"
12#include "chrome/browser/chrome_notification_types.h"
13#include "chrome/browser/search_engines/search_provider_install_data.h"
14#include "chrome/browser/search_engines/template_url.h"
15#include "chrome/browser/search_engines/template_url_prepopulate_data.h"
16#include "chrome/browser/search_engines/template_url_service.h"
17#include "chrome/browser/search_engines/template_url_service_test_util.h"
18#include "chrome/common/pref_names.h"
19#include "chrome/test/base/testing_pref_service_syncable.h"
20#include "chrome/test/base/testing_profile.h"
21#include "content/public/browser/notification_service.h"
22#include "content/public/browser/notification_source.h"
23#include "content/public/test/test_browser_thread.h"
24#include "testing/gtest/include/gtest/gtest.h"
25
26using content::BrowserThread;
27
28namespace {
29
30// TestGetInstallState --------------------------------------------------------
31
32// Test the SearchProviderInstallData::GetInstallState.
33class TestGetInstallState :
34    public base::RefCountedThreadSafe<TestGetInstallState> {
35 public:
36  explicit TestGetInstallState(SearchProviderInstallData* install_data);
37
38  void set_search_provider_host(
39      const std::string& search_provider_host) {
40    search_provider_host_ = search_provider_host;
41  }
42
43  void set_default_search_provider_host(
44      const std::string& default_search_provider_host) {
45    default_search_provider_host_ = default_search_provider_host;
46  }
47
48  // Runs the test. Returns true if all passed. False if any failed.
49  bool RunTests();
50
51 private:
52  friend class base::RefCountedThreadSafe<TestGetInstallState>;
53  ~TestGetInstallState();
54
55  // Starts the test run on the IO thread.
56  void StartTestOnIOThread();
57
58  // Callback for when SearchProviderInstallData is ready to have
59  // GetInstallState called. Runs all of the test cases.
60  void DoInstallStateTests();
61
62  // Does a verification for one url and its expected state.
63  void VerifyInstallState(SearchProviderInstallData::State expected_state,
64                          const std::string& url);
65
66  SearchProviderInstallData* install_data_;
67  base::MessageLoop* main_loop_;
68
69  // A host which should be a search provider but not the default.
70  std::string search_provider_host_;
71
72  // A host which should be a search provider but not the default.
73  std::string default_search_provider_host_;
74
75  // Used to indicate if DoInstallStateTests passed all test.
76  bool passed_;
77
78  DISALLOW_COPY_AND_ASSIGN(TestGetInstallState);
79};
80
81TestGetInstallState::TestGetInstallState(
82    SearchProviderInstallData* install_data)
83    : install_data_(install_data),
84      main_loop_(NULL),
85      passed_(false) {
86}
87
88bool TestGetInstallState::RunTests() {
89  passed_ = true;
90
91  main_loop_ = base::MessageLoop::current();
92
93  BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)->PostTask(
94      FROM_HERE,
95      base::Bind(&TestGetInstallState::StartTestOnIOThread, this));
96  // Run the current message loop. When the test is finished on the I/O thread,
97  // it invokes Quit, which unblocks this.
98  base::MessageLoop::current()->Run();
99  main_loop_ = NULL;
100
101  // Let the testing code know what the result is.
102  return passed_;
103}
104
105TestGetInstallState::~TestGetInstallState() {
106}
107
108void TestGetInstallState::StartTestOnIOThread() {
109  install_data_->CallWhenLoaded(
110      base::Bind(&TestGetInstallState::DoInstallStateTests, this));
111}
112
113void TestGetInstallState::DoInstallStateTests() {
114  // Installed but not default.
115  VerifyInstallState(SearchProviderInstallData::INSTALLED_BUT_NOT_DEFAULT,
116                     "http://" + search_provider_host_ + "/");
117  VerifyInstallState(SearchProviderInstallData::INSTALLED_BUT_NOT_DEFAULT,
118                     "http://" + search_provider_host_ + ":80/");
119
120  // Not installed.
121  VerifyInstallState(SearchProviderInstallData::NOT_INSTALLED,
122                     "http://" + search_provider_host_ + ":96/");
123
124  // Not installed due to different scheme.
125  VerifyInstallState(SearchProviderInstallData::NOT_INSTALLED,
126                     "https://" + search_provider_host_ + "/");
127
128  // Not installed.
129  VerifyInstallState(SearchProviderInstallData::NOT_INSTALLED,
130                     "http://a" + search_provider_host_ + "/");
131
132  // Installed as default.
133  if (!default_search_provider_host_.empty()) {
134    VerifyInstallState(SearchProviderInstallData::INSTALLED_AS_DEFAULT,
135                       "http://" + default_search_provider_host_ + "/");
136  }
137
138  // All done.
139  main_loop_->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
140}
141
142void TestGetInstallState::VerifyInstallState(
143    SearchProviderInstallData::State expected_state,
144    const std::string& url) {
145
146  SearchProviderInstallData::State actual_state =
147      install_data_->GetInstallState(GURL(url));
148  if (expected_state == actual_state)
149    return;
150
151  passed_ = false;
152  LOG(ERROR) << "GetInstallState for " << url << " failed. Expected " <<
153      expected_state << ".  Actual " << actual_state << ".";
154}
155
156};  // namespace
157
158
159// SearchProviderInstallDataTest ----------------------------------------------
160
161// Provides basic test set-up/tear-down functionality needed by all tests
162// that use TemplateURLServiceTestUtil.
163class SearchProviderInstallDataTest : public testing::Test {
164 public:
165  SearchProviderInstallDataTest();
166
167  virtual void SetUp() OVERRIDE;
168  virtual void TearDown() OVERRIDE;
169
170  void SimulateDefaultSearchIsManaged(const std::string& url);
171
172 protected:
173  TemplateURL* AddNewTemplateURL(const std::string& url,
174                                 const string16& keyword);
175
176  TemplateURLServiceTestUtil util_;
177
178  // Provides the search provider install state on the I/O thread. It must be
179  // deleted on the I/O thread, which is why it isn't a scoped_ptr.
180  SearchProviderInstallData* install_data_;
181
182  DISALLOW_COPY_AND_ASSIGN(SearchProviderInstallDataTest);
183};
184
185SearchProviderInstallDataTest::SearchProviderInstallDataTest()
186    : install_data_(NULL) {
187}
188
189void SearchProviderInstallDataTest::SetUp() {
190  testing::Test::SetUp();
191#if defined(OS_ANDROID)
192  TemplateURLPrepopulateData::InitCountryCode(
193      std::string() /* unknown country code */);
194#endif
195  util_.SetUp();
196  util_.StartIOThread();
197  install_data_ = new SearchProviderInstallData(util_.profile(),
198      content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
199      content::Source<SearchProviderInstallDataTest>(this));
200}
201
202void SearchProviderInstallDataTest::TearDown() {
203  BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, install_data_);
204  install_data_ = NULL;
205
206  // Make sure that the install data class on the UI thread gets cleaned up.
207  // It doesn't matter that this happens after install_data_ is deleted.
208  content::NotificationService::current()->Notify(
209      content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
210      content::Source<SearchProviderInstallDataTest>(this),
211      content::NotificationService::NoDetails());
212
213  util_.TearDown();
214  testing::Test::TearDown();
215}
216
217void SearchProviderInstallDataTest::SimulateDefaultSearchIsManaged(
218    const std::string& url) {
219  ASSERT_FALSE(url.empty());
220  TestingPrefServiceSyncable* service =
221      util_.profile()->GetTestingPrefService();
222  service->SetManagedPref(prefs::kDefaultSearchProviderEnabled,
223                          Value::CreateBooleanValue(true));
224  service->SetManagedPref(prefs::kDefaultSearchProviderSearchURL,
225                          Value::CreateStringValue(url));
226  service->SetManagedPref(prefs::kDefaultSearchProviderName,
227                          Value::CreateStringValue("managed"));
228  // Clear the IDs that are not specified via policy.
229  service->SetManagedPref(prefs::kDefaultSearchProviderID,
230                          new StringValue(std::string()));
231  service->SetManagedPref(prefs::kDefaultSearchProviderPrepopulateID,
232                          new StringValue(std::string()));
233  util_.model()->Observe(chrome::NOTIFICATION_DEFAULT_SEARCH_POLICY_CHANGED,
234                         content::NotificationService::AllSources(),
235                         content::NotificationService::NoDetails());
236}
237
238TemplateURL* SearchProviderInstallDataTest::AddNewTemplateURL(
239    const std::string& url,
240    const string16& keyword) {
241  TemplateURLData data;
242  data.short_name = keyword;
243  data.SetKeyword(keyword);
244  data.SetURL(url);
245  TemplateURL* t_url = new TemplateURL(util_.profile(), data);
246  util_.model()->Add(t_url);
247  return t_url;
248}
249
250
251// Actual tests ---------------------------------------------------------------
252
253TEST_F(SearchProviderInstallDataTest, GetInstallState) {
254  // Set up the database.
255  util_.ChangeModelToLoadState();
256  std::string host = "www.unittest.com";
257  AddNewTemplateURL("http://" + host + "/path", ASCIIToUTF16("unittest"));
258
259  // Wait for the changes to be saved.
260  TemplateURLServiceTestUtil::BlockTillServiceProcessesRequests();
261
262  // Verify the search providers install state (with no default set).
263  scoped_refptr<TestGetInstallState> test_get_install_state(
264      new TestGetInstallState(install_data_));
265  test_get_install_state->set_search_provider_host(host);
266  EXPECT_TRUE(test_get_install_state->RunTests());
267
268  // Set-up a default and try it all one more time.
269  std::string default_host = "www.mmm.com";
270  TemplateURL* default_url =
271      AddNewTemplateURL("http://" + default_host + "/", ASCIIToUTF16("mmm"));
272  util_.model()->SetDefaultSearchProvider(default_url);
273  test_get_install_state->set_default_search_provider_host(default_host);
274  EXPECT_TRUE(test_get_install_state->RunTests());
275}
276
277
278TEST_F(SearchProviderInstallDataTest, ManagedDefaultSearch) {
279  // Set up the database.
280  util_.ChangeModelToLoadState();
281  std::string host = "www.unittest.com";
282  AddNewTemplateURL("http://" + host + "/path", ASCIIToUTF16("unittest"));
283
284  // Set a managed preference that establishes a default search provider.
285  std::string host2 = "www.managedtest.com";
286  std::string url2 = "http://" + host2 + "/p{searchTerms}";
287  SimulateDefaultSearchIsManaged(url2);
288  EXPECT_TRUE(util_.model()->is_default_search_managed());
289
290  // Wait for the changes to be saved.
291  util_.BlockTillServiceProcessesRequests();
292
293  // Verify the search providers install state.  The default search should be
294  // the managed one we previously set.
295  scoped_refptr<TestGetInstallState> test_get_install_state(
296      new TestGetInstallState(install_data_));
297  test_get_install_state->set_search_provider_host(host);
298  test_get_install_state->set_default_search_provider_host(host2);
299  EXPECT_TRUE(test_get_install_state->RunTests());
300}
301
302
303TEST_F(SearchProviderInstallDataTest, GoogleBaseUrlChange) {
304  scoped_refptr<TestGetInstallState> test_get_install_state(
305      new TestGetInstallState(install_data_));
306
307  // Set up the database.
308  util_.ChangeModelToLoadState();
309  std::string google_host = "w.com";
310  util_.SetGoogleBaseURL(GURL("http://" + google_host + "/"));
311  // Wait for the I/O thread to process the update notification.
312  TemplateURLServiceTestUtil::BlockTillIOThreadProcessesRequests();
313
314  AddNewTemplateURL("{google:baseURL}?q={searchTerms}", ASCIIToUTF16("t"));
315  TemplateURL* default_url =
316      AddNewTemplateURL("http://d.com/", ASCIIToUTF16("d"));
317  util_.model()->SetDefaultSearchProvider(default_url);
318
319  // Wait for the changes to be saved.
320  TemplateURLServiceTestUtil::BlockTillServiceProcessesRequests();
321
322  // Verify the search providers install state (with no default set).
323  test_get_install_state->set_search_provider_host(google_host);
324  EXPECT_TRUE(test_get_install_state->RunTests());
325
326  // Change the Google base url.
327  google_host = "foo.com";
328  util_.SetGoogleBaseURL(GURL("http://" + google_host + "/"));
329  // Wait for the I/O thread to process the update notification.
330  TemplateURLServiceTestUtil::BlockTillIOThreadProcessesRequests();
331
332  // Verify that the change got picked up.
333  test_get_install_state->set_search_provider_host(google_host);
334  EXPECT_TRUE(test_get_install_state->RunTests());
335}
336