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/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 "net/test/embedded_test_server/embedded_test_server.h"
19 #include "testing/gtest/include/gtest/gtest.h"
22 using base::ASCIIToUTF16
;
24 class TemplateURLFetcherTest
;
26 // Handles callbacks from TemplateURLFetcher.
27 class TemplateURLFetcherTestCallbacks
: public TemplateURLFetcherCallbacks
{
29 explicit TemplateURLFetcherTestCallbacks(TemplateURLFetcherTest
* test
)
32 virtual ~TemplateURLFetcherTestCallbacks();
34 // TemplateURLFetcherCallbacks implementation.
35 virtual void ConfirmAddSearchProvider(TemplateURL
* template_url
,
36 Profile
* profile
) OVERRIDE
;
39 TemplateURLFetcherTest
* test_
;
41 DISALLOW_COPY_AND_ASSIGN(TemplateURLFetcherTestCallbacks
);
44 // Basic set-up for TemplateURLFetcher tests.
45 class TemplateURLFetcherTest
: public testing::Test
{
47 TemplateURLFetcherTest();
49 virtual void SetUp() OVERRIDE
{
51 TestingProfile
* profile
= test_util_
.profile();
53 ASSERT_TRUE(TemplateURLFetcherFactory::GetForProfile(profile
));
55 ASSERT_TRUE(profile
->GetRequestContext());
56 ASSERT_TRUE(test_server_
.InitializeAndWaitUntilReady());
59 virtual void TearDown() OVERRIDE
{
60 ASSERT_TRUE(test_server_
.ShutdownAndWaitUntilComplete());
61 test_util_
.TearDown();
64 // Called by ~TemplateURLFetcherTestCallbacks.
65 void DestroyedCallback(TemplateURLFetcherTestCallbacks
* callbacks
);
67 // TemplateURLFetcherCallbacks implementation. (Although not derived from
68 // this class, this method handles those calls for the test.)
69 void ConfirmAddSearchProvider(TemplateURL
* template_url
, Profile
* profile
);
72 // Schedules the download of the url.
73 void StartDownload(const base::string16
& keyword
,
74 const std::string
& osdd_file_name
,
75 TemplateURLFetcher::ProviderType provider_type
,
76 bool check_that_file_exists
);
78 // Waits for any downloads to finish.
79 void WaitForDownloadToFinish();
81 TemplateURLServiceTestUtil test_util_
;
82 net::test_server::EmbeddedTestServer test_server_
;
84 // The last TemplateURL to come from a callback.
85 scoped_ptr
<TemplateURL
> last_callback_template_url_
;
87 // How many TemplateURLFetcherTestCallbacks have been destructed.
88 int callbacks_destroyed_
;
90 // How many times ConfirmAddSearchProvider has been called.
91 int add_provider_called_
;
93 // Is the code in WaitForDownloadToFinish in a message loop waiting for a
94 // callback to finish?
95 bool waiting_for_download_
;
98 DISALLOW_COPY_AND_ASSIGN(TemplateURLFetcherTest
);
101 TemplateURLFetcherTestCallbacks::~TemplateURLFetcherTestCallbacks() {
102 test_
->DestroyedCallback(this);
105 void TemplateURLFetcherTestCallbacks::ConfirmAddSearchProvider(
106 TemplateURL
* template_url
,
108 test_
->ConfirmAddSearchProvider(template_url
, profile
);
111 TemplateURLFetcherTest::TemplateURLFetcherTest()
112 : callbacks_destroyed_(0),
113 add_provider_called_(0),
114 waiting_for_download_(false) {
115 base::FilePath src_dir
;
116 CHECK(PathService::Get(base::DIR_SOURCE_ROOT
, &src_dir
));
117 test_server_
.ServeFilesFromDirectory(
118 src_dir
.AppendASCII("chrome/test/data"));
121 void TemplateURLFetcherTest::DestroyedCallback(
122 TemplateURLFetcherTestCallbacks
* callbacks
) {
123 callbacks_destroyed_
++;
124 if (waiting_for_download_
)
125 base::MessageLoop::current()->Quit();
128 void TemplateURLFetcherTest::ConfirmAddSearchProvider(
129 TemplateURL
* template_url
,
131 last_callback_template_url_
.reset(template_url
);
132 add_provider_called_
++;
135 void TemplateURLFetcherTest::StartDownload(
136 const base::string16
& keyword
,
137 const std::string
& osdd_file_name
,
138 TemplateURLFetcher::ProviderType provider_type
,
139 bool check_that_file_exists
) {
141 if (check_that_file_exists
) {
142 base::FilePath osdd_full_path
;
143 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA
, &osdd_full_path
));
144 osdd_full_path
= osdd_full_path
.AppendASCII(osdd_file_name
);
145 ASSERT_TRUE(base::PathExists(osdd_full_path
));
146 ASSERT_FALSE(base::DirectoryExists(osdd_full_path
));
150 GURL osdd_url
= test_server_
.GetURL("/" + osdd_file_name
);
152 TemplateURLFetcherFactory::GetForProfile(
153 test_util_
.profile())->ScheduleDownload(
154 keyword
, osdd_url
, favicon_url
, NULL
,
155 new TemplateURLFetcherTestCallbacks(this), provider_type
);
158 void TemplateURLFetcherTest::WaitForDownloadToFinish() {
159 ASSERT_FALSE(waiting_for_download_
);
160 waiting_for_download_
= true;
161 base::MessageLoop::current()->Run();
162 waiting_for_download_
= false;
165 TEST_F(TemplateURLFetcherTest
, BasicAutodetectedTest
) {
166 base::string16
keyword(ASCIIToUTF16("test"));
168 test_util_
.ChangeModelToLoadState();
169 ASSERT_FALSE(test_util_
.model()->GetTemplateURLForKeyword(keyword
));
171 std::string
osdd_file_name("simple_open_search.xml");
172 StartDownload(keyword
, osdd_file_name
,
173 TemplateURLFetcher::AUTODETECTED_PROVIDER
, true);
174 ASSERT_EQ(0, add_provider_called_
);
175 ASSERT_EQ(0, callbacks_destroyed_
);
177 WaitForDownloadToFinish();
178 ASSERT_EQ(0, add_provider_called_
);
179 ASSERT_EQ(1, callbacks_destroyed_
);
181 const TemplateURL
* t_url
= test_util_
.model()->GetTemplateURLForKeyword(
184 EXPECT_EQ(ASCIIToUTF16("http://example.com/%s/other_stuff"),
185 t_url
->url_ref().DisplayURL());
186 EXPECT_TRUE(t_url
->safe_for_autoreplace());
189 TEST_F(TemplateURLFetcherTest
, DuplicatesThrownAway
) {
190 base::string16
keyword(ASCIIToUTF16("test"));
192 test_util_
.ChangeModelToLoadState();
193 ASSERT_FALSE(test_util_
.model()->GetTemplateURLForKeyword(keyword
));
195 std::string
osdd_file_name("simple_open_search.xml");
196 StartDownload(keyword
, osdd_file_name
,
197 TemplateURLFetcher::AUTODETECTED_PROVIDER
, true);
198 ASSERT_EQ(0, add_provider_called_
);
199 ASSERT_EQ(0, callbacks_destroyed_
);
202 std::string description
;
203 std::string osdd_file_name
;
204 base::string16 keyword
;
205 TemplateURLFetcher::ProviderType provider_type
;
207 { "Duplicate osdd url with autodetected provider.", osdd_file_name
,
208 keyword
+ ASCIIToUTF16("1"),
209 TemplateURLFetcher::AUTODETECTED_PROVIDER
},
210 { "Duplicate keyword with autodetected provider.", osdd_file_name
+ "1",
211 keyword
, TemplateURLFetcher::AUTODETECTED_PROVIDER
},
212 { "Duplicate osdd url with explicit provider.", osdd_file_name
,
213 base::string16(), TemplateURLFetcher::EXPLICIT_PROVIDER
},
216 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(test_cases
); ++i
) {
217 StartDownload(test_cases
[i
].keyword
, test_cases
[i
].osdd_file_name
,
218 test_cases
[i
].provider_type
, false);
221 TemplateURLFetcherFactory::GetForProfile(
222 test_util_
.profile())->requests_count()) <<
223 test_cases
[i
].description
;
224 ASSERT_EQ(i
+ 1, static_cast<size_t>(callbacks_destroyed_
));
227 WaitForDownloadToFinish();
228 ASSERT_EQ(1 + ARRAYSIZE_UNSAFE(test_cases
),
229 static_cast<size_t>(callbacks_destroyed_
));
230 ASSERT_EQ(0, add_provider_called_
);
233 TEST_F(TemplateURLFetcherTest
, BasicExplicitTest
) {
234 base::string16
keyword(ASCIIToUTF16("test"));
236 test_util_
.ChangeModelToLoadState();
237 ASSERT_FALSE(test_util_
.model()->GetTemplateURLForKeyword(keyword
));
239 std::string
osdd_file_name("simple_open_search.xml");
240 StartDownload(keyword
, osdd_file_name
,
241 TemplateURLFetcher::EXPLICIT_PROVIDER
, true);
242 ASSERT_EQ(0, add_provider_called_
);
243 ASSERT_EQ(0, callbacks_destroyed_
);
245 WaitForDownloadToFinish();
246 ASSERT_EQ(1, add_provider_called_
);
247 ASSERT_EQ(1, callbacks_destroyed_
);
249 ASSERT_TRUE(last_callback_template_url_
.get());
250 EXPECT_EQ(ASCIIToUTF16("http://example.com/%s/other_stuff"),
251 last_callback_template_url_
->url_ref().DisplayURL());
252 EXPECT_EQ(ASCIIToUTF16("example.com"),
253 last_callback_template_url_
->keyword());
254 EXPECT_FALSE(last_callback_template_url_
->safe_for_autoreplace());
257 TEST_F(TemplateURLFetcherTest
, AutodetectedBeforeLoadTest
) {
258 base::string16
keyword(ASCIIToUTF16("test"));
259 ASSERT_FALSE(test_util_
.model()->GetTemplateURLForKeyword(keyword
));
261 std::string
osdd_file_name("simple_open_search.xml");
262 StartDownload(keyword
, osdd_file_name
,
263 TemplateURLFetcher::AUTODETECTED_PROVIDER
, true);
264 ASSERT_EQ(0, add_provider_called_
);
265 ASSERT_EQ(1, callbacks_destroyed_
);
268 TEST_F(TemplateURLFetcherTest
, ExplicitBeforeLoadTest
) {
269 base::string16
keyword(ASCIIToUTF16("test"));
270 ASSERT_FALSE(test_util_
.model()->GetTemplateURLForKeyword(keyword
));
272 std::string
osdd_file_name("simple_open_search.xml");
273 StartDownload(keyword
, osdd_file_name
,
274 TemplateURLFetcher::EXPLICIT_PROVIDER
, true);
275 ASSERT_EQ(0, add_provider_called_
);
276 ASSERT_EQ(0, callbacks_destroyed_
);
278 WaitForDownloadToFinish();
279 ASSERT_EQ(1, add_provider_called_
);
280 ASSERT_EQ(1, callbacks_destroyed_
);
282 ASSERT_TRUE(last_callback_template_url_
.get());
283 EXPECT_EQ(ASCIIToUTF16("http://example.com/%s/other_stuff"),
284 last_callback_template_url_
->url_ref().DisplayURL());
285 EXPECT_EQ(ASCIIToUTF16("example.com"),
286 last_callback_template_url_
->keyword());
287 EXPECT_FALSE(last_callback_template_url_
->safe_for_autoreplace());
290 TEST_F(TemplateURLFetcherTest
, DuplicateKeywordsTest
) {
291 base::string16
keyword(ASCIIToUTF16("test"));
292 TemplateURLData data
;
293 data
.short_name
= keyword
;
294 data
.SetKeyword(keyword
);
295 data
.SetURL("http://example.com/");
296 test_util_
.model()->Add(new TemplateURL(test_util_
.profile(), data
));
297 test_util_
.ChangeModelToLoadState();
299 ASSERT_TRUE(test_util_
.model()->GetTemplateURLForKeyword(keyword
));
301 // This should bail because the keyword already exists.
302 std::string
osdd_file_name("simple_open_search.xml");
303 StartDownload(keyword
, osdd_file_name
,
304 TemplateURLFetcher::AUTODETECTED_PROVIDER
, true);
305 ASSERT_EQ(0, add_provider_called_
);
306 ASSERT_EQ(1, callbacks_destroyed_
);
307 ASSERT_FALSE(last_callback_template_url_
.get());
310 TEST_F(TemplateURLFetcherTest
, DuplicateDownloadTest
) {
311 base::string16
keyword(ASCIIToUTF16("test"));
312 std::string
osdd_file_name("simple_open_search.xml");
313 StartDownload(keyword
, osdd_file_name
,
314 TemplateURLFetcher::EXPLICIT_PROVIDER
, true);
315 ASSERT_EQ(0, add_provider_called_
);
316 ASSERT_EQ(0, callbacks_destroyed_
);
318 // This should bail because the keyword already has a pending download.
319 StartDownload(keyword
, osdd_file_name
,
320 TemplateURLFetcher::EXPLICIT_PROVIDER
, true);
321 ASSERT_EQ(0, add_provider_called_
);
322 ASSERT_EQ(1, callbacks_destroyed_
);
324 WaitForDownloadToFinish();
325 ASSERT_EQ(1, add_provider_called_
);
326 ASSERT_EQ(2, callbacks_destroyed_
);
327 ASSERT_TRUE(last_callback_template_url_
.get());