// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/file_util.h" #include "base/message_loop.h" #include "base/path_service.h" #include "base/scoped_ptr.h" #include "chrome/browser/search_engines/template_url.h" #include "chrome/browser/search_engines/template_url_fetcher.h" #include "chrome/browser/search_engines/template_url_fetcher_callbacks.h" #include "chrome/browser/search_engines/template_url_model.h" #include "chrome/browser/search_engines/template_url_model_test_util.h" #include "chrome/common/chrome_paths.h" #include "chrome/test/testing_profile.h" #include "googleurl/src/gurl.h" #include "net/test/test_server.h" #include "testing/gtest/include/gtest/gtest.h" class TemplateURLFetcherTest; // Handles callbacks from TemplateURLFetcher. class TemplateURLFetcherTestCallbacks : public TemplateURLFetcherCallbacks { public: explicit TemplateURLFetcherTestCallbacks(TemplateURLFetcherTest* test) : test_(test) { } virtual ~TemplateURLFetcherTestCallbacks(); // TemplateURLFetcherCallbacks implementation. virtual void ConfirmSetDefaultSearchProvider( TemplateURL* template_url, TemplateURLModel* template_url_model); virtual void ConfirmAddSearchProvider( TemplateURL* template_url, Profile* profile); private: TemplateURLFetcherTest* test_; DISALLOW_COPY_AND_ASSIGN(TemplateURLFetcherTestCallbacks); }; // Basic set-up for TemplateURLFetcher tests. class TemplateURLFetcherTest : public testing::Test { public: TemplateURLFetcherTest(); virtual void SetUp() { test_util_.SetUp(); test_util_.StartIOThread(); ASSERT_TRUE(test_util_.profile()); test_util_.profile()->CreateTemplateURLFetcher(); ASSERT_TRUE(test_util_.profile()->GetTemplateURLFetcher()); test_util_.profile()->CreateRequestContext(); ASSERT_TRUE(test_util_.profile()->GetRequestContext()); ASSERT_TRUE(test_server_.Start()); } virtual void TearDown() { test_util_.TearDown(); } // Called by ~TemplateURLFetcherTestCallbacks. void DestroyedCallback(TemplateURLFetcherTestCallbacks* callbacks); // TemplateURLFetcherCallbacks implementation. (Although not derived from // this class, these methods handle those calls for the test.) virtual void ConfirmSetDefaultSearchProvider( TemplateURL* template_url, TemplateURLModel* template_url_model); virtual void ConfirmAddSearchProvider( TemplateURL* template_url, Profile* profile); protected: // Schedules the download of the url. void StartDownload(const std::wstring& keyword, const std::string& osdd_file_name, TemplateURLFetcher::ProviderType provider_type, bool check_that_file_exists); // Waits for any downloads to finish. void WaitForDownloadToFinish(); TemplateURLModelTestUtil test_util_; net::TestServer test_server_; // The last TemplateURL to come from a callback. scoped_ptr last_callback_template_url_; // How many TemplateURLFetcherTestCallbacks have been destructed. int callbacks_destroyed_; // How many times ConfirmSetDefaultSearchProvider has been called. int set_default_called_; // How many times ConfirmAddSearchProvider has been called. int add_provider_called_; // Is the code in WaitForDownloadToFinish in a message loop waiting for a // callback to finish? bool waiting_for_download_; private: DISALLOW_COPY_AND_ASSIGN(TemplateURLFetcherTest); }; TemplateURLFetcherTestCallbacks::~TemplateURLFetcherTestCallbacks() { test_->DestroyedCallback(this); } void TemplateURLFetcherTestCallbacks::ConfirmSetDefaultSearchProvider( TemplateURL* template_url, TemplateURLModel* template_url_model) { test_->ConfirmSetDefaultSearchProvider(template_url, template_url_model); } void TemplateURLFetcherTestCallbacks::ConfirmAddSearchProvider( TemplateURL* template_url, Profile* profile) { test_->ConfirmAddSearchProvider(template_url, profile); } TemplateURLFetcherTest::TemplateURLFetcherTest() : test_server_(net::TestServer::TYPE_HTTP, FilePath(FILE_PATH_LITERAL("chrome/test/data"))), callbacks_destroyed_(0), set_default_called_(0), add_provider_called_(0), waiting_for_download_(false) { } void TemplateURLFetcherTest::DestroyedCallback( TemplateURLFetcherTestCallbacks* callbacks) { callbacks_destroyed_++; if (waiting_for_download_) MessageLoop::current()->Quit(); } void TemplateURLFetcherTest::ConfirmSetDefaultSearchProvider( TemplateURL* template_url, TemplateURLModel* template_url_model) { last_callback_template_url_.reset(template_url); set_default_called_++; } void TemplateURLFetcherTest::ConfirmAddSearchProvider( TemplateURL* template_url, Profile* profile) { last_callback_template_url_.reset(template_url); add_provider_called_++; } void TemplateURLFetcherTest::StartDownload( const std::wstring& keyword, const std::string& osdd_file_name, TemplateURLFetcher::ProviderType provider_type, bool check_that_file_exists) { if (check_that_file_exists) { FilePath osdd_full_path; ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &osdd_full_path)); osdd_full_path = osdd_full_path.AppendASCII(osdd_file_name); ASSERT_TRUE(file_util::PathExists(osdd_full_path)); ASSERT_FALSE(file_util::DirectoryExists(osdd_full_path)); } // Start the fetch. GURL osdd_url = test_server_.GetURL("files/" + osdd_file_name); GURL favicon_url; test_util_.profile()->GetTemplateURLFetcher()->ScheduleDownload( keyword, osdd_url, favicon_url, new TemplateURLFetcherTestCallbacks(this), provider_type); } void TemplateURLFetcherTest::WaitForDownloadToFinish() { ASSERT_FALSE(waiting_for_download_); waiting_for_download_ = true; MessageLoop::current()->Run(); waiting_for_download_ = false; } TEST_F(TemplateURLFetcherTest, BasicAutodetectedTest) { std::wstring keyword(L"test"); test_util_.ChangeModelToLoadState(); ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword)); std::string osdd_file_name("simple_open_search.xml"); StartDownload(keyword, osdd_file_name, TemplateURLFetcher::AUTODETECTED_PROVIDER, true); ASSERT_EQ(0, set_default_called_); ASSERT_EQ(0, add_provider_called_); ASSERT_EQ(0, callbacks_destroyed_); WaitForDownloadToFinish(); ASSERT_EQ(0, set_default_called_); ASSERT_EQ(0, add_provider_called_); ASSERT_EQ(1, callbacks_destroyed_); const TemplateURL* t_url = test_util_.model()->GetTemplateURLForKeyword( keyword); ASSERT_TRUE(t_url); EXPECT_STREQ(L"http://example.com/%s/other_stuff", t_url->url()->DisplayURL().c_str()); EXPECT_TRUE(t_url->safe_for_autoreplace()); } TEST_F(TemplateURLFetcherTest, DuplicatesThrownAway) { std::wstring keyword(L"test"); test_util_.ChangeModelToLoadState(); ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword)); std::string osdd_file_name("simple_open_search.xml"); StartDownload(keyword, osdd_file_name, TemplateURLFetcher::AUTODETECTED_PROVIDER, true); ASSERT_EQ(0, set_default_called_); ASSERT_EQ(0, add_provider_called_); ASSERT_EQ(0, callbacks_destroyed_); struct { std::string description; std::string osdd_file_name; std::wstring keyword; TemplateURLFetcher::ProviderType provider_type; } test_cases[] = { { "Duplicate keyword and osdd url with autodetected provider.", osdd_file_name, keyword, TemplateURLFetcher::AUTODETECTED_PROVIDER }, { "Duplicate keyword and osdd url with explicit provider.", osdd_file_name, keyword, TemplateURLFetcher::EXPLICIT_PROVIDER }, { "Duplicate osdd url with explicit provider.", osdd_file_name, keyword + L"1", TemplateURLFetcher::EXPLICIT_PROVIDER }, { "Duplicate keyword with explicit provider.", osdd_file_name + "1", keyword, TemplateURLFetcher::EXPLICIT_PROVIDER } }; for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { StartDownload(test_cases[i].keyword, test_cases[i].osdd_file_name, test_cases[i].provider_type, false); ASSERT_EQ( 1, test_util_.profile()->GetTemplateURLFetcher()->requests_count()) << test_cases[i].description; ASSERT_EQ(i + 1, static_cast(callbacks_destroyed_)); } WaitForDownloadToFinish(); ASSERT_EQ(1 + ARRAYSIZE_UNSAFE(test_cases), static_cast(callbacks_destroyed_)); ASSERT_EQ(0, set_default_called_); ASSERT_EQ(0, add_provider_called_); } TEST_F(TemplateURLFetcherTest, BasicExplicitTest) { std::wstring keyword(L"test"); test_util_.ChangeModelToLoadState(); ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword)); std::string osdd_file_name("simple_open_search.xml"); StartDownload(keyword, osdd_file_name, TemplateURLFetcher::EXPLICIT_PROVIDER, true); ASSERT_EQ(0, set_default_called_); ASSERT_EQ(0, add_provider_called_); ASSERT_EQ(0, callbacks_destroyed_); WaitForDownloadToFinish(); ASSERT_EQ(0, set_default_called_); ASSERT_EQ(1, add_provider_called_); ASSERT_EQ(1, callbacks_destroyed_); ASSERT_TRUE(last_callback_template_url_.get()); EXPECT_STREQ(L"http://example.com/%s/other_stuff", last_callback_template_url_->url()->DisplayURL().c_str()); EXPECT_FALSE(last_callback_template_url_->safe_for_autoreplace()); } TEST_F(TemplateURLFetcherTest, BasicExplicitDefaultTest) { std::wstring keyword(L"test"); test_util_.ChangeModelToLoadState(); ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword)); std::string osdd_file_name("simple_open_search.xml"); StartDownload(keyword, osdd_file_name, TemplateURLFetcher::EXPLICIT_DEFAULT_PROVIDER, true); ASSERT_EQ(0, set_default_called_); ASSERT_EQ(0, add_provider_called_); ASSERT_EQ(0, callbacks_destroyed_); WaitForDownloadToFinish(); ASSERT_EQ(1, set_default_called_); ASSERT_EQ(0, add_provider_called_); ASSERT_EQ(1, callbacks_destroyed_); ASSERT_TRUE(last_callback_template_url_.get()); EXPECT_STREQ(L"http://example.com/%s/other_stuff", last_callback_template_url_->url()->DisplayURL().c_str()); EXPECT_FALSE(last_callback_template_url_->safe_for_autoreplace()); } TEST_F(TemplateURLFetcherTest, AutodetectedBeforeLoadTest) { std::wstring keyword(L"test"); ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword)); std::string osdd_file_name("simple_open_search.xml"); StartDownload(keyword, osdd_file_name, TemplateURLFetcher::AUTODETECTED_PROVIDER, true); ASSERT_EQ(0, set_default_called_); ASSERT_EQ(0, add_provider_called_); ASSERT_EQ(1, callbacks_destroyed_); } TEST_F(TemplateURLFetcherTest, ExplicitBeforeLoadTest) { std::wstring keyword(L"test"); ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword)); std::string osdd_file_name("simple_open_search.xml"); StartDownload(keyword, osdd_file_name, TemplateURLFetcher::EXPLICIT_PROVIDER, true); ASSERT_EQ(0, set_default_called_); ASSERT_EQ(0, add_provider_called_); ASSERT_EQ(1, callbacks_destroyed_); } TEST_F(TemplateURLFetcherTest, ExplicitDefaultBeforeLoadTest) { std::wstring keyword(L"test"); ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword)); std::string osdd_file_name("simple_open_search.xml"); StartDownload(keyword, osdd_file_name, TemplateURLFetcher::EXPLICIT_DEFAULT_PROVIDER, true); ASSERT_EQ(0, set_default_called_); ASSERT_EQ(0, add_provider_called_); ASSERT_EQ(0, callbacks_destroyed_); WaitForDownloadToFinish(); ASSERT_EQ(1, set_default_called_); ASSERT_EQ(0, add_provider_called_); ASSERT_EQ(1, callbacks_destroyed_); ASSERT_TRUE(last_callback_template_url_.get()); EXPECT_STREQ(L"http://example.com/%s/other_stuff", last_callback_template_url_->url()->DisplayURL().c_str()); EXPECT_FALSE(last_callback_template_url_->safe_for_autoreplace()); } TEST_F(TemplateURLFetcherTest, DuplicateKeywordsTest) { std::wstring keyword(L"test"); TemplateURL* t_url = new TemplateURL(); t_url->SetURL("http://example.com/", 0, 0); t_url->set_keyword(keyword); t_url->set_short_name(keyword); test_util_.model()->Add(t_url); test_util_.ChangeModelToLoadState(); ASSERT_TRUE(test_util_.model()->GetTemplateURLForKeyword(keyword)); std::string osdd_file_name("simple_open_search.xml"); StartDownload(keyword, osdd_file_name, TemplateURLFetcher::AUTODETECTED_PROVIDER, true); ASSERT_EQ(0, set_default_called_); ASSERT_EQ(0, add_provider_called_); ASSERT_EQ(1, callbacks_destroyed_); StartDownload(keyword, osdd_file_name, TemplateURLFetcher::EXPLICIT_PROVIDER, true); ASSERT_EQ(0, set_default_called_); ASSERT_EQ(0, add_provider_called_); ASSERT_EQ(2, callbacks_destroyed_); StartDownload(keyword, osdd_file_name, TemplateURLFetcher::EXPLICIT_DEFAULT_PROVIDER, true); ASSERT_EQ(0, set_default_called_); ASSERT_EQ(0, add_provider_called_); ASSERT_EQ(2, callbacks_destroyed_); WaitForDownloadToFinish(); ASSERT_EQ(1, set_default_called_); ASSERT_EQ(0, add_provider_called_); ASSERT_EQ(3, callbacks_destroyed_); ASSERT_TRUE(last_callback_template_url_.get()); ASSERT_STRNE(keyword.c_str(), last_callback_template_url_->keyword().c_str()); }