- add sources.
[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 class TemplateURLFetcherTest;
24
25 // Handles callbacks from TemplateURLFetcher.
26 class TemplateURLFetcherTestCallbacks : public TemplateURLFetcherCallbacks {
27  public:
28   explicit TemplateURLFetcherTestCallbacks(TemplateURLFetcherTest* test)
29       : test_(test) {
30   }
31   virtual ~TemplateURLFetcherTestCallbacks();
32
33   // TemplateURLFetcherCallbacks implementation.
34   virtual void ConfirmAddSearchProvider(TemplateURL* template_url,
35                                         Profile* profile) OVERRIDE;
36
37  private:
38   TemplateURLFetcherTest* test_;
39
40   DISALLOW_COPY_AND_ASSIGN(TemplateURLFetcherTestCallbacks);
41 };
42
43 // Basic set-up for TemplateURLFetcher tests.
44 class TemplateURLFetcherTest : public testing::Test {
45  public:
46   TemplateURLFetcherTest();
47
48   virtual void SetUp() OVERRIDE {
49     test_util_.SetUp();
50     TestingProfile* profile = test_util_.profile();
51     ASSERT_TRUE(profile);
52     ASSERT_TRUE(TemplateURLFetcherFactory::GetForProfile(profile));
53
54     ASSERT_TRUE(profile->GetRequestContext());
55     ASSERT_TRUE(test_server_.InitializeAndWaitUntilReady());
56   }
57
58   virtual void TearDown() OVERRIDE {
59     ASSERT_TRUE(test_server_.ShutdownAndWaitUntilComplete());
60     test_util_.TearDown();
61   }
62
63   // Called by ~TemplateURLFetcherTestCallbacks.
64   void DestroyedCallback(TemplateURLFetcherTestCallbacks* callbacks);
65
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);
69
70  protected:
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);
76
77   // Waits for any downloads to finish.
78   void WaitForDownloadToFinish();
79
80   TemplateURLServiceTestUtil test_util_;
81   net::test_server::EmbeddedTestServer test_server_;
82
83   // The last TemplateURL to come from a callback.
84   scoped_ptr<TemplateURL> last_callback_template_url_;
85
86   // How many TemplateURLFetcherTestCallbacks have been destructed.
87   int callbacks_destroyed_;
88
89   // How many times ConfirmAddSearchProvider has been called.
90   int add_provider_called_;
91
92   // Is the code in WaitForDownloadToFinish in a message loop waiting for a
93   // callback to finish?
94   bool waiting_for_download_;
95
96  private:
97   DISALLOW_COPY_AND_ASSIGN(TemplateURLFetcherTest);
98 };
99
100 TemplateURLFetcherTestCallbacks::~TemplateURLFetcherTestCallbacks() {
101   test_->DestroyedCallback(this);
102 }
103
104 void TemplateURLFetcherTestCallbacks::ConfirmAddSearchProvider(
105     TemplateURL* template_url,
106     Profile* profile) {
107   test_->ConfirmAddSearchProvider(template_url, profile);
108 }
109
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"));
118 }
119
120 void TemplateURLFetcherTest::DestroyedCallback(
121     TemplateURLFetcherTestCallbacks* callbacks) {
122   callbacks_destroyed_++;
123   if (waiting_for_download_)
124     base::MessageLoop::current()->Quit();
125 }
126
127 void TemplateURLFetcherTest::ConfirmAddSearchProvider(
128     TemplateURL* template_url,
129     Profile* profile) {
130   last_callback_template_url_.reset(template_url);
131   add_provider_called_++;
132 }
133
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) {
139
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));
146   }
147
148   // Start the fetch.
149   GURL osdd_url = test_server_.GetURL("/" + osdd_file_name);
150   GURL favicon_url;
151   TemplateURLFetcherFactory::GetForProfile(
152       test_util_.profile())->ScheduleDownload(
153           keyword, osdd_url, favicon_url, NULL,
154           new TemplateURLFetcherTestCallbacks(this), provider_type);
155 }
156
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;
162 }
163
164 TEST_F(TemplateURLFetcherTest, BasicAutodetectedTest) {
165   string16 keyword(ASCIIToUTF16("test"));
166
167   test_util_.ChangeModelToLoadState();
168   ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
169
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_);
175
176   WaitForDownloadToFinish();
177   ASSERT_EQ(0, add_provider_called_);
178   ASSERT_EQ(1, callbacks_destroyed_);
179
180   const TemplateURL* t_url = test_util_.model()->GetTemplateURLForKeyword(
181       keyword);
182   ASSERT_TRUE(t_url);
183   EXPECT_EQ(ASCIIToUTF16("http://example.com/%s/other_stuff"),
184             t_url->url_ref().DisplayURL());
185   EXPECT_TRUE(t_url->safe_for_autoreplace());
186 }
187
188 TEST_F(TemplateURLFetcherTest, DuplicatesThrownAway) {
189   string16 keyword(ASCIIToUTF16("test"));
190
191   test_util_.ChangeModelToLoadState();
192   ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
193
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_);
199
200   struct {
201     std::string description;
202     std::string osdd_file_name;
203     string16 keyword;
204     TemplateURLFetcher::ProviderType provider_type;
205   } test_cases[] = {
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 },
213   };
214
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);
218     ASSERT_EQ(
219         1,
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_));
224   }
225
226   WaitForDownloadToFinish();
227   ASSERT_EQ(1 + ARRAYSIZE_UNSAFE(test_cases),
228             static_cast<size_t>(callbacks_destroyed_));
229   ASSERT_EQ(0, add_provider_called_);
230 }
231
232 TEST_F(TemplateURLFetcherTest, BasicExplicitTest) {
233   string16 keyword(ASCIIToUTF16("test"));
234
235   test_util_.ChangeModelToLoadState();
236   ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
237
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_);
243
244   WaitForDownloadToFinish();
245   ASSERT_EQ(1, add_provider_called_);
246   ASSERT_EQ(1, callbacks_destroyed_);
247
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());
254 }
255
256 TEST_F(TemplateURLFetcherTest, AutodetectedBeforeLoadTest) {
257   string16 keyword(ASCIIToUTF16("test"));
258   ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
259
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_);
265 }
266
267 TEST_F(TemplateURLFetcherTest, ExplicitBeforeLoadTest) {
268   string16 keyword(ASCIIToUTF16("test"));
269   ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
270
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_);
276
277   WaitForDownloadToFinish();
278   ASSERT_EQ(1, add_provider_called_);
279   ASSERT_EQ(1, callbacks_destroyed_);
280
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());
287 }
288
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();
297
298   ASSERT_TRUE(test_util_.model()->GetTemplateURLForKeyword(keyword));
299
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());
307 }
308
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_);
316
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_);
322
323   WaitForDownloadToFinish();
324   ASSERT_EQ(1, add_provider_called_);
325   ASSERT_EQ(2, callbacks_destroyed_);
326   ASSERT_TRUE(last_callback_template_url_.get());
327 }