template_url_fetcher_unittest.cc revision 72a454cd3513ac24fbdd0e0cb9ad70b86a99b801
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/message_loop.h"
7#include "base/path_service.h"
8#include "base/scoped_ptr.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
21class TemplateURLFetcherTest;
22
23// Handles callbacks from TemplateURLFetcher.
24class 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.
46class 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
111TemplateURLFetcherTestCallbacks::~TemplateURLFetcherTestCallbacks() {
112  test_->DestroyedCallback(this);
113}
114
115void TemplateURLFetcherTestCallbacks::ConfirmSetDefaultSearchProvider(
116    TemplateURL* template_url,
117    TemplateURLModel* template_url_model) {
118  test_->ConfirmSetDefaultSearchProvider(template_url, template_url_model);
119}
120
121void TemplateURLFetcherTestCallbacks::ConfirmAddSearchProvider(
122    TemplateURL* template_url,
123    Profile* profile) {
124  test_->ConfirmAddSearchProvider(template_url, profile);
125}
126
127TemplateURLFetcherTest::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
136void TemplateURLFetcherTest::DestroyedCallback(
137    TemplateURLFetcherTestCallbacks* callbacks) {
138  callbacks_destroyed_++;
139  if (waiting_for_download_)
140    MessageLoop::current()->Quit();
141}
142
143void 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
150void TemplateURLFetcherTest::ConfirmAddSearchProvider(
151    TemplateURL* template_url,
152    Profile* profile) {
153  last_callback_template_url_.reset(template_url);
154  add_provider_called_++;
155}
156
157void 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
179void TemplateURLFetcherTest::WaitForDownloadToFinish() {
180  ASSERT_FALSE(waiting_for_download_);
181  waiting_for_download_ = true;
182  MessageLoop::current()->Run();
183  waiting_for_download_ = false;
184}
185
186TEST_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
212TEST_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
259TEST_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
283TEST_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
307TEST_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
319TEST_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
331TEST_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
353TEST_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