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/callback_helpers.h"
6 #include "base/file_util.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/path_service.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/search_engines/template_url_service_test_util.h"
12 #include "chrome/common/chrome_paths.h"
13 #include "chrome/test/base/testing_profile.h"
14 #include "components/search_engines/template_url.h"
15 #include "components/search_engines/template_url_fetcher.h"
16 #include "components/search_engines/template_url_service.h"
17 #include "net/test/embedded_test_server/embedded_test_server.h"
18 #include "testing/gtest/include/gtest/gtest.h"
21 using base::ASCIIToUTF16;
23 // Basic set-up for TemplateURLFetcher tests.
24 class TemplateURLFetcherTest : public testing::Test {
26 TemplateURLFetcherTest();
28 virtual void SetUp() OVERRIDE {
29 TestingProfile* profile = test_util_.profile();
30 ASSERT_TRUE(profile->GetRequestContext());
31 template_url_fetcher_.reset(new TemplateURLFetcher(
32 test_util_.model(), profile->GetRequestContext()));
34 ASSERT_TRUE(test_server_.InitializeAndWaitUntilReady());
37 virtual void TearDown() OVERRIDE {
38 ASSERT_TRUE(test_server_.ShutdownAndWaitUntilComplete());
41 // Called when the callback is destroyed.
42 void DestroyedCallback();
44 // TemplateURLFetcherCallbacks implementation. (Although not derived from
45 // this class, this method handles those calls for the test.)
46 void ConfirmAddSearchProvider(
47 base::ScopedClosureRunner* callback_destruction_notifier,
48 scoped_ptr<TemplateURL> template_url);
51 // Schedules the download of the url.
52 void StartDownload(const base::string16& keyword,
53 const std::string& osdd_file_name,
54 TemplateURLFetcher::ProviderType provider_type,
55 bool check_that_file_exists);
57 // Waits for any downloads to finish.
58 void WaitForDownloadToFinish();
60 TemplateURLServiceTestUtil test_util_;
61 scoped_ptr<TemplateURLFetcher> template_url_fetcher_;
62 net::test_server::EmbeddedTestServer test_server_;
64 // The last TemplateURL to come from a callback.
65 scoped_ptr<TemplateURL> last_callback_template_url_;
67 // How many TemplateURLFetcherTestCallbacks have been destructed.
68 int callbacks_destroyed_;
70 // How many times ConfirmAddSearchProvider has been called.
71 int add_provider_called_;
73 // Is the code in WaitForDownloadToFinish in a message loop waiting for a
74 // callback to finish?
75 bool waiting_for_download_;
78 DISALLOW_COPY_AND_ASSIGN(TemplateURLFetcherTest);
81 TemplateURLFetcherTest::TemplateURLFetcherTest()
82 : callbacks_destroyed_(0),
83 add_provider_called_(0),
84 waiting_for_download_(false) {
85 base::FilePath src_dir;
86 CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &src_dir));
87 test_server_.ServeFilesFromDirectory(
88 src_dir.AppendASCII("chrome/test/data"));
91 void TemplateURLFetcherTest::DestroyedCallback() {
92 callbacks_destroyed_++;
93 if (waiting_for_download_)
94 base::MessageLoop::current()->Quit();
97 void TemplateURLFetcherTest::ConfirmAddSearchProvider(
98 base::ScopedClosureRunner* callback_destruction_notifier,
99 scoped_ptr<TemplateURL> template_url) {
100 last_callback_template_url_ = template_url.Pass();
101 add_provider_called_++;
104 void TemplateURLFetcherTest::StartDownload(
105 const base::string16& keyword,
106 const std::string& osdd_file_name,
107 TemplateURLFetcher::ProviderType provider_type,
108 bool check_that_file_exists) {
110 if (check_that_file_exists) {
111 base::FilePath osdd_full_path;
112 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &osdd_full_path));
113 osdd_full_path = osdd_full_path.AppendASCII(osdd_file_name);
114 ASSERT_TRUE(base::PathExists(osdd_full_path));
115 ASSERT_FALSE(base::DirectoryExists(osdd_full_path));
119 GURL osdd_url = test_server_.GetURL("/" + osdd_file_name);
121 base::ScopedClosureRunner* callback_destruction_notifier =
122 new base::ScopedClosureRunner(
123 base::Bind(&TemplateURLFetcherTest::DestroyedCallback,
124 base::Unretained(this)));
126 template_url_fetcher_->ScheduleDownload(
127 keyword, osdd_url, favicon_url,
128 TemplateURLFetcher::URLFetcherCustomizeCallback(),
129 base::Bind(&TemplateURLFetcherTest::ConfirmAddSearchProvider,
130 base::Unretained(this),
131 base::Owned(callback_destruction_notifier)),
135 void TemplateURLFetcherTest::WaitForDownloadToFinish() {
136 ASSERT_FALSE(waiting_for_download_);
137 waiting_for_download_ = true;
138 base::MessageLoop::current()->Run();
139 waiting_for_download_ = false;
142 TEST_F(TemplateURLFetcherTest, BasicAutodetectedTest) {
143 base::string16 keyword(ASCIIToUTF16("test"));
145 test_util_.ChangeModelToLoadState();
146 ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
148 std::string osdd_file_name("simple_open_search.xml");
149 StartDownload(keyword, osdd_file_name,
150 TemplateURLFetcher::AUTODETECTED_PROVIDER, true);
151 ASSERT_EQ(0, add_provider_called_);
152 ASSERT_EQ(0, callbacks_destroyed_);
154 WaitForDownloadToFinish();
155 ASSERT_EQ(0, add_provider_called_);
156 ASSERT_EQ(1, callbacks_destroyed_);
158 const TemplateURL* t_url = test_util_.model()->GetTemplateURLForKeyword(
161 EXPECT_EQ(ASCIIToUTF16("http://example.com/%s/other_stuff"),
162 t_url->url_ref().DisplayURL(
163 test_util_.model()->search_terms_data()));
164 EXPECT_TRUE(t_url->safe_for_autoreplace());
167 TEST_F(TemplateURLFetcherTest, DuplicatesThrownAway) {
168 base::string16 keyword(ASCIIToUTF16("test"));
170 test_util_.ChangeModelToLoadState();
171 ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
173 std::string osdd_file_name("simple_open_search.xml");
174 StartDownload(keyword, osdd_file_name,
175 TemplateURLFetcher::AUTODETECTED_PROVIDER, true);
176 ASSERT_EQ(0, add_provider_called_);
177 ASSERT_EQ(0, callbacks_destroyed_);
180 std::string description;
181 std::string osdd_file_name;
182 base::string16 keyword;
183 TemplateURLFetcher::ProviderType provider_type;
185 { "Duplicate osdd url with autodetected provider.", osdd_file_name,
186 keyword + ASCIIToUTF16("1"),
187 TemplateURLFetcher::AUTODETECTED_PROVIDER },
188 { "Duplicate keyword with autodetected provider.", osdd_file_name + "1",
189 keyword, TemplateURLFetcher::AUTODETECTED_PROVIDER },
190 { "Duplicate osdd url with explicit provider.", osdd_file_name,
191 base::string16(), TemplateURLFetcher::EXPLICIT_PROVIDER },
194 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
195 StartDownload(test_cases[i].keyword, test_cases[i].osdd_file_name,
196 test_cases[i].provider_type, false);
197 ASSERT_EQ(1, template_url_fetcher_->requests_count())
198 << test_cases[i].description;
199 ASSERT_EQ(i + 1, static_cast<size_t>(callbacks_destroyed_));
202 WaitForDownloadToFinish();
203 ASSERT_EQ(1 + ARRAYSIZE_UNSAFE(test_cases),
204 static_cast<size_t>(callbacks_destroyed_));
205 ASSERT_EQ(0, add_provider_called_);
208 TEST_F(TemplateURLFetcherTest, BasicExplicitTest) {
209 base::string16 keyword(ASCIIToUTF16("test"));
211 test_util_.ChangeModelToLoadState();
212 ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
214 std::string osdd_file_name("simple_open_search.xml");
215 StartDownload(keyword, osdd_file_name,
216 TemplateURLFetcher::EXPLICIT_PROVIDER, true);
217 ASSERT_EQ(0, add_provider_called_);
218 ASSERT_EQ(0, callbacks_destroyed_);
220 WaitForDownloadToFinish();
221 ASSERT_EQ(1, add_provider_called_);
222 ASSERT_EQ(1, callbacks_destroyed_);
224 ASSERT_TRUE(last_callback_template_url_.get());
225 EXPECT_EQ(ASCIIToUTF16("http://example.com/%s/other_stuff"),
226 last_callback_template_url_->url_ref().DisplayURL(
227 test_util_.model()->search_terms_data()));
228 EXPECT_EQ(ASCIIToUTF16("example.com"),
229 last_callback_template_url_->keyword());
230 EXPECT_FALSE(last_callback_template_url_->safe_for_autoreplace());
233 TEST_F(TemplateURLFetcherTest, AutodetectedBeforeLoadTest) {
234 base::string16 keyword(ASCIIToUTF16("test"));
235 ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
237 std::string osdd_file_name("simple_open_search.xml");
238 StartDownload(keyword, osdd_file_name,
239 TemplateURLFetcher::AUTODETECTED_PROVIDER, true);
240 ASSERT_EQ(0, add_provider_called_);
241 ASSERT_EQ(1, callbacks_destroyed_);
244 TEST_F(TemplateURLFetcherTest, ExplicitBeforeLoadTest) {
245 base::string16 keyword(ASCIIToUTF16("test"));
246 ASSERT_FALSE(test_util_.model()->GetTemplateURLForKeyword(keyword));
248 std::string osdd_file_name("simple_open_search.xml");
249 StartDownload(keyword, osdd_file_name,
250 TemplateURLFetcher::EXPLICIT_PROVIDER, true);
251 ASSERT_EQ(0, add_provider_called_);
252 ASSERT_EQ(0, callbacks_destroyed_);
254 WaitForDownloadToFinish();
255 ASSERT_EQ(1, add_provider_called_);
256 ASSERT_EQ(1, callbacks_destroyed_);
258 ASSERT_TRUE(last_callback_template_url_.get());
259 EXPECT_EQ(ASCIIToUTF16("http://example.com/%s/other_stuff"),
260 last_callback_template_url_->url_ref().DisplayURL(
261 test_util_.model()->search_terms_data()));
262 EXPECT_EQ(ASCIIToUTF16("example.com"),
263 last_callback_template_url_->keyword());
264 EXPECT_FALSE(last_callback_template_url_->safe_for_autoreplace());
267 TEST_F(TemplateURLFetcherTest, DuplicateKeywordsTest) {
268 base::string16 keyword(ASCIIToUTF16("test"));
269 TemplateURLData data;
270 data.short_name = keyword;
271 data.SetKeyword(keyword);
272 data.SetURL("http://example.com/");
273 test_util_.model()->Add(new TemplateURL(data));
274 test_util_.ChangeModelToLoadState();
276 ASSERT_TRUE(test_util_.model()->GetTemplateURLForKeyword(keyword));
278 // This should bail because the keyword already exists.
279 std::string osdd_file_name("simple_open_search.xml");
280 StartDownload(keyword, osdd_file_name,
281 TemplateURLFetcher::AUTODETECTED_PROVIDER, true);
282 ASSERT_EQ(0, add_provider_called_);
283 ASSERT_EQ(1, callbacks_destroyed_);
284 ASSERT_FALSE(last_callback_template_url_.get());
287 TEST_F(TemplateURLFetcherTest, DuplicateDownloadTest) {
288 base::string16 keyword(ASCIIToUTF16("test"));
289 std::string osdd_file_name("simple_open_search.xml");
290 StartDownload(keyword, osdd_file_name,
291 TemplateURLFetcher::EXPLICIT_PROVIDER, true);
292 ASSERT_EQ(0, add_provider_called_);
293 ASSERT_EQ(0, callbacks_destroyed_);
295 // This should bail because the keyword already has a pending download.
296 StartDownload(keyword, osdd_file_name,
297 TemplateURLFetcher::EXPLICIT_PROVIDER, true);
298 ASSERT_EQ(0, add_provider_called_);
299 ASSERT_EQ(1, callbacks_destroyed_);
301 WaitForDownloadToFinish();
302 ASSERT_EQ(1, add_provider_called_);
303 ASSERT_EQ(2, callbacks_destroyed_);
304 ASSERT_TRUE(last_callback_template_url_.get());