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:
TemplateURLFetcherTestCallbacks(TemplateURLFetcherTest * test)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
SetUp()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
TearDown()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
~TemplateURLFetcherTestCallbacks()111 TemplateURLFetcherTestCallbacks::~TemplateURLFetcherTestCallbacks() {
112 test_->DestroyedCallback(this);
113 }
114
ConfirmSetDefaultSearchProvider(TemplateURL * template_url,TemplateURLModel * template_url_model)115 void TemplateURLFetcherTestCallbacks::ConfirmSetDefaultSearchProvider(
116 TemplateURL* template_url,
117 TemplateURLModel* template_url_model) {
118 test_->ConfirmSetDefaultSearchProvider(template_url, template_url_model);
119 }
120
ConfirmAddSearchProvider(TemplateURL * template_url,Profile * profile)121 void TemplateURLFetcherTestCallbacks::ConfirmAddSearchProvider(
122 TemplateURL* template_url,
123 Profile* profile) {
124 test_->ConfirmAddSearchProvider(template_url, profile);
125 }
126
TemplateURLFetcherTest()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
DestroyedCallback(TemplateURLFetcherTestCallbacks * callbacks)136 void TemplateURLFetcherTest::DestroyedCallback(
137 TemplateURLFetcherTestCallbacks* callbacks) {
138 callbacks_destroyed_++;
139 if (waiting_for_download_)
140 MessageLoop::current()->Quit();
141 }
142
ConfirmSetDefaultSearchProvider(TemplateURL * template_url,TemplateURLModel * template_url_model)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
ConfirmAddSearchProvider(TemplateURL * template_url,Profile * profile)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
StartDownload(const string16 & keyword,const std::string & osdd_file_name,TemplateURLFetcher::ProviderType provider_type,bool check_that_file_exists)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
WaitForDownloadToFinish()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
TEST_F(TemplateURLFetcherTest,BasicAutodetectedTest)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
TEST_F(TemplateURLFetcherTest,DuplicatesThrownAway)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
TEST_F(TemplateURLFetcherTest,BasicExplicitTest)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
TEST_F(TemplateURLFetcherTest,BasicExplicitDefaultTest)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
TEST_F(TemplateURLFetcherTest,AutodetectedBeforeLoadTest)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
TEST_F(TemplateURLFetcherTest,ExplicitBeforeLoadTest)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
TEST_F(TemplateURLFetcherTest,ExplicitDefaultBeforeLoadTest)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
TEST_F(TemplateURLFetcherTest,DuplicateKeywordsTest)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