b0b6ad8ae535859d5ffeda91caf667e2e4bfc48e
[platform/framework/web/crosswalk.git] / src / chrome / browser / search_engines / template_url_fetcher_unittest.cc
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.
4
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"
21 #include "url/gurl.h"
22
23 using base::ASCIIToUTF16;
24
25 class TemplateURLFetcherTest;
26
27 // Handles callbacks from TemplateURLFetcher.
28 class TemplateURLFetcherTestCallbacks : public TemplateURLFetcherCallbacks {
29  public:
30   explicit TemplateURLFetcherTestCallbacks(TemplateURLFetcherTest* test)
31       : test_(test) {
32   }
33   virtual ~TemplateURLFetcherTestCallbacks();
34
35   // TemplateURLFetcherCallbacks implementation.
36   virtual void ConfirmAddSearchProvider(TemplateURL* template_url,
37                                         Profile* profile) OVERRIDE;
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() OVERRIDE {
51     test_util_.SetUp();
52     TestingProfile* profile = test_util_.profile();
53     ASSERT_TRUE(profile);
54     ASSERT_TRUE(TemplateURLFetcherFactory::GetForProfile(profile));
55
56     ASSERT_TRUE(profile->GetRequestContext());
57     ASSERT_TRUE(test_server_.InitializeAndWaitUntilReady());
58   }
59
60   virtual void TearDown() OVERRIDE {
61     ASSERT_TRUE(test_server_.ShutdownAndWaitUntilComplete());
62     test_util_.TearDown();
63   }
64
65   // Called by ~TemplateURLFetcherTestCallbacks.
66   void DestroyedCallback(TemplateURLFetcherTestCallbacks* callbacks);
67
68   // TemplateURLFetcherCallbacks implementation.  (Although not derived from
69   // this class, this method handles those calls for the test.)
70   void ConfirmAddSearchProvider(TemplateURL* template_url, Profile* profile);
71
72  protected:
73   // Schedules the download of the url.
74   void StartDownload(const base::string16& keyword,
75                      const std::string& osdd_file_name,
76                      TemplateURLFetcher::ProviderType provider_type,
77                      bool check_that_file_exists);
78
79   // Waits for any downloads to finish.
80   void WaitForDownloadToFinish();
81
82   TemplateURLServiceTestUtil test_util_;
83   net::test_server::EmbeddedTestServer test_server_;
84
85   // The last TemplateURL to come from a callback.
86   scoped_ptr<TemplateURL> last_callback_template_url_;
87
88   // How many TemplateURLFetcherTestCallbacks have been destructed.
89   int callbacks_destroyed_;
90
91   // How many times ConfirmAddSearchProvider has been called.
92   int add_provider_called_;
93
94   // Is the code in WaitForDownloadToFinish in a message loop waiting for a
95   // callback to finish?
96   bool waiting_for_download_;
97
98  private:
99   DISALLOW_COPY_AND_ASSIGN(TemplateURLFetcherTest);
100 };
101
102 TemplateURLFetcherTestCallbacks::~TemplateURLFetcherTestCallbacks() {
103   test_->DestroyedCallback(this);
104 }
105
106 void TemplateURLFetcherTestCallbacks::ConfirmAddSearchProvider(
107     TemplateURL* template_url,
108     Profile* profile) {
109   test_->ConfirmAddSearchProvider(template_url, profile);
110 }
111
112 TemplateURLFetcherTest::TemplateURLFetcherTest()
113     : callbacks_destroyed_(0),
114       add_provider_called_(0),
115       waiting_for_download_(false) {
116   base::FilePath src_dir;
117   CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &src_dir));
118   test_server_.ServeFilesFromDirectory(
119       src_dir.AppendASCII("chrome/test/data"));
120 }
121
122 void TemplateURLFetcherTest::DestroyedCallback(
123     TemplateURLFetcherTestCallbacks* callbacks) {
124   callbacks_destroyed_++;
125   if (waiting_for_download_)
126     base::MessageLoop::current()->Quit();
127 }
128
129 void TemplateURLFetcherTest::ConfirmAddSearchProvider(
130     TemplateURL* template_url,
131     Profile* profile) {
132   last_callback_template_url_.reset(template_url);
133   add_provider_called_++;
134 }
135
136 void TemplateURLFetcherTest::StartDownload(
137     const base::string16& keyword,
138     const std::string& osdd_file_name,
139     TemplateURLFetcher::ProviderType provider_type,
140     bool check_that_file_exists) {
141
142   if (check_that_file_exists) {
143     base::FilePath osdd_full_path;
144     ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &osdd_full_path));
145     osdd_full_path = osdd_full_path.AppendASCII(osdd_file_name);
146     ASSERT_TRUE(base::PathExists(osdd_full_path));
147     ASSERT_FALSE(base::DirectoryExists(osdd_full_path));
148   }
149
150   // Start the fetch.
151   GURL osdd_url = test_server_.GetURL("/" + osdd_file_name);
152   GURL favicon_url;
153   TemplateURLFetcherFactory::GetForProfile(
154       test_util_.profile())->ScheduleDownload(
155           keyword, osdd_url, favicon_url, NULL,
156           new TemplateURLFetcherTestCallbacks(this), provider_type);
157 }
158
159 void TemplateURLFetcherTest::WaitForDownloadToFinish() {
160   ASSERT_FALSE(waiting_for_download_);
161   waiting_for_download_ = true;
162   base::MessageLoop::current()->Run();
163   waiting_for_download_ = false;
164 }
165
166 TEST_F(TemplateURLFetcherTest, BasicAutodetectedTest) {
167   base::string16 keyword(ASCIIToUTF16("test"));
168
169   test_util_.ChangeModelToLoadState();
170   ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
171
172   std::string osdd_file_name("simple_open_search.xml");
173   StartDownload(keyword, osdd_file_name,
174                 TemplateURLFetcher::AUTODETECTED_PROVIDER, true);
175   ASSERT_EQ(0, add_provider_called_);
176   ASSERT_EQ(0, callbacks_destroyed_);
177
178   WaitForDownloadToFinish();
179   ASSERT_EQ(0, add_provider_called_);
180   ASSERT_EQ(1, callbacks_destroyed_);
181
182   const TemplateURL* t_url = test_util_.model()->GetTemplateURLForKeyword(
183       keyword);
184   ASSERT_TRUE(t_url);
185   EXPECT_EQ(ASCIIToUTF16("http://example.com/%s/other_stuff"),
186             t_url->url_ref().DisplayURL());
187   EXPECT_TRUE(t_url->safe_for_autoreplace());
188 }
189
190 TEST_F(TemplateURLFetcherTest, DuplicatesThrownAway) {
191   base::string16 keyword(ASCIIToUTF16("test"));
192
193   test_util_.ChangeModelToLoadState();
194   ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
195
196   std::string osdd_file_name("simple_open_search.xml");
197   StartDownload(keyword, osdd_file_name,
198                 TemplateURLFetcher::AUTODETECTED_PROVIDER, true);
199   ASSERT_EQ(0, add_provider_called_);
200   ASSERT_EQ(0, callbacks_destroyed_);
201
202   struct {
203     std::string description;
204     std::string osdd_file_name;
205     base::string16 keyword;
206     TemplateURLFetcher::ProviderType provider_type;
207   } test_cases[] = {
208       { "Duplicate osdd url with autodetected provider.", osdd_file_name,
209         keyword + ASCIIToUTF16("1"),
210         TemplateURLFetcher::AUTODETECTED_PROVIDER },
211       { "Duplicate keyword with autodetected provider.", osdd_file_name + "1",
212         keyword, TemplateURLFetcher::AUTODETECTED_PROVIDER },
213       { "Duplicate osdd url with explicit provider.", osdd_file_name,
214         base::string16(), TemplateURLFetcher::EXPLICIT_PROVIDER },
215   };
216
217   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
218     StartDownload(test_cases[i].keyword, test_cases[i].osdd_file_name,
219                   test_cases[i].provider_type, false);
220     ASSERT_EQ(
221         1,
222         TemplateURLFetcherFactory::GetForProfile(
223             test_util_.profile())->requests_count()) <<
224         test_cases[i].description;
225     ASSERT_EQ(i + 1, static_cast<size_t>(callbacks_destroyed_));
226   }
227
228   WaitForDownloadToFinish();
229   ASSERT_EQ(1 + ARRAYSIZE_UNSAFE(test_cases),
230             static_cast<size_t>(callbacks_destroyed_));
231   ASSERT_EQ(0, add_provider_called_);
232 }
233
234 TEST_F(TemplateURLFetcherTest, BasicExplicitTest) {
235   base::string16 keyword(ASCIIToUTF16("test"));
236
237   test_util_.ChangeModelToLoadState();
238   ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
239
240   std::string osdd_file_name("simple_open_search.xml");
241   StartDownload(keyword, osdd_file_name,
242                 TemplateURLFetcher::EXPLICIT_PROVIDER, true);
243   ASSERT_EQ(0, add_provider_called_);
244   ASSERT_EQ(0, callbacks_destroyed_);
245
246   WaitForDownloadToFinish();
247   ASSERT_EQ(1, add_provider_called_);
248   ASSERT_EQ(1, callbacks_destroyed_);
249
250   ASSERT_TRUE(last_callback_template_url_.get());
251   EXPECT_EQ(ASCIIToUTF16("http://example.com/%s/other_stuff"),
252             last_callback_template_url_->url_ref().DisplayURL());
253   EXPECT_EQ(ASCIIToUTF16("example.com"),
254             last_callback_template_url_->keyword());
255   EXPECT_FALSE(last_callback_template_url_->safe_for_autoreplace());
256 }
257
258 TEST_F(TemplateURLFetcherTest, AutodetectedBeforeLoadTest) {
259   base::string16 keyword(ASCIIToUTF16("test"));
260   ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
261
262   std::string osdd_file_name("simple_open_search.xml");
263   StartDownload(keyword, osdd_file_name,
264                 TemplateURLFetcher::AUTODETECTED_PROVIDER, true);
265   ASSERT_EQ(0, add_provider_called_);
266   ASSERT_EQ(1, callbacks_destroyed_);
267 }
268
269 TEST_F(TemplateURLFetcherTest, ExplicitBeforeLoadTest) {
270   base::string16 keyword(ASCIIToUTF16("test"));
271   ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
272
273   std::string osdd_file_name("simple_open_search.xml");
274   StartDownload(keyword, osdd_file_name,
275                 TemplateURLFetcher::EXPLICIT_PROVIDER, true);
276   ASSERT_EQ(0, add_provider_called_);
277   ASSERT_EQ(0, callbacks_destroyed_);
278
279   WaitForDownloadToFinish();
280   ASSERT_EQ(1, add_provider_called_);
281   ASSERT_EQ(1, callbacks_destroyed_);
282
283   ASSERT_TRUE(last_callback_template_url_.get());
284   EXPECT_EQ(ASCIIToUTF16("http://example.com/%s/other_stuff"),
285             last_callback_template_url_->url_ref().DisplayURL());
286   EXPECT_EQ(ASCIIToUTF16("example.com"),
287             last_callback_template_url_->keyword());
288   EXPECT_FALSE(last_callback_template_url_->safe_for_autoreplace());
289 }
290
291 TEST_F(TemplateURLFetcherTest, DuplicateKeywordsTest) {
292   base::string16 keyword(ASCIIToUTF16("test"));
293   TemplateURLData data;
294   data.short_name = keyword;
295   data.SetKeyword(keyword);
296   data.SetURL("http://example.com/");
297   test_util_.model()->Add(new TemplateURL(test_util_.profile(), data));
298   test_util_.ChangeModelToLoadState();
299
300   ASSERT_TRUE(test_util_.model()->GetTemplateURLForKeyword(keyword));
301
302   // This should bail because the keyword already exists.
303   std::string osdd_file_name("simple_open_search.xml");
304   StartDownload(keyword, osdd_file_name,
305                 TemplateURLFetcher::AUTODETECTED_PROVIDER, true);
306   ASSERT_EQ(0, add_provider_called_);
307   ASSERT_EQ(1, callbacks_destroyed_);
308   ASSERT_FALSE(last_callback_template_url_.get());
309 }
310
311 TEST_F(TemplateURLFetcherTest, DuplicateDownloadTest) {
312   base::string16 keyword(ASCIIToUTF16("test"));
313   std::string osdd_file_name("simple_open_search.xml");
314   StartDownload(keyword, osdd_file_name,
315                 TemplateURLFetcher::EXPLICIT_PROVIDER, true);
316   ASSERT_EQ(0, add_provider_called_);
317   ASSERT_EQ(0, callbacks_destroyed_);
318
319   // This should bail because the keyword already has a pending download.
320   StartDownload(keyword, osdd_file_name,
321                 TemplateURLFetcher::EXPLICIT_PROVIDER, true);
322   ASSERT_EQ(0, add_provider_called_);
323   ASSERT_EQ(1, callbacks_destroyed_);
324
325   WaitForDownloadToFinish();
326   ASSERT_EQ(1, add_provider_called_);
327   ASSERT_EQ(2, callbacks_destroyed_);
328   ASSERT_TRUE(last_callback_template_url_.get());
329 }