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.
5 #include "base/file_util.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/path_service.h"
9 #include "base/strings/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_fetcher_factory.h"
14 #include "chrome/browser/search_engines/template_url_service.h"
15 #include "chrome/browser/search_engines/template_url_service_test_util.h"
16 #include "chrome/common/chrome_paths.h"
17 #include "chrome/test/base/testing_profile.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "net/test/embedded_test_server/embedded_test_server.h"
20 #include "testing/gtest/include/gtest/gtest.h"
23 class TemplateURLFetcherTest;
25 // Handles callbacks from TemplateURLFetcher.
26 class TemplateURLFetcherTestCallbacks : public TemplateURLFetcherCallbacks {
28 explicit TemplateURLFetcherTestCallbacks(TemplateURLFetcherTest* test)
31 virtual ~TemplateURLFetcherTestCallbacks();
33 // TemplateURLFetcherCallbacks implementation.
34 virtual void ConfirmAddSearchProvider(TemplateURL* template_url,
35 Profile* profile) OVERRIDE;
38 TemplateURLFetcherTest* test_;
40 DISALLOW_COPY_AND_ASSIGN(TemplateURLFetcherTestCallbacks);
43 // Basic set-up for TemplateURLFetcher tests.
44 class TemplateURLFetcherTest : public testing::Test {
46 TemplateURLFetcherTest();
48 virtual void SetUp() OVERRIDE {
50 TestingProfile* profile = test_util_.profile();
52 ASSERT_TRUE(TemplateURLFetcherFactory::GetForProfile(profile));
54 ASSERT_TRUE(profile->GetRequestContext());
55 ASSERT_TRUE(test_server_.InitializeAndWaitUntilReady());
58 virtual void TearDown() OVERRIDE {
59 ASSERT_TRUE(test_server_.ShutdownAndWaitUntilComplete());
60 test_util_.TearDown();
63 // Called by ~TemplateURLFetcherTestCallbacks.
64 void DestroyedCallback(TemplateURLFetcherTestCallbacks* callbacks);
66 // TemplateURLFetcherCallbacks implementation. (Although not derived from
67 // this class, this method handles those calls for the test.)
68 void ConfirmAddSearchProvider(TemplateURL* template_url, Profile* profile);
71 // Schedules the download of the url.
72 void StartDownload(const string16& keyword,
73 const std::string& osdd_file_name,
74 TemplateURLFetcher::ProviderType provider_type,
75 bool check_that_file_exists);
77 // Waits for any downloads to finish.
78 void WaitForDownloadToFinish();
80 TemplateURLServiceTestUtil test_util_;
81 net::test_server::EmbeddedTestServer test_server_;
83 // The last TemplateURL to come from a callback.
84 scoped_ptr<TemplateURL> last_callback_template_url_;
86 // How many TemplateURLFetcherTestCallbacks have been destructed.
87 int callbacks_destroyed_;
89 // How many times ConfirmAddSearchProvider has been called.
90 int add_provider_called_;
92 // Is the code in WaitForDownloadToFinish in a message loop waiting for a
93 // callback to finish?
94 bool waiting_for_download_;
97 DISALLOW_COPY_AND_ASSIGN(TemplateURLFetcherTest);
100 TemplateURLFetcherTestCallbacks::~TemplateURLFetcherTestCallbacks() {
101 test_->DestroyedCallback(this);
104 void TemplateURLFetcherTestCallbacks::ConfirmAddSearchProvider(
105 TemplateURL* template_url,
107 test_->ConfirmAddSearchProvider(template_url, profile);
110 TemplateURLFetcherTest::TemplateURLFetcherTest()
111 : callbacks_destroyed_(0),
112 add_provider_called_(0),
113 waiting_for_download_(false) {
114 base::FilePath src_dir;
115 CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &src_dir));
116 test_server_.ServeFilesFromDirectory(
117 src_dir.AppendASCII("chrome/test/data"));
120 void TemplateURLFetcherTest::DestroyedCallback(
121 TemplateURLFetcherTestCallbacks* callbacks) {
122 callbacks_destroyed_++;
123 if (waiting_for_download_)
124 base::MessageLoop::current()->Quit();
127 void TemplateURLFetcherTest::ConfirmAddSearchProvider(
128 TemplateURL* template_url,
130 last_callback_template_url_.reset(template_url);
131 add_provider_called_++;
134 void TemplateURLFetcherTest::StartDownload(
135 const string16& keyword,
136 const std::string& osdd_file_name,
137 TemplateURLFetcher::ProviderType provider_type,
138 bool check_that_file_exists) {
140 if (check_that_file_exists) {
141 base::FilePath osdd_full_path;
142 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &osdd_full_path));
143 osdd_full_path = osdd_full_path.AppendASCII(osdd_file_name);
144 ASSERT_TRUE(base::PathExists(osdd_full_path));
145 ASSERT_FALSE(base::DirectoryExists(osdd_full_path));
149 GURL osdd_url = test_server_.GetURL("/" + osdd_file_name);
151 TemplateURLFetcherFactory::GetForProfile(
152 test_util_.profile())->ScheduleDownload(
153 keyword, osdd_url, favicon_url, NULL,
154 new TemplateURLFetcherTestCallbacks(this), provider_type);
157 void TemplateURLFetcherTest::WaitForDownloadToFinish() {
158 ASSERT_FALSE(waiting_for_download_);
159 waiting_for_download_ = true;
160 base::MessageLoop::current()->Run();
161 waiting_for_download_ = false;
164 TEST_F(TemplateURLFetcherTest, BasicAutodetectedTest) {
165 string16 keyword(ASCIIToUTF16("test"));
167 test_util_.ChangeModelToLoadState();
168 ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
170 std::string osdd_file_name("simple_open_search.xml");
171 StartDownload(keyword, osdd_file_name,
172 TemplateURLFetcher::AUTODETECTED_PROVIDER, true);
173 ASSERT_EQ(0, add_provider_called_);
174 ASSERT_EQ(0, callbacks_destroyed_);
176 WaitForDownloadToFinish();
177 ASSERT_EQ(0, add_provider_called_);
178 ASSERT_EQ(1, callbacks_destroyed_);
180 const TemplateURL* t_url = test_util_.model()->GetTemplateURLForKeyword(
183 EXPECT_EQ(ASCIIToUTF16("http://example.com/%s/other_stuff"),
184 t_url->url_ref().DisplayURL());
185 EXPECT_TRUE(t_url->safe_for_autoreplace());
188 TEST_F(TemplateURLFetcherTest, DuplicatesThrownAway) {
189 string16 keyword(ASCIIToUTF16("test"));
191 test_util_.ChangeModelToLoadState();
192 ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
194 std::string osdd_file_name("simple_open_search.xml");
195 StartDownload(keyword, osdd_file_name,
196 TemplateURLFetcher::AUTODETECTED_PROVIDER, true);
197 ASSERT_EQ(0, add_provider_called_);
198 ASSERT_EQ(0, callbacks_destroyed_);
201 std::string description;
202 std::string osdd_file_name;
204 TemplateURLFetcher::ProviderType provider_type;
206 { "Duplicate osdd url with autodetected provider.", osdd_file_name,
207 keyword + ASCIIToUTF16("1"),
208 TemplateURLFetcher::AUTODETECTED_PROVIDER },
209 { "Duplicate keyword with autodetected provider.", osdd_file_name + "1",
210 keyword, TemplateURLFetcher::AUTODETECTED_PROVIDER },
211 { "Duplicate osdd url with explicit provider.", osdd_file_name,
212 string16(), TemplateURLFetcher::EXPLICIT_PROVIDER },
215 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
216 StartDownload(test_cases[i].keyword, test_cases[i].osdd_file_name,
217 test_cases[i].provider_type, false);
220 TemplateURLFetcherFactory::GetForProfile(
221 test_util_.profile())->requests_count()) <<
222 test_cases[i].description;
223 ASSERT_EQ(i + 1, static_cast<size_t>(callbacks_destroyed_));
226 WaitForDownloadToFinish();
227 ASSERT_EQ(1 + ARRAYSIZE_UNSAFE(test_cases),
228 static_cast<size_t>(callbacks_destroyed_));
229 ASSERT_EQ(0, add_provider_called_);
232 TEST_F(TemplateURLFetcherTest, BasicExplicitTest) {
233 string16 keyword(ASCIIToUTF16("test"));
235 test_util_.ChangeModelToLoadState();
236 ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
238 std::string osdd_file_name("simple_open_search.xml");
239 StartDownload(keyword, osdd_file_name,
240 TemplateURLFetcher::EXPLICIT_PROVIDER, true);
241 ASSERT_EQ(0, add_provider_called_);
242 ASSERT_EQ(0, callbacks_destroyed_);
244 WaitForDownloadToFinish();
245 ASSERT_EQ(1, add_provider_called_);
246 ASSERT_EQ(1, callbacks_destroyed_);
248 ASSERT_TRUE(last_callback_template_url_.get());
249 EXPECT_EQ(ASCIIToUTF16("http://example.com/%s/other_stuff"),
250 last_callback_template_url_->url_ref().DisplayURL());
251 EXPECT_EQ(ASCIIToUTF16("example.com"),
252 last_callback_template_url_->keyword());
253 EXPECT_FALSE(last_callback_template_url_->safe_for_autoreplace());
256 TEST_F(TemplateURLFetcherTest, AutodetectedBeforeLoadTest) {
257 string16 keyword(ASCIIToUTF16("test"));
258 ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
260 std::string osdd_file_name("simple_open_search.xml");
261 StartDownload(keyword, osdd_file_name,
262 TemplateURLFetcher::AUTODETECTED_PROVIDER, true);
263 ASSERT_EQ(0, add_provider_called_);
264 ASSERT_EQ(1, callbacks_destroyed_);
267 TEST_F(TemplateURLFetcherTest, ExplicitBeforeLoadTest) {
268 string16 keyword(ASCIIToUTF16("test"));
269 ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
271 std::string osdd_file_name("simple_open_search.xml");
272 StartDownload(keyword, osdd_file_name,
273 TemplateURLFetcher::EXPLICIT_PROVIDER, true);
274 ASSERT_EQ(0, add_provider_called_);
275 ASSERT_EQ(0, callbacks_destroyed_);
277 WaitForDownloadToFinish();
278 ASSERT_EQ(1, add_provider_called_);
279 ASSERT_EQ(1, callbacks_destroyed_);
281 ASSERT_TRUE(last_callback_template_url_.get());
282 EXPECT_EQ(ASCIIToUTF16("http://example.com/%s/other_stuff"),
283 last_callback_template_url_->url_ref().DisplayURL());
284 EXPECT_EQ(ASCIIToUTF16("example.com"),
285 last_callback_template_url_->keyword());
286 EXPECT_FALSE(last_callback_template_url_->safe_for_autoreplace());
289 TEST_F(TemplateURLFetcherTest, DuplicateKeywordsTest) {
290 string16 keyword(ASCIIToUTF16("test"));
291 TemplateURLData data;
292 data.short_name = keyword;
293 data.SetKeyword(keyword);
294 data.SetURL("http://example.com/");
295 test_util_.model()->Add(new TemplateURL(test_util_.profile(), data));
296 test_util_.ChangeModelToLoadState();
298 ASSERT_TRUE(test_util_.model()->GetTemplateURLForKeyword(keyword));
300 // This should bail because the keyword already exists.
301 std::string osdd_file_name("simple_open_search.xml");
302 StartDownload(keyword, osdd_file_name,
303 TemplateURLFetcher::AUTODETECTED_PROVIDER, true);
304 ASSERT_EQ(0, add_provider_called_);
305 ASSERT_EQ(1, callbacks_destroyed_);
306 ASSERT_FALSE(last_callback_template_url_.get());
309 TEST_F(TemplateURLFetcherTest, DuplicateDownloadTest) {
310 string16 keyword(ASCIIToUTF16("test"));
311 std::string osdd_file_name("simple_open_search.xml");
312 StartDownload(keyword, osdd_file_name,
313 TemplateURLFetcher::EXPLICIT_PROVIDER, true);
314 ASSERT_EQ(0, add_provider_called_);
315 ASSERT_EQ(0, callbacks_destroyed_);
317 // This should bail because the keyword already has a pending download.
318 StartDownload(keyword, osdd_file_name,
319 TemplateURLFetcher::EXPLICIT_PROVIDER, true);
320 ASSERT_EQ(0, add_provider_called_);
321 ASSERT_EQ(1, callbacks_destroyed_);
323 WaitForDownloadToFinish();
324 ASSERT_EQ(1, add_provider_called_);
325 ASSERT_EQ(2, callbacks_destroyed_);
326 ASSERT_TRUE(last_callback_template_url_.get());