OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/files/file_path.h" | 5 #include "base/files/file_path.h" |
6 #include "base/files/scoped_temp_dir.h" | 6 #include "base/files/scoped_temp_dir.h" |
7 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
8 #include "base/observer_list.h" | 8 #include "base/observer_list.h" |
9 #include "base/prefs/pref_service.h" | 9 #include "base/prefs/pref_service.h" |
10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
12 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
13 #include "base/value_conversions.h" | 13 #include "base/value_conversions.h" |
14 #include "chrome/browser/download/chrome_download_manager_delegate.h" | 14 #include "chrome/browser/download/chrome_download_manager_delegate.h" |
15 #include "chrome/browser/download/download_extensions.h" | 15 #include "chrome/browser/download/download_extensions.h" |
16 #include "chrome/browser/download/download_prefs.h" | 16 #include "chrome/browser/download/download_prefs.h" |
17 #include "chrome/browser/download/download_target_determiner.h" | 17 #include "chrome/browser/download/download_target_determiner.h" |
| 18 #include "chrome/browser/download/download_target_info.h" |
18 #include "chrome/browser/history/history_service.h" | 19 #include "chrome/browser/history/history_service.h" |
19 #include "chrome/browser/history/history_service_factory.h" | 20 #include "chrome/browser/history/history_service_factory.h" |
20 #include "chrome/browser/history/history_types.h" | 21 #include "chrome/browser/history/history_types.h" |
21 #include "chrome/common/extensions/extension.h" | 22 #include "chrome/common/extensions/extension.h" |
22 #include "chrome/common/pref_names.h" | 23 #include "chrome/common/pref_names.h" |
23 #include "chrome/test/base/chrome_render_view_host_test_harness.h" | 24 #include "chrome/test/base/chrome_render_view_host_test_harness.h" |
24 #include "chrome/test/base/testing_pref_service_syncable.h" | 25 #include "chrome/test/base/testing_pref_service_syncable.h" |
25 #include "chrome/test/base/testing_profile.h" | 26 #include "chrome/test/base/testing_profile.h" |
26 #include "content/public/browser/download_interrupt_reasons.h" | 27 #include "content/public/browser/download_interrupt_reasons.h" |
27 #include "content/public/browser/web_contents.h" | 28 #include "content/public/browser/web_contents.h" |
28 #include "content/public/browser/web_contents_delegate.h" | 29 #include "content/public/browser/web_contents_delegate.h" |
29 #include "content/public/test/mock_download_item.h" | 30 #include "content/public/test/mock_download_item.h" |
30 #include "content/public/test/test_browser_thread.h" | 31 #include "content/public/test/test_browser_thread.h" |
31 #include "content/public/test/test_renderer_host.h" | 32 #include "content/public/test/test_renderer_host.h" |
32 #include "content/public/test/web_contents_tester.h" | 33 #include "content/public/test/web_contents_tester.h" |
| 34 #include "net/base/mime_util.h" |
33 #include "testing/gmock/include/gmock/gmock.h" | 35 #include "testing/gmock/include/gmock/gmock.h" |
34 #include "testing/gtest/include/gtest/gtest.h" | 36 #include "testing/gtest/include/gtest/gtest.h" |
35 | 37 |
| 38 #if defined(ENABLE_PLUGINS) |
| 39 #include "chrome/browser/plugins/plugin_prefs.h" |
| 40 #include "content/public/browser/plugin_service.h" |
| 41 #include "content/public/common/webplugininfo.h" |
| 42 #endif |
| 43 |
36 using ::testing::AnyNumber; | 44 using ::testing::AnyNumber; |
37 using ::testing::Invoke; | 45 using ::testing::Invoke; |
38 using ::testing::Ref; | 46 using ::testing::Ref; |
39 using ::testing::Return; | 47 using ::testing::Return; |
40 using ::testing::ReturnRef; | 48 using ::testing::ReturnRef; |
41 using ::testing::ReturnRefOfCopy; | 49 using ::testing::ReturnRefOfCopy; |
42 using ::testing::Truly; | 50 using ::testing::Truly; |
43 using ::testing::WithArg; | 51 using ::testing::WithArg; |
44 using ::testing::_; | 52 using ::testing::_; |
45 using content::DownloadItem; | 53 using content::DownloadItem; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 MOCK_METHOD3(PromptUserForDownloadPath, | 144 MOCK_METHOD3(PromptUserForDownloadPath, |
137 void(content::DownloadItem*, const base::FilePath&, | 145 void(content::DownloadItem*, const base::FilePath&, |
138 const FileSelectedCallback&)); | 146 const FileSelectedCallback&)); |
139 MOCK_METHOD3(DetermineLocalPath, | 147 MOCK_METHOD3(DetermineLocalPath, |
140 void(DownloadItem*, const base::FilePath&, | 148 void(DownloadItem*, const base::FilePath&, |
141 const LocalPathCallback&)); | 149 const LocalPathCallback&)); |
142 MOCK_METHOD5(ReserveVirtualPath, | 150 MOCK_METHOD5(ReserveVirtualPath, |
143 void(DownloadItem*, const base::FilePath&, bool, | 151 void(DownloadItem*, const base::FilePath&, bool, |
144 DownloadPathReservationTracker::FilenameConflictAction, | 152 DownloadPathReservationTracker::FilenameConflictAction, |
145 const ReservedPathCallback&)); | 153 const ReservedPathCallback&)); |
| 154 MOCK_METHOD2(GetFileMimeType, |
| 155 void(const base::FilePath&, |
| 156 const GetFileMimeTypeCallback&)); |
146 | 157 |
147 void SetupDefaults() { | 158 void SetupDefaults() { |
148 ON_CALL(*this, CheckDownloadUrl(_, _, _)) | 159 ON_CALL(*this, CheckDownloadUrl(_, _, _)) |
149 .WillByDefault(WithArg<2>( | 160 .WillByDefault(WithArg<2>( |
150 ScheduleCallback(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS))); | 161 ScheduleCallback(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS))); |
151 ON_CALL(*this, NotifyExtensions(_, _, _)) | 162 ON_CALL(*this, NotifyExtensions(_, _, _)) |
152 .WillByDefault(WithArg<2>( | 163 .WillByDefault(WithArg<2>( |
153 ScheduleCallback2(base::FilePath(), | 164 ScheduleCallback2(base::FilePath(), |
154 DownloadPathReservationTracker::UNIQUIFY))); | 165 DownloadPathReservationTracker::UNIQUIFY))); |
155 ON_CALL(*this, ReserveVirtualPath(_, _, _, _, _)) | 166 ON_CALL(*this, ReserveVirtualPath(_, _, _, _, _)) |
156 .WillByDefault(Invoke( | 167 .WillByDefault(Invoke( |
157 &MockDownloadTargetDeterminerDelegate::NullReserveVirtualPath)); | 168 &MockDownloadTargetDeterminerDelegate::NullReserveVirtualPath)); |
158 ON_CALL(*this, PromptUserForDownloadPath(_, _, _)) | 169 ON_CALL(*this, PromptUserForDownloadPath(_, _, _)) |
159 .WillByDefault(Invoke( | 170 .WillByDefault(Invoke( |
160 &MockDownloadTargetDeterminerDelegate::NullPromptUser)); | 171 &MockDownloadTargetDeterminerDelegate::NullPromptUser)); |
161 ON_CALL(*this, DetermineLocalPath(_, _, _)) | 172 ON_CALL(*this, DetermineLocalPath(_, _, _)) |
162 .WillByDefault(Invoke( | 173 .WillByDefault(Invoke( |
163 &MockDownloadTargetDeterminerDelegate::NullDetermineLocalPath)); | 174 &MockDownloadTargetDeterminerDelegate::NullDetermineLocalPath)); |
| 175 ON_CALL(*this, GetFileMimeType(_, _)) |
| 176 .WillByDefault(WithArg<1>( |
| 177 ScheduleCallback(""))); |
164 } | 178 } |
165 private: | 179 private: |
166 static void NullReserveVirtualPath( | 180 static void NullReserveVirtualPath( |
167 DownloadItem* download, | 181 DownloadItem* download, |
168 const base::FilePath& virtual_path, | 182 const base::FilePath& virtual_path, |
169 bool create_directory, | 183 bool create_directory, |
170 DownloadPathReservationTracker::FilenameConflictAction conflict_action, | 184 DownloadPathReservationTracker::FilenameConflictAction conflict_action, |
171 const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback); | 185 const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback); |
172 static void NullPromptUser( | 186 static void NullPromptUser( |
173 DownloadItem* download, const base::FilePath& suggested_path, | 187 DownloadItem* download, const base::FilePath& suggested_path, |
(...skipping 25 matching lines...) Expand all Loading... |
199 | 213 |
200 // Given the relative path |path|, returns the full path under the temporary | 214 // Given the relative path |path|, returns the full path under the temporary |
201 // downloads directory. | 215 // downloads directory. |
202 base::FilePath GetPathInDownloadDir(const base::FilePath::StringType& path); | 216 base::FilePath GetPathInDownloadDir(const base::FilePath::StringType& path); |
203 | 217 |
204 // Run |test_case| using |item|. | 218 // Run |test_case| using |item|. |
205 void RunTestCase(const DownloadTestCase& test_case, | 219 void RunTestCase(const DownloadTestCase& test_case, |
206 const base::FilePath& initial_virtual_path, | 220 const base::FilePath& initial_virtual_path, |
207 content::MockDownloadItem* item); | 221 content::MockDownloadItem* item); |
208 | 222 |
| 223 // Runs |test_case| with |item|. When the DownloadTargetDeterminer is done, |
| 224 // returns the resulting DownloadTargetInfo. |
| 225 scoped_ptr<DownloadTargetInfo> RunDownloadTargetDeterminer( |
| 226 const base::FilePath& initial_virtual_path, |
| 227 content::MockDownloadItem* item); |
| 228 |
209 // Run through |test_case_count| tests in |test_cases|. A new MockDownloadItem | 229 // Run through |test_case_count| tests in |test_cases|. A new MockDownloadItem |
210 // will be created for each test case and destroyed when the test case is | 230 // will be created for each test case and destroyed when the test case is |
211 // complete. | 231 // complete. |
212 void RunTestCasesWithActiveItem(const DownloadTestCase test_cases[], | 232 void RunTestCasesWithActiveItem(const DownloadTestCase test_cases[], |
213 size_t test_case_count); | 233 size_t test_case_count); |
214 | 234 |
215 // Verifies that |target_path|, |disposition|, |expected_danger_type| and | 235 // Verifies that |target_path|, |disposition|, |expected_danger_type| and |
216 // |intermediate_path| matches the expectations of |test_case|. Posts | 236 // |intermediate_path| matches the expectations of |test_case|. Posts |
217 // |closure| to the current message loop when done. | 237 // |closure| to the current message loop when done. |
218 void DownloadTargetVerifier(const base::Closure& closure, | 238 void VerifyDownloadTarget(const DownloadTestCase& test_case, |
219 const DownloadTestCase& test_case, | 239 const DownloadTargetInfo* target_info); |
220 const base::FilePath& local_path, | |
221 DownloadItem::TargetDisposition disposition, | |
222 content::DownloadDangerType danger_type, | |
223 const base::FilePath& intermediate_path); | |
224 | 240 |
225 const base::FilePath& test_download_dir() const { | 241 const base::FilePath& test_download_dir() const { |
226 return test_download_dir_.path(); | 242 return test_download_dir_.path(); |
227 } | 243 } |
228 | 244 |
229 const base::FilePath& test_virtual_dir() const { | 245 const base::FilePath& test_virtual_dir() const { |
230 return test_virtual_dir_; | 246 return test_virtual_dir_; |
231 } | 247 } |
232 | 248 |
233 MockDownloadTargetDeterminerDelegate* delegate() { | 249 MockDownloadTargetDeterminerDelegate* delegate() { |
(...skipping 14 matching lines...) Expand all Loading... |
248 | 264 |
249 void DownloadTargetDeterminerTest::SetUp() { | 265 void DownloadTargetDeterminerTest::SetUp() { |
250 ChromeRenderViewHostTestHarness::SetUp(); | 266 ChromeRenderViewHostTestHarness::SetUp(); |
251 CHECK(profile()); | 267 CHECK(profile()); |
252 download_prefs_.reset(new DownloadPrefs(profile())); | 268 download_prefs_.reset(new DownloadPrefs(profile())); |
253 web_contents()->SetDelegate(&web_contents_delegate_); | 269 web_contents()->SetDelegate(&web_contents_delegate_); |
254 ASSERT_TRUE(test_download_dir_.CreateUniqueTempDir()); | 270 ASSERT_TRUE(test_download_dir_.CreateUniqueTempDir()); |
255 test_virtual_dir_ = test_download_dir().Append(FILE_PATH_LITERAL("virtual")); | 271 test_virtual_dir_ = test_download_dir().Append(FILE_PATH_LITERAL("virtual")); |
256 download_prefs_->SetDownloadPath(test_download_dir()); | 272 download_prefs_->SetDownloadPath(test_download_dir()); |
257 delegate_.SetupDefaults(); | 273 delegate_.SetupDefaults(); |
| 274 #if defined(ENABLE_PLUGINS) |
| 275 content::PluginService::GetInstance()->Init(); |
| 276 content::PluginService::GetInstance()->DisablePluginsDiscoveryForTesting(); |
| 277 #endif |
258 } | 278 } |
259 | 279 |
260 void DownloadTargetDeterminerTest::TearDown() { | 280 void DownloadTargetDeterminerTest::TearDown() { |
261 download_prefs_.reset(); | 281 download_prefs_.reset(); |
262 ChromeRenderViewHostTestHarness::TearDown(); | 282 ChromeRenderViewHostTestHarness::TearDown(); |
263 } | 283 } |
264 | 284 |
265 content::MockDownloadItem* | 285 content::MockDownloadItem* |
266 DownloadTargetDeterminerTest::CreateActiveDownloadItem( | 286 DownloadTargetDeterminerTest::CreateActiveDownloadItem( |
267 int32 id, | 287 int32 id, |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 if (relative_path.empty()) | 363 if (relative_path.empty()) |
344 return base::FilePath(); | 364 return base::FilePath(); |
345 base::FilePath full_path(test_download_dir().Append(relative_path)); | 365 base::FilePath full_path(test_download_dir().Append(relative_path)); |
346 return full_path.NormalizePathSeparators(); | 366 return full_path.NormalizePathSeparators(); |
347 } | 367 } |
348 | 368 |
349 void DownloadTargetDeterminerTest::RunTestCase( | 369 void DownloadTargetDeterminerTest::RunTestCase( |
350 const DownloadTestCase& test_case, | 370 const DownloadTestCase& test_case, |
351 const base::FilePath& initial_virtual_path, | 371 const base::FilePath& initial_virtual_path, |
352 content::MockDownloadItem* item) { | 372 content::MockDownloadItem* item) { |
353 // Kick off the test. | 373 scoped_ptr<DownloadTargetInfo> target_info = |
354 base::WeakPtrFactory<DownloadTargetDeterminerTest> factory(this); | 374 RunDownloadTargetDeterminer(initial_virtual_path, item); |
| 375 VerifyDownloadTarget(test_case, target_info.get()); |
| 376 } |
| 377 |
| 378 void CompletionCallbackWrapper( |
| 379 const base::Closure& closure, |
| 380 scoped_ptr<DownloadTargetInfo>* target_info_receiver, |
| 381 scoped_ptr<DownloadTargetInfo> target_info) { |
| 382 target_info_receiver->swap(target_info); |
| 383 base::MessageLoop::current()->PostTask(FROM_HERE, closure); |
| 384 } |
| 385 |
| 386 scoped_ptr<DownloadTargetInfo> |
| 387 DownloadTargetDeterminerTest::RunDownloadTargetDeterminer( |
| 388 const base::FilePath& initial_virtual_path, |
| 389 content::MockDownloadItem* item) { |
| 390 scoped_ptr<DownloadTargetInfo> target_info; |
355 base::RunLoop run_loop; | 391 base::RunLoop run_loop; |
356 DownloadTargetDeterminer::Start( | 392 DownloadTargetDeterminer::Start( |
357 item, initial_virtual_path, download_prefs_.get(), delegate(), | 393 item, initial_virtual_path, download_prefs_.get(), delegate(), |
358 base::Bind(&DownloadTargetDeterminerTest::DownloadTargetVerifier, | 394 base::Bind(&CompletionCallbackWrapper, |
359 factory.GetWeakPtr(), run_loop.QuitClosure(), test_case)); | 395 run_loop.QuitClosure(), |
| 396 &target_info)); |
360 run_loop.Run(); | 397 run_loop.Run(); |
361 ::testing::Mock::VerifyAndClearExpectations(delegate()); | 398 ::testing::Mock::VerifyAndClearExpectations(delegate()); |
| 399 return target_info.Pass(); |
362 } | 400 } |
363 | 401 |
364 void DownloadTargetDeterminerTest::RunTestCasesWithActiveItem( | 402 void DownloadTargetDeterminerTest::RunTestCasesWithActiveItem( |
365 const DownloadTestCase test_cases[], | 403 const DownloadTestCase test_cases[], |
366 size_t test_case_count) { | 404 size_t test_case_count) { |
367 for (size_t i = 0; i < test_case_count; ++i) { | 405 for (size_t i = 0; i < test_case_count; ++i) { |
368 scoped_ptr<content::MockDownloadItem> item( | 406 scoped_ptr<content::MockDownloadItem> item( |
369 CreateActiveDownloadItem(i, test_cases[i])); | 407 CreateActiveDownloadItem(i, test_cases[i])); |
370 SCOPED_TRACE(testing::Message() << "Running test case " << i); | 408 SCOPED_TRACE(testing::Message() << "Running test case " << i); |
371 RunTestCase(test_cases[i], base::FilePath(), item.get()); | 409 RunTestCase(test_cases[i], base::FilePath(), item.get()); |
372 } | 410 } |
373 } | 411 } |
374 | 412 |
375 void DownloadTargetDeterminerTest::DownloadTargetVerifier( | 413 void DownloadTargetDeterminerTest::VerifyDownloadTarget( |
376 const base::Closure& closure, | |
377 const DownloadTestCase& test_case, | 414 const DownloadTestCase& test_case, |
378 const base::FilePath& local_path, | 415 const DownloadTargetInfo* target_info) { |
379 DownloadItem::TargetDisposition disposition, | |
380 content::DownloadDangerType danger_type, | |
381 const base::FilePath& intermediate_path) { | |
382 base::FilePath expected_local_path( | 416 base::FilePath expected_local_path( |
383 GetPathInDownloadDir(test_case.expected_local_path)); | 417 GetPathInDownloadDir(test_case.expected_local_path)); |
384 EXPECT_EQ(expected_local_path.value(), local_path.value()); | 418 EXPECT_EQ(expected_local_path.value(), target_info->target_path.value()); |
385 EXPECT_EQ(test_case.expected_disposition, disposition); | 419 EXPECT_EQ(test_case.expected_disposition, target_info->target_disposition); |
386 EXPECT_EQ(test_case.expected_danger_type, danger_type); | 420 EXPECT_EQ(test_case.expected_danger_type, target_info->danger_type); |
387 | 421 |
388 switch (test_case.expected_intermediate) { | 422 switch (test_case.expected_intermediate) { |
389 case EXPECT_CRDOWNLOAD: | 423 case EXPECT_CRDOWNLOAD: |
390 EXPECT_EQ(DownloadTargetDeterminer::GetCrDownloadPath(local_path).value(), | 424 EXPECT_EQ(DownloadTargetDeterminer::GetCrDownloadPath( |
391 intermediate_path.value()); | 425 target_info->target_path).value(), |
| 426 target_info->intermediate_path.value()); |
392 break; | 427 break; |
393 | 428 |
394 case EXPECT_UNCONFIRMED: | 429 case EXPECT_UNCONFIRMED: |
395 // The paths (in English) look like: /path/Unconfirmed xxx.crdownload. | 430 // The paths (in English) look like: /path/Unconfirmed xxx.crdownload. |
396 // Of this, we only check that the path is: | 431 // Of this, we only check that the path is: |
397 // 1. Not "/path/target.crdownload", | 432 // 1. Not "/path/target.crdownload", |
398 // 2. Points to the same directory as the target. | 433 // 2. Points to the same directory as the target. |
399 // 3. Has extension ".crdownload". | 434 // 3. Has extension ".crdownload". |
400 // 4. Basename starts with "Unconfirmed ". | 435 // 4. Basename starts with "Unconfirmed ". |
401 EXPECT_NE(DownloadTargetDeterminer::GetCrDownloadPath(expected_local_path) | 436 EXPECT_NE(DownloadTargetDeterminer::GetCrDownloadPath(expected_local_path) |
402 .value(), | 437 .value(), |
403 intermediate_path.value()); | 438 target_info->intermediate_path.value()); |
404 EXPECT_EQ(expected_local_path.DirName().value(), | 439 EXPECT_EQ(expected_local_path.DirName().value(), |
405 intermediate_path.DirName().value()); | 440 target_info->intermediate_path.DirName().value()); |
406 EXPECT_TRUE(intermediate_path.MatchesExtension( | 441 EXPECT_TRUE(target_info->intermediate_path.MatchesExtension( |
407 FILE_PATH_LITERAL(".crdownload"))); | 442 FILE_PATH_LITERAL(".crdownload"))); |
408 EXPECT_EQ(0u, intermediate_path.BaseName().value().find( | 443 EXPECT_EQ(0u, |
409 FILE_PATH_LITERAL("Unconfirmed "))); | 444 target_info->intermediate_path.BaseName().value().find( |
| 445 FILE_PATH_LITERAL("Unconfirmed "))); |
410 break; | 446 break; |
411 | 447 |
412 case EXPECT_LOCAL_PATH: | 448 case EXPECT_LOCAL_PATH: |
413 EXPECT_EQ(expected_local_path.value(), intermediate_path.value()); | 449 EXPECT_EQ(expected_local_path.value(), |
| 450 target_info->intermediate_path.value()); |
414 break; | 451 break; |
415 } | 452 } |
416 base::MessageLoop::current()->PostTask(FROM_HERE, closure); | |
417 } | 453 } |
418 | 454 |
419 // static | 455 // static |
420 void MockDownloadTargetDeterminerDelegate::NullReserveVirtualPath( | 456 void MockDownloadTargetDeterminerDelegate::NullReserveVirtualPath( |
421 DownloadItem* download, | 457 DownloadItem* download, |
422 const base::FilePath& virtual_path, | 458 const base::FilePath& virtual_path, |
423 bool create_directory, | 459 bool create_directory, |
424 DownloadPathReservationTracker::FilenameConflictAction conflict_action, | 460 DownloadPathReservationTracker::FilenameConflictAction conflict_action, |
425 const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback) { | 461 const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback) { |
426 callback.Run(virtual_path, true); | 462 callback.Run(virtual_path, true); |
(...skipping 1270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1697 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _)) | 1733 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _)) |
1698 .Times(test_case.test_type == AUTOMATIC ? 1 : 0); | 1734 .Times(test_case.test_type == AUTOMATIC ? 1 : 0); |
1699 EXPECT_CALL(*delegate(), ReserveVirtualPath(_, expected_path, false, _, _)); | 1735 EXPECT_CALL(*delegate(), ReserveVirtualPath(_, expected_path, false, _, _)); |
1700 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, expected_path, _)); | 1736 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, expected_path, _)); |
1701 EXPECT_CALL(*delegate(), DetermineLocalPath(_, expected_path, _)); | 1737 EXPECT_CALL(*delegate(), DetermineLocalPath(_, expected_path, _)); |
1702 EXPECT_CALL(*delegate(), CheckDownloadUrl(_, expected_path, _)); | 1738 EXPECT_CALL(*delegate(), CheckDownloadUrl(_, expected_path, _)); |
1703 RunTestCase(test_case, GetPathInDownloadDir(kInitialPath), item.get()); | 1739 RunTestCase(test_case, GetPathInDownloadDir(kInitialPath), item.get()); |
1704 } | 1740 } |
1705 } | 1741 } |
1706 | 1742 |
1707 // Used with TargetDeterminer_IntermediateNameForResumed test. Verifies that | |
1708 // |intermediate_path| == |expected_intermediate_path| if the latter is | |
1709 // non-empty. | |
1710 void IntermediatePathVerifier( | |
1711 const base::FilePath& expected_intermediate_path, | |
1712 const content::DownloadTargetCallback& callback, | |
1713 const base::FilePath& target_path, | |
1714 content::DownloadItem::TargetDisposition disposition, | |
1715 content::DownloadDangerType danger_type, | |
1716 const base::FilePath& intermediate_path) { | |
1717 if (!expected_intermediate_path.empty()) | |
1718 EXPECT_EQ(expected_intermediate_path, intermediate_path); | |
1719 callback.Run(target_path, disposition, danger_type, intermediate_path); | |
1720 } | |
1721 | |
1722 // Test intermediate filename generation for resumed downloads. | 1743 // Test intermediate filename generation for resumed downloads. |
1723 TEST_F(DownloadTargetDeterminerTest, | 1744 TEST_F(DownloadTargetDeterminerTest, |
1724 TargetDeterminer_IntermediateNameForResumed) { | 1745 TargetDeterminer_IntermediateNameForResumed) { |
1725 // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital | 1746 // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital |
1726 // path. | 1747 // path. |
1727 const base::FilePath::CharType kInitialPath[] = | 1748 const base::FilePath::CharType kInitialPath[] = |
1728 FILE_PATH_LITERAL("some_path/bar.txt"); | 1749 FILE_PATH_LITERAL("some_path/bar.txt"); |
1729 | 1750 |
1730 struct IntermediateNameTestCase { | 1751 struct IntermediateNameTestCase { |
1731 // General test case settings. | 1752 // General test case settings. |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1848 | 1869 |
1849 ON_CALL(*item.get(), GetLastReason()) | 1870 ON_CALL(*item.get(), GetLastReason()) |
1850 .WillByDefault(Return( | 1871 .WillByDefault(Return( |
1851 content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED)); | 1872 content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED)); |
1852 ON_CALL(*item.get(), GetFullPath()) | 1873 ON_CALL(*item.get(), GetFullPath()) |
1853 .WillByDefault(ReturnRefOfCopy( | 1874 .WillByDefault(ReturnRefOfCopy( |
1854 GetPathInDownloadDir(test_case.initial_intermediate_path))); | 1875 GetPathInDownloadDir(test_case.initial_intermediate_path))); |
1855 ON_CALL(*item.get(), GetDangerType()) | 1876 ON_CALL(*item.get(), GetDangerType()) |
1856 .WillByDefault(Return(test_case.general.expected_danger_type)); | 1877 .WillByDefault(Return(test_case.general.expected_danger_type)); |
1857 | 1878 |
1858 base::WeakPtrFactory<DownloadTargetDeterminerTest> factory(this); | 1879 scoped_ptr<DownloadTargetInfo> target_info = |
1859 base::RunLoop run_loop; | 1880 RunDownloadTargetDeterminer(GetPathInDownloadDir(kInitialPath), |
1860 content::DownloadTargetCallback verifier_callback = | 1881 item.get()); |
1861 base::Bind(&DownloadTargetDeterminerTest::DownloadTargetVerifier, | 1882 VerifyDownloadTarget(test_case.general, target_info.get()); |
1862 factory.GetWeakPtr(), | 1883 base::FilePath expected_intermediate_path = |
1863 run_loop.QuitClosure(), | 1884 GetPathInDownloadDir(test_case.expected_intermediate_path); |
1864 test_case.general); | 1885 if (!expected_intermediate_path.empty()) |
1865 content::DownloadTargetCallback test_callback = | 1886 EXPECT_EQ(expected_intermediate_path, target_info->intermediate_path); |
1866 base::Bind(&IntermediatePathVerifier, | |
1867 GetPathInDownloadDir(test_case.expected_intermediate_path), | |
1868 verifier_callback); | |
1869 DownloadTargetDeterminer::Start(item.get(), | |
1870 GetPathInDownloadDir(kInitialPath), | |
1871 download_prefs(), | |
1872 delegate(), | |
1873 test_callback); | |
1874 run_loop.Run(); | |
1875 ::testing::Mock::VerifyAndClearExpectations(delegate()); | |
1876 } | 1887 } |
1877 } | 1888 } |
1878 | 1889 |
| 1890 // Test MIME type determination based on the target filename. |
| 1891 TEST_F(DownloadTargetDeterminerTest, |
| 1892 TargetDeterminer_MIMETypeDetermination) { |
| 1893 // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital |
| 1894 // path. |
| 1895 const base::FilePath::CharType kInitialPath[] = |
| 1896 FILE_PATH_LITERAL("some_path/bar.txt"); |
| 1897 |
| 1898 struct MIMETypeTestCase { |
| 1899 // General test case settings. |
| 1900 DownloadTestCase general; |
| 1901 |
| 1902 // Expected MIME type for test case. |
| 1903 const char* expected_mime_type; |
| 1904 } kMIMETypeTestCases[] = { |
| 1905 { |
| 1906 { |
| 1907 // 0: |
| 1908 AUTOMATIC, |
| 1909 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 1910 "http://example.com/foo.png", "image/png", |
| 1911 FILE_PATH_LITERAL(""), |
| 1912 |
| 1913 FILE_PATH_LITERAL(""), |
| 1914 FILE_PATH_LITERAL("foo.png"), |
| 1915 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 1916 |
| 1917 EXPECT_CRDOWNLOAD |
| 1918 }, |
| 1919 "image/png" |
| 1920 }, |
| 1921 { |
| 1922 { |
| 1923 // 1: Empty MIME type in response. |
| 1924 AUTOMATIC, |
| 1925 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 1926 "http://example.com/foo.png", "", |
| 1927 FILE_PATH_LITERAL(""), |
| 1928 |
| 1929 FILE_PATH_LITERAL(""), |
| 1930 FILE_PATH_LITERAL("foo.png"), |
| 1931 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 1932 |
| 1933 EXPECT_CRDOWNLOAD |
| 1934 }, |
| 1935 "image/png" |
| 1936 }, |
| 1937 { |
| 1938 { |
| 1939 // 2: Forced path. |
| 1940 FORCED, |
| 1941 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 1942 "http://example.com/foo.abc", "", |
| 1943 FILE_PATH_LITERAL("foo.png"), |
| 1944 |
| 1945 FILE_PATH_LITERAL(""), |
| 1946 FILE_PATH_LITERAL("foo.png"), |
| 1947 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 1948 |
| 1949 EXPECT_CRDOWNLOAD |
| 1950 }, |
| 1951 "image/png" |
| 1952 }, |
| 1953 { |
| 1954 { |
| 1955 // 3: Unknown file type. |
| 1956 AUTOMATIC, |
| 1957 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 1958 "http://example.com/foo.notarealext", "", |
| 1959 FILE_PATH_LITERAL(""), |
| 1960 |
| 1961 FILE_PATH_LITERAL(""), |
| 1962 FILE_PATH_LITERAL("foo.notarealext"), |
| 1963 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 1964 |
| 1965 EXPECT_CRDOWNLOAD |
| 1966 }, |
| 1967 "" |
| 1968 }, |
| 1969 { |
| 1970 { |
| 1971 // 4: Unknown file type. |
| 1972 AUTOMATIC, |
| 1973 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 1974 "http://example.com/foo.notarealext", "image/png", |
| 1975 FILE_PATH_LITERAL(""), |
| 1976 |
| 1977 FILE_PATH_LITERAL(""), |
| 1978 FILE_PATH_LITERAL("foo.notarealext"), |
| 1979 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 1980 |
| 1981 EXPECT_CRDOWNLOAD |
| 1982 }, |
| 1983 "" |
| 1984 }, |
| 1985 }; |
| 1986 |
| 1987 ON_CALL(*delegate(), GetFileMimeType( |
| 1988 GetPathInDownloadDir(FILE_PATH_LITERAL("foo.png")), _)) |
| 1989 .WillByDefault(WithArg<1>( |
| 1990 ScheduleCallback("image/png"))); |
| 1991 |
| 1992 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kMIMETypeTestCases); ++i) { |
| 1993 SCOPED_TRACE(testing::Message() << "Running test case " << i); |
| 1994 const MIMETypeTestCase& test_case = kMIMETypeTestCases[i]; |
| 1995 scoped_ptr<content::MockDownloadItem> item( |
| 1996 CreateActiveDownloadItem(i, test_case.general)); |
| 1997 scoped_ptr<DownloadTargetInfo> target_info = |
| 1998 RunDownloadTargetDeterminer(GetPathInDownloadDir(kInitialPath), |
| 1999 item.get()); |
| 2000 EXPECT_EQ(test_case.expected_mime_type, target_info->mime_type); |
| 2001 } |
| 2002 } |
| 2003 |
| 2004 #if defined(ENABLE_PLUGINS) |
| 2005 |
| 2006 void DummyGetPluginsCallback( |
| 2007 const base::Closure& closure, |
| 2008 const std::vector<content::WebPluginInfo>& plugins) { |
| 2009 closure.Run(); |
| 2010 } |
| 2011 |
| 2012 void ForceRefreshOfPlugins() { |
| 2013 base::RunLoop run_loop; |
| 2014 content::PluginService::GetInstance()->GetPlugins( |
| 2015 base::Bind(&DummyGetPluginsCallback, run_loop.QuitClosure())); |
| 2016 run_loop.Run(); |
| 2017 } |
| 2018 |
| 2019 void PluginEnabledCallback(const base::Closure& closure, |
| 2020 bool result) { |
| 2021 EXPECT_TRUE(result); |
| 2022 closure.Run(); |
| 2023 } |
| 2024 |
| 2025 void EnablePlugin(bool enable, PluginPrefs* prefs, const base::FilePath& path) { |
| 2026 base::RunLoop run_loop; |
| 2027 prefs->EnablePlugin(enable, path, |
| 2028 base::Bind(&PluginEnabledCallback, |
| 2029 run_loop.QuitClosure())); |
| 2030 run_loop.Run(); |
| 2031 } |
| 2032 |
| 2033 // Check if secure handling of filetypes is determined correctly for PPAPI |
| 2034 // plugins. |
| 2035 TEST_F(DownloadTargetDeterminerTest, |
| 2036 TargetDeterminer_CheckForSecureHandling_PPAPI) { |
| 2037 // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital |
| 2038 // path. |
| 2039 const base::FilePath::CharType kInitialPath[] = |
| 2040 FILE_PATH_LITERAL("some_path/bar.txt"); |
| 2041 const char kTestMIMEType[] = "application/x-example-should-not-exist"; |
| 2042 |
| 2043 DownloadTestCase kSecureHandlingTestCase = { |
| 2044 AUTOMATIC, |
| 2045 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 2046 "http://example.com/foo.fakeext", "", |
| 2047 FILE_PATH_LITERAL(""), |
| 2048 |
| 2049 FILE_PATH_LITERAL(""), |
| 2050 FILE_PATH_LITERAL("foo.fakeext"), |
| 2051 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 2052 |
| 2053 EXPECT_CRDOWNLOAD |
| 2054 }; |
| 2055 |
| 2056 content::PluginService* plugin_service = |
| 2057 content::PluginService::GetInstance(); |
| 2058 // This creates a PluginPrefs for our TestingProfile. |
| 2059 scoped_refptr<PluginPrefs> plugin_prefs = |
| 2060 PluginPrefs::GetForTestingProfile(profile()); |
| 2061 |
| 2062 // Verify our test assumptions. |
| 2063 { |
| 2064 ForceRefreshOfPlugins(); |
| 2065 std::vector<content::WebPluginInfo> info; |
| 2066 ASSERT_FALSE(plugin_service->GetPluginInfoArray( |
| 2067 GURL(), kTestMIMEType, false, &info, NULL)); |
| 2068 ASSERT_EQ(0u, info.size()) |
| 2069 << "Name: " << info[0].name << ", Path: " << info[0].path.value(); |
| 2070 } |
| 2071 |
| 2072 ON_CALL(*delegate(), GetFileMimeType( |
| 2073 GetPathInDownloadDir(FILE_PATH_LITERAL("foo.fakeext")), _)) |
| 2074 .WillByDefault(WithArg<1>( |
| 2075 ScheduleCallback(kTestMIMEType))); |
| 2076 scoped_ptr<content::MockDownloadItem> item( |
| 2077 CreateActiveDownloadItem(1, kSecureHandlingTestCase)); |
| 2078 scoped_ptr<DownloadTargetInfo> target_info = |
| 2079 RunDownloadTargetDeterminer(GetPathInDownloadDir(kInitialPath), |
| 2080 item.get()); |
| 2081 EXPECT_FALSE(target_info->is_filetype_handled_securely); |
| 2082 |
| 2083 // Register a PPAPI plugin. This should count as handling the filetype |
| 2084 // securely. |
| 2085 content::WebPluginMimeType plugin_mime_type(kTestMIMEType, |
| 2086 "fakeext", |
| 2087 "Test file"); |
| 2088 content::WebPluginInfo plugin_info(base::string16(), |
| 2089 test_download_dir().AppendASCII("foo"), |
| 2090 base::string16(), |
| 2091 base::string16()); |
| 2092 plugin_info.mime_types.push_back(plugin_mime_type); |
| 2093 plugin_info.type = content::WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS; |
| 2094 |
| 2095 plugin_service->RegisterInternalPlugin(plugin_info, true); |
| 2096 plugin_service->RefreshPlugins(); |
| 2097 ForceRefreshOfPlugins(); |
| 2098 |
| 2099 target_info = RunDownloadTargetDeterminer( |
| 2100 GetPathInDownloadDir(kInitialPath), item.get()); |
| 2101 EXPECT_TRUE(target_info->is_filetype_handled_securely); |
| 2102 |
| 2103 // Try disabling the plugin. Handling should no longer be considered secure. |
| 2104 EnablePlugin(false, plugin_prefs, plugin_info.path); |
| 2105 target_info = RunDownloadTargetDeterminer( |
| 2106 GetPathInDownloadDir(kInitialPath), item.get()); |
| 2107 EXPECT_FALSE(target_info->is_filetype_handled_securely); |
| 2108 |
| 2109 // Now register an unsandboxed PPAPI plug-in. This should not be considered |
| 2110 // secure. |
| 2111 plugin_info.path = test_download_dir().AppendASCII("bar"); |
| 2112 plugin_info.type = content::WebPluginInfo::PLUGIN_TYPE_PEPPER_UNSANDBOXED; |
| 2113 plugin_service->RegisterInternalPlugin(plugin_info, true); |
| 2114 plugin_service->RefreshPlugins(); |
| 2115 ForceRefreshOfPlugins(); |
| 2116 |
| 2117 target_info = RunDownloadTargetDeterminer( |
| 2118 GetPathInDownloadDir(kInitialPath), item.get()); |
| 2119 EXPECT_FALSE(target_info->is_filetype_handled_securely); |
| 2120 } |
| 2121 |
| 2122 // Check if secure handling of filetypes is determined correctly for NPAPI |
| 2123 // plugins. |
| 2124 TEST_F(DownloadTargetDeterminerTest, |
| 2125 TargetDeterminer_CheckForSecureHandling_NPAPI) { |
| 2126 // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital |
| 2127 // path. |
| 2128 const base::FilePath::CharType kInitialPath[] = |
| 2129 FILE_PATH_LITERAL("some_path/bar.txt"); |
| 2130 const char kTestMIMEType[] = "application/x-example-should-not-exist"; |
| 2131 |
| 2132 DownloadTestCase kSecureHandlingTestCase = { |
| 2133 AUTOMATIC, |
| 2134 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 2135 "http://example.com/foo.fakeext", "", |
| 2136 FILE_PATH_LITERAL(""), |
| 2137 |
| 2138 FILE_PATH_LITERAL(""), |
| 2139 FILE_PATH_LITERAL("foo.fakeext"), |
| 2140 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 2141 |
| 2142 EXPECT_CRDOWNLOAD |
| 2143 }; |
| 2144 |
| 2145 content::PluginService* plugin_service = |
| 2146 content::PluginService::GetInstance(); |
| 2147 // This creates a PluginPrefs for our TestingProfile. |
| 2148 scoped_refptr<PluginPrefs> plugin_prefs = |
| 2149 PluginPrefs::GetForTestingProfile(profile()); |
| 2150 |
| 2151 // Verify our test assumptions. |
| 2152 { |
| 2153 ForceRefreshOfPlugins(); |
| 2154 std::vector<content::WebPluginInfo> info; |
| 2155 ASSERT_FALSE(plugin_service->GetPluginInfoArray( |
| 2156 GURL(), kTestMIMEType, false, &info, NULL)); |
| 2157 ASSERT_EQ(0u, info.size()) |
| 2158 << "Name: " << info[0].name << ", Path: " << info[0].path.value(); |
| 2159 } |
| 2160 |
| 2161 ON_CALL(*delegate(), GetFileMimeType( |
| 2162 GetPathInDownloadDir(FILE_PATH_LITERAL("foo.fakeext")), _)) |
| 2163 .WillByDefault(WithArg<1>( |
| 2164 ScheduleCallback(kTestMIMEType))); |
| 2165 scoped_ptr<content::MockDownloadItem> item( |
| 2166 CreateActiveDownloadItem(1, kSecureHandlingTestCase)); |
| 2167 scoped_ptr<DownloadTargetInfo> target_info = |
| 2168 RunDownloadTargetDeterminer(GetPathInDownloadDir(kInitialPath), |
| 2169 item.get()); |
| 2170 EXPECT_FALSE(target_info->is_filetype_handled_securely); |
| 2171 |
| 2172 // Register a NPAPI plugin. This should not count as handling the filetype |
| 2173 // securely. |
| 2174 content::WebPluginMimeType plugin_mime_type(kTestMIMEType, |
| 2175 "fakeext", |
| 2176 "Test file"); |
| 2177 content::WebPluginInfo plugin_info(base::string16(), |
| 2178 test_download_dir().AppendASCII("foo"), |
| 2179 base::string16(), |
| 2180 base::string16()); |
| 2181 plugin_info.mime_types.push_back(plugin_mime_type); |
| 2182 plugin_info.type = content::WebPluginInfo::PLUGIN_TYPE_NPAPI; |
| 2183 |
| 2184 plugin_service->RegisterInternalPlugin(plugin_info, true); |
| 2185 plugin_service->RefreshPlugins(); |
| 2186 ForceRefreshOfPlugins(); |
| 2187 |
| 2188 target_info = RunDownloadTargetDeterminer( |
| 2189 GetPathInDownloadDir(kInitialPath), item.get()); |
| 2190 EXPECT_FALSE(target_info->is_filetype_handled_securely); |
| 2191 } |
| 2192 #endif // ENABLE_PLUGINS |
| 2193 |
1879 } // namespace | 2194 } // namespace |
OLD | NEW |