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 "base/file_util.h"
      6 #include "base/memory/scoped_ptr.h"
      7 #include "base/message_loop.h"
      8 #include "base/path_service.h"
      9 #include "base/utf_string_conversions.h"
     10 #include "chrome/browser/search_engines/template_url.h"
     11 #include "chrome/browser/search_engines/template_url_fetcher.h"
     12 #include "chrome/browser/search_engines/template_url_fetcher_callbacks.h"
     13 #include "chrome/browser/search_engines/template_url_model.h"
     14 #include "chrome/browser/search_engines/template_url_model_test_util.h"
     15 #include "chrome/common/chrome_paths.h"
     16 #include "chrome/test/testing_profile.h"
     17 #include "googleurl/src/gurl.h"
     18 #include "net/test/test_server.h"
     19 #include "testing/gtest/include/gtest/gtest.h"
     20 
     21 class TemplateURLFetcherTest;
     22 
     23 // Handles callbacks from TemplateURLFetcher.
     24 class TemplateURLFetcherTestCallbacks : public TemplateURLFetcherCallbacks {
     25  public:
     26   explicit TemplateURLFetcherTestCallbacks(TemplateURLFetcherTest* test)
     27       : test_(test) {
     28   }
     29   virtual ~TemplateURLFetcherTestCallbacks();
     30 
     31   // TemplateURLFetcherCallbacks implementation.
     32   virtual void ConfirmSetDefaultSearchProvider(
     33       TemplateURL* template_url,
     34       TemplateURLModel* template_url_model);
     35   virtual void ConfirmAddSearchProvider(
     36       TemplateURL* template_url,
     37       Profile* profile);
     38 
     39  private:
     40   TemplateURLFetcherTest* test_;
     41 
     42   DISALLOW_COPY_AND_ASSIGN(TemplateURLFetcherTestCallbacks);
     43 };
     44 
     45 // Basic set-up for TemplateURLFetcher tests.
     46 class TemplateURLFetcherTest : public testing::Test {
     47  public:
     48   TemplateURLFetcherTest();
     49 
     50   virtual void SetUp() {
     51     test_util_.SetUp();
     52     test_util_.StartIOThread();
     53     ASSERT_TRUE(test_util_.profile());
     54     test_util_.profile()->CreateTemplateURLFetcher();
     55     ASSERT_TRUE(test_util_.profile()->GetTemplateURLFetcher());
     56 
     57     test_util_.profile()->CreateRequestContext();
     58     ASSERT_TRUE(test_util_.profile()->GetRequestContext());
     59     ASSERT_TRUE(test_server_.Start());
     60   }
     61 
     62   virtual void TearDown() {
     63     test_util_.TearDown();
     64   }
     65 
     66   // Called by ~TemplateURLFetcherTestCallbacks.
     67   void DestroyedCallback(TemplateURLFetcherTestCallbacks* callbacks);
     68 
     69   // TemplateURLFetcherCallbacks implementation.  (Although not derived from
     70   // this class, these methods handle those calls for the test.)
     71   virtual void ConfirmSetDefaultSearchProvider(
     72       TemplateURL* template_url,
     73       TemplateURLModel* template_url_model);
     74   virtual void ConfirmAddSearchProvider(
     75       TemplateURL* template_url,
     76       Profile* profile);
     77 
     78  protected:
     79   // Schedules the download of the url.
     80   void StartDownload(const string16& keyword,
     81                      const std::string& osdd_file_name,
     82                      TemplateURLFetcher::ProviderType provider_type,
     83                      bool check_that_file_exists);
     84 
     85   // Waits for any downloads to finish.
     86   void WaitForDownloadToFinish();
     87 
     88   TemplateURLModelTestUtil test_util_;
     89   net::TestServer test_server_;
     90 
     91   // The last TemplateURL to come from a callback.
     92   scoped_ptr<TemplateURL> last_callback_template_url_;
     93 
     94   // How many TemplateURLFetcherTestCallbacks have been destructed.
     95   int callbacks_destroyed_;
     96 
     97   // How many times ConfirmSetDefaultSearchProvider has been called.
     98   int set_default_called_;
     99 
    100   // How many times ConfirmAddSearchProvider has been called.
    101   int add_provider_called_;
    102 
    103   // Is the code in WaitForDownloadToFinish in a message loop waiting for a
    104   // callback to finish?
    105   bool waiting_for_download_;
    106 
    107  private:
    108   DISALLOW_COPY_AND_ASSIGN(TemplateURLFetcherTest);
    109 };
    110 
    111 TemplateURLFetcherTestCallbacks::~TemplateURLFetcherTestCallbacks() {
    112   test_->DestroyedCallback(this);
    113 }
    114 
    115 void TemplateURLFetcherTestCallbacks::ConfirmSetDefaultSearchProvider(
    116     TemplateURL* template_url,
    117     TemplateURLModel* template_url_model) {
    118   test_->ConfirmSetDefaultSearchProvider(template_url, template_url_model);
    119 }
    120 
    121 void TemplateURLFetcherTestCallbacks::ConfirmAddSearchProvider(
    122     TemplateURL* template_url,
    123     Profile* profile) {
    124   test_->ConfirmAddSearchProvider(template_url, profile);
    125 }
    126 
    127 TemplateURLFetcherTest::TemplateURLFetcherTest()
    128     : test_server_(net::TestServer::TYPE_HTTP,
    129                    FilePath(FILE_PATH_LITERAL("chrome/test/data"))),
    130       callbacks_destroyed_(0),
    131       set_default_called_(0),
    132       add_provider_called_(0),
    133       waiting_for_download_(false) {
    134 }
    135 
    136 void TemplateURLFetcherTest::DestroyedCallback(
    137     TemplateURLFetcherTestCallbacks* callbacks) {
    138   callbacks_destroyed_++;
    139   if (waiting_for_download_)
    140     MessageLoop::current()->Quit();
    141 }
    142 
    143 void TemplateURLFetcherTest::ConfirmSetDefaultSearchProvider(
    144     TemplateURL* template_url,
    145     TemplateURLModel* template_url_model) {
    146   last_callback_template_url_.reset(template_url);
    147   set_default_called_++;
    148 }
    149 
    150 void TemplateURLFetcherTest::ConfirmAddSearchProvider(
    151     TemplateURL* template_url,
    152     Profile* profile) {
    153   last_callback_template_url_.reset(template_url);
    154   add_provider_called_++;
    155 }
    156 
    157 void TemplateURLFetcherTest::StartDownload(
    158     const string16& keyword,
    159     const std::string& osdd_file_name,
    160     TemplateURLFetcher::ProviderType provider_type,
    161     bool check_that_file_exists) {
    162 
    163   if (check_that_file_exists) {
    164     FilePath osdd_full_path;
    165     ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &osdd_full_path));
    166     osdd_full_path = osdd_full_path.AppendASCII(osdd_file_name);
    167     ASSERT_TRUE(file_util::PathExists(osdd_full_path));
    168     ASSERT_FALSE(file_util::DirectoryExists(osdd_full_path));
    169   }
    170 
    171   // Start the fetch.
    172   GURL osdd_url = test_server_.GetURL("files/" + osdd_file_name);
    173   GURL favicon_url;
    174   test_util_.profile()->GetTemplateURLFetcher()->ScheduleDownload(
    175       keyword, osdd_url, favicon_url, new TemplateURLFetcherTestCallbacks(this),
    176       provider_type);
    177 }
    178 
    179 void TemplateURLFetcherTest::WaitForDownloadToFinish() {
    180   ASSERT_FALSE(waiting_for_download_);
    181   waiting_for_download_ = true;
    182   MessageLoop::current()->Run();
    183   waiting_for_download_ = false;
    184 }
    185 
    186 TEST_F(TemplateURLFetcherTest, BasicAutodetectedTest) {
    187   string16 keyword(ASCIIToUTF16("test"));
    188 
    189   test_util_.ChangeModelToLoadState();
    190   ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
    191 
    192   std::string osdd_file_name("simple_open_search.xml");
    193   StartDownload(keyword, osdd_file_name,
    194                 TemplateURLFetcher::AUTODETECTED_PROVIDER, true);
    195   ASSERT_EQ(0, set_default_called_);
    196   ASSERT_EQ(0, add_provider_called_);
    197   ASSERT_EQ(0, callbacks_destroyed_);
    198 
    199   WaitForDownloadToFinish();
    200   ASSERT_EQ(0, set_default_called_);
    201   ASSERT_EQ(0, add_provider_called_);
    202   ASSERT_EQ(1, callbacks_destroyed_);
    203 
    204   const TemplateURL* t_url = test_util_.model()->GetTemplateURLForKeyword(
    205       keyword);
    206   ASSERT_TRUE(t_url);
    207   EXPECT_EQ(ASCIIToUTF16("http://example.com/%s/other_stuff"),
    208             t_url->url()->DisplayURL());
    209   EXPECT_TRUE(t_url->safe_for_autoreplace());
    210 }
    211 
    212 TEST_F(TemplateURLFetcherTest, DuplicatesThrownAway) {
    213   string16 keyword(ASCIIToUTF16("test"));
    214 
    215   test_util_.ChangeModelToLoadState();
    216   ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
    217 
    218   std::string osdd_file_name("simple_open_search.xml");
    219   StartDownload(keyword, osdd_file_name,
    220                 TemplateURLFetcher::AUTODETECTED_PROVIDER, true);
    221   ASSERT_EQ(0, set_default_called_);
    222   ASSERT_EQ(0, add_provider_called_);
    223   ASSERT_EQ(0, callbacks_destroyed_);
    224 
    225   struct {
    226     std::string description;
    227     std::string osdd_file_name;
    228     string16 keyword;
    229     TemplateURLFetcher::ProviderType provider_type;
    230   } test_cases[] = {
    231       { "Duplicate keyword and osdd url with autodetected provider.",
    232         osdd_file_name, keyword, TemplateURLFetcher::AUTODETECTED_PROVIDER },
    233       { "Duplicate keyword and osdd url with explicit provider.",
    234         osdd_file_name, keyword, TemplateURLFetcher::EXPLICIT_PROVIDER },
    235       { "Duplicate osdd url with explicit provider.",
    236         osdd_file_name, keyword + ASCIIToUTF16("1"),
    237         TemplateURLFetcher::EXPLICIT_PROVIDER },
    238       { "Duplicate keyword with explicit provider.",
    239         osdd_file_name + "1", keyword, TemplateURLFetcher::EXPLICIT_PROVIDER }
    240   };
    241 
    242   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
    243     StartDownload(test_cases[i].keyword, test_cases[i].osdd_file_name,
    244                   test_cases[i].provider_type, false);
    245     ASSERT_EQ(
    246         1,
    247         test_util_.profile()->GetTemplateURLFetcher()->requests_count()) <<
    248         test_cases[i].description;
    249     ASSERT_EQ(i + 1, static_cast<size_t>(callbacks_destroyed_));
    250   }
    251 
    252   WaitForDownloadToFinish();
    253   ASSERT_EQ(1 + ARRAYSIZE_UNSAFE(test_cases),
    254             static_cast<size_t>(callbacks_destroyed_));
    255   ASSERT_EQ(0, set_default_called_);
    256   ASSERT_EQ(0, add_provider_called_);
    257 }
    258 
    259 TEST_F(TemplateURLFetcherTest, BasicExplicitTest) {
    260   string16 keyword(ASCIIToUTF16("test"));
    261 
    262   test_util_.ChangeModelToLoadState();
    263   ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
    264 
    265   std::string osdd_file_name("simple_open_search.xml");
    266   StartDownload(keyword, osdd_file_name,
    267                 TemplateURLFetcher::EXPLICIT_PROVIDER, true);
    268   ASSERT_EQ(0, set_default_called_);
    269   ASSERT_EQ(0, add_provider_called_);
    270   ASSERT_EQ(0, callbacks_destroyed_);
    271 
    272   WaitForDownloadToFinish();
    273   ASSERT_EQ(0, set_default_called_);
    274   ASSERT_EQ(1, add_provider_called_);
    275   ASSERT_EQ(1, callbacks_destroyed_);
    276 
    277   ASSERT_TRUE(last_callback_template_url_.get());
    278   EXPECT_EQ(ASCIIToUTF16("http://example.com/%s/other_stuff"),
    279             last_callback_template_url_->url()->DisplayURL());
    280   EXPECT_FALSE(last_callback_template_url_->safe_for_autoreplace());
    281 }
    282 
    283 TEST_F(TemplateURLFetcherTest, BasicExplicitDefaultTest) {
    284   string16 keyword(ASCIIToUTF16("test"));
    285 
    286   test_util_.ChangeModelToLoadState();
    287   ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
    288 
    289   std::string osdd_file_name("simple_open_search.xml");
    290   StartDownload(keyword, osdd_file_name,
    291                 TemplateURLFetcher::EXPLICIT_DEFAULT_PROVIDER, true);
    292   ASSERT_EQ(0, set_default_called_);
    293   ASSERT_EQ(0, add_provider_called_);
    294   ASSERT_EQ(0, callbacks_destroyed_);
    295 
    296   WaitForDownloadToFinish();
    297   ASSERT_EQ(1, set_default_called_);
    298   ASSERT_EQ(0, add_provider_called_);
    299   ASSERT_EQ(1, callbacks_destroyed_);
    300 
    301   ASSERT_TRUE(last_callback_template_url_.get());
    302   EXPECT_EQ(ASCIIToUTF16("http://example.com/%s/other_stuff"),
    303             last_callback_template_url_->url()->DisplayURL());
    304   EXPECT_FALSE(last_callback_template_url_->safe_for_autoreplace());
    305 }
    306 
    307 TEST_F(TemplateURLFetcherTest, AutodetectedBeforeLoadTest) {
    308   string16 keyword(ASCIIToUTF16("test"));
    309   ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
    310 
    311   std::string osdd_file_name("simple_open_search.xml");
    312   StartDownload(keyword, osdd_file_name,
    313                 TemplateURLFetcher::AUTODETECTED_PROVIDER, true);
    314   ASSERT_EQ(0, set_default_called_);
    315   ASSERT_EQ(0, add_provider_called_);
    316   ASSERT_EQ(1, callbacks_destroyed_);
    317 }
    318 
    319 TEST_F(TemplateURLFetcherTest, ExplicitBeforeLoadTest) {
    320   string16 keyword(ASCIIToUTF16("test"));
    321   ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
    322 
    323   std::string osdd_file_name("simple_open_search.xml");
    324   StartDownload(keyword, osdd_file_name,
    325                 TemplateURLFetcher::EXPLICIT_PROVIDER, true);
    326   ASSERT_EQ(0, set_default_called_);
    327   ASSERT_EQ(0, add_provider_called_);
    328   ASSERT_EQ(1, callbacks_destroyed_);
    329 }
    330 
    331 TEST_F(TemplateURLFetcherTest, ExplicitDefaultBeforeLoadTest) {
    332   string16 keyword(ASCIIToUTF16("test"));
    333   ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
    334 
    335   std::string osdd_file_name("simple_open_search.xml");
    336   StartDownload(keyword, osdd_file_name,
    337                 TemplateURLFetcher::EXPLICIT_DEFAULT_PROVIDER, true);
    338   ASSERT_EQ(0, set_default_called_);
    339   ASSERT_EQ(0, add_provider_called_);
    340   ASSERT_EQ(0, callbacks_destroyed_);
    341 
    342   WaitForDownloadToFinish();
    343   ASSERT_EQ(1, set_default_called_);
    344   ASSERT_EQ(0, add_provider_called_);
    345   ASSERT_EQ(1, callbacks_destroyed_);
    346 
    347   ASSERT_TRUE(last_callback_template_url_.get());
    348   EXPECT_EQ(ASCIIToUTF16("http://example.com/%s/other_stuff"),
    349             last_callback_template_url_->url()->DisplayURL());
    350   EXPECT_FALSE(last_callback_template_url_->safe_for_autoreplace());
    351 }
    352 
    353 TEST_F(TemplateURLFetcherTest, DuplicateKeywordsTest) {
    354   string16 keyword(ASCIIToUTF16("test"));
    355 
    356   TemplateURL* t_url = new TemplateURL();
    357   t_url->SetURL("http://example.com/", 0, 0);
    358   t_url->set_keyword(keyword);
    359   t_url->set_short_name(keyword);
    360   test_util_.model()->Add(t_url);
    361   test_util_.ChangeModelToLoadState();
    362 
    363   ASSERT_TRUE(test_util_.model()->GetTemplateURLForKeyword(keyword));
    364 
    365   std::string osdd_file_name("simple_open_search.xml");
    366   StartDownload(keyword, osdd_file_name,
    367                 TemplateURLFetcher::AUTODETECTED_PROVIDER, true);
    368   ASSERT_EQ(0, set_default_called_);
    369   ASSERT_EQ(0, add_provider_called_);
    370   ASSERT_EQ(1, callbacks_destroyed_);
    371 
    372   StartDownload(keyword, osdd_file_name,
    373                 TemplateURLFetcher::EXPLICIT_PROVIDER, true);
    374   ASSERT_EQ(0, set_default_called_);
    375   ASSERT_EQ(0, add_provider_called_);
    376   ASSERT_EQ(2, callbacks_destroyed_);
    377 
    378   StartDownload(keyword, osdd_file_name,
    379                 TemplateURLFetcher::EXPLICIT_DEFAULT_PROVIDER, true);
    380   ASSERT_EQ(0, set_default_called_);
    381   ASSERT_EQ(0, add_provider_called_);
    382   ASSERT_EQ(2, callbacks_destroyed_);
    383 
    384   WaitForDownloadToFinish();
    385   ASSERT_EQ(1, set_default_called_);
    386   ASSERT_EQ(0, add_provider_called_);
    387   ASSERT_EQ(3, callbacks_destroyed_);
    388   ASSERT_TRUE(last_callback_template_url_.get());
    389   ASSERT_NE(keyword, last_callback_template_url_->keyword());
    390 }
    391