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