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.h" | 7 #include "base/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/string_util.h" | 12 #include "base/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_util.h" | 18 #include "chrome/browser/download/download_util.h" |
19 #include "chrome/browser/history/history_service.h" | 19 #include "chrome/browser/history/history_service.h" |
20 #include "chrome/browser/history/history_service_factory.h" | 20 #include "chrome/browser/history/history_service_factory.h" |
21 #include "chrome/browser/history/history_types.h" | 21 #include "chrome/browser/history/history_types.h" |
22 #include "chrome/common/extensions/extension.h" | 22 #include "chrome/common/extensions/extension.h" |
23 #include "chrome/common/pref_names.h" | 23 #include "chrome/common/pref_names.h" |
24 #include "chrome/test/base/chrome_render_view_host_test_harness.h" | 24 #include "chrome/test/base/chrome_render_view_host_test_harness.h" |
25 #include "chrome/test/base/testing_pref_service_syncable.h" | 25 #include "chrome/test/base/testing_pref_service_syncable.h" |
26 #include "chrome/test/base/testing_profile.h" | 26 #include "chrome/test/base/testing_profile.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" |
33 #include "testing/gmock/include/gmock/gmock.h" | 34 #include "testing/gmock/include/gmock/gmock.h" |
34 #include "testing/gtest/include/gtest/gtest.h" | 35 #include "testing/gtest/include/gtest/gtest.h" |
35 | 36 |
36 using ::testing::AnyNumber; | 37 using ::testing::AnyNumber; |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 | 199 |
199 // Set the kPromptForDownload user preference to |prompt|. | 200 // Set the kPromptForDownload user preference to |prompt|. |
200 void SetPromptForDownload(bool prompt); | 201 void SetPromptForDownload(bool prompt); |
201 | 202 |
202 // Given the relative path |path|, returns the full path under the temporary | 203 // Given the relative path |path|, returns the full path under the temporary |
203 // downloads directory. | 204 // downloads directory. |
204 base::FilePath GetPathInDownloadDir(const base::FilePath::StringType& path); | 205 base::FilePath GetPathInDownloadDir(const base::FilePath::StringType& path); |
205 | 206 |
206 // Run |test_case| using |item|. | 207 // Run |test_case| using |item|. |
207 void RunTestCase(const DownloadTestCase& test_case, | 208 void RunTestCase(const DownloadTestCase& test_case, |
| 209 const base::FilePath& initial_virtual_path, |
208 content::MockDownloadItem* item); | 210 content::MockDownloadItem* item); |
209 | 211 |
210 // Run through |test_case_count| tests in |test_cases|. A new MockDownloadItem | 212 // Run through |test_case_count| tests in |test_cases|. A new MockDownloadItem |
211 // will be created for each test case and destroyed when the test case is | 213 // will be created for each test case and destroyed when the test case is |
212 // complete. | 214 // complete. |
213 void RunTestCasesWithActiveItem(const DownloadTestCase test_cases[], | 215 void RunTestCasesWithActiveItem(const DownloadTestCase test_cases[], |
214 size_t test_case_count); | 216 size_t test_case_count); |
215 | 217 |
| 218 // Verifies that |target_path|, |disposition|, |expected_danger_type| and |
| 219 // |intermediate_path| matches the expectations of |test_case|. Posts |
| 220 // |closure| to the current message loop when done. |
| 221 void DownloadTargetVerifier(const base::Closure& closure, |
| 222 const DownloadTestCase& test_case, |
| 223 const base::FilePath& local_path, |
| 224 DownloadItem::TargetDisposition disposition, |
| 225 content::DownloadDangerType danger_type, |
| 226 const base::FilePath& intermediate_path); |
| 227 |
216 const base::FilePath& test_download_dir() const { | 228 const base::FilePath& test_download_dir() const { |
217 return test_download_dir_.path(); | 229 return test_download_dir_.path(); |
218 } | 230 } |
219 | 231 |
220 const base::FilePath& test_virtual_dir() const { | 232 const base::FilePath& test_virtual_dir() const { |
221 return test_virtual_dir_; | 233 return test_virtual_dir_; |
222 } | 234 } |
223 | 235 |
224 MockDownloadTargetDeterminerDelegate* delegate() { | 236 MockDownloadTargetDeterminerDelegate* delegate() { |
225 return &delegate_; | 237 return &delegate_; |
226 } | 238 } |
227 | 239 |
228 DownloadPrefs* download_prefs() { | 240 DownloadPrefs* download_prefs() { |
229 return download_prefs_.get(); | 241 return download_prefs_.get(); |
230 } | 242 } |
231 | 243 |
232 private: | 244 private: |
233 // Verifies that |target_path|, |disposition|, |expected_danger_type| and | |
234 // |intermediate_path| matches the expectations of |test_case|. Posts | |
235 // |closure| to the current message loop when done. | |
236 void DownloadTargetVerifier(const base::Closure& closure, | |
237 const DownloadTestCase& test_case, | |
238 const base::FilePath& local_path, | |
239 DownloadItem::TargetDisposition disposition, | |
240 content::DownloadDangerType danger_type, | |
241 const base::FilePath& intermediate_path); | |
242 | |
243 scoped_ptr<DownloadPrefs> download_prefs_; | 245 scoped_ptr<DownloadPrefs> download_prefs_; |
244 ::testing::NiceMock<MockDownloadTargetDeterminerDelegate> delegate_; | 246 ::testing::NiceMock<MockDownloadTargetDeterminerDelegate> delegate_; |
245 NullWebContentsDelegate web_contents_delegate_; | 247 NullWebContentsDelegate web_contents_delegate_; |
246 base::ScopedTempDir test_download_dir_; | 248 base::ScopedTempDir test_download_dir_; |
247 base::FilePath test_virtual_dir_; | 249 base::FilePath test_virtual_dir_; |
248 content::TestBrowserThread ui_thread_; | 250 content::TestBrowserThread ui_thread_; |
249 content::TestBrowserThread file_thread_; | 251 content::TestBrowserThread file_thread_; |
250 }; | 252 }; |
251 | 253 |
252 DownloadTargetDeterminerTest::DownloadTargetDeterminerTest() | 254 DownloadTargetDeterminerTest::DownloadTargetDeterminerTest() |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 ON_CALL(*item, GetDangerType()) | 297 ON_CALL(*item, GetDangerType()) |
296 .WillByDefault(Return(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS)); | 298 .WillByDefault(Return(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS)); |
297 ON_CALL(*item, GetForcedFilePath()) | 299 ON_CALL(*item, GetForcedFilePath()) |
298 .WillByDefault(ReturnRefOfCopy(forced_file_path)); | 300 .WillByDefault(ReturnRefOfCopy(forced_file_path)); |
299 ON_CALL(*item, GetFullPath()) | 301 ON_CALL(*item, GetFullPath()) |
300 .WillByDefault(ReturnRefOfCopy(base::FilePath())); | 302 .WillByDefault(ReturnRefOfCopy(base::FilePath())); |
301 ON_CALL(*item, GetHash()) | 303 ON_CALL(*item, GetHash()) |
302 .WillByDefault(ReturnRefOfCopy(std::string())); | 304 .WillByDefault(ReturnRefOfCopy(std::string())); |
303 ON_CALL(*item, GetId()) | 305 ON_CALL(*item, GetId()) |
304 .WillByDefault(Return(id)); | 306 .WillByDefault(Return(id)); |
| 307 ON_CALL(*item, GetLastReason()) |
| 308 .WillByDefault(Return(content::DOWNLOAD_INTERRUPT_REASON_NONE)); |
305 ON_CALL(*item, GetMimeType()) | 309 ON_CALL(*item, GetMimeType()) |
306 .WillByDefault(Return(test_case.mime_type)); | 310 .WillByDefault(Return(test_case.mime_type)); |
307 ON_CALL(*item, GetReferrerUrl()) | 311 ON_CALL(*item, GetReferrerUrl()) |
308 .WillByDefault(ReturnRefOfCopy(download_url)); | 312 .WillByDefault(ReturnRefOfCopy(download_url)); |
309 ON_CALL(*item, GetState()) | 313 ON_CALL(*item, GetState()) |
310 .WillByDefault(Return(DownloadItem::IN_PROGRESS)); | 314 .WillByDefault(Return(DownloadItem::IN_PROGRESS)); |
311 ON_CALL(*item, GetTargetDisposition()) | 315 ON_CALL(*item, GetTargetDisposition()) |
312 .WillByDefault(Return(initial_disposition)); | 316 .WillByDefault(Return(initial_disposition)); |
313 ON_CALL(*item, GetTargetFilePath()) | 317 ON_CALL(*item, GetTargetFilePath()) |
314 .WillByDefault(ReturnRefOfCopy(base::FilePath())); | 318 .WillByDefault(ReturnRefOfCopy(base::FilePath())); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 base::FilePath DownloadTargetDeterminerTest::GetPathInDownloadDir( | 353 base::FilePath DownloadTargetDeterminerTest::GetPathInDownloadDir( |
350 const base::FilePath::StringType& relative_path) { | 354 const base::FilePath::StringType& relative_path) { |
351 if (relative_path.empty()) | 355 if (relative_path.empty()) |
352 return base::FilePath(); | 356 return base::FilePath(); |
353 base::FilePath full_path(test_download_dir().Append(relative_path)); | 357 base::FilePath full_path(test_download_dir().Append(relative_path)); |
354 return full_path.NormalizePathSeparators(); | 358 return full_path.NormalizePathSeparators(); |
355 } | 359 } |
356 | 360 |
357 void DownloadTargetDeterminerTest::RunTestCase( | 361 void DownloadTargetDeterminerTest::RunTestCase( |
358 const DownloadTestCase& test_case, | 362 const DownloadTestCase& test_case, |
| 363 const base::FilePath& initial_virtual_path, |
359 content::MockDownloadItem* item) { | 364 content::MockDownloadItem* item) { |
360 // Kick off the test. | 365 // Kick off the test. |
361 base::WeakPtrFactory<DownloadTargetDeterminerTest> factory(this); | 366 base::WeakPtrFactory<DownloadTargetDeterminerTest> factory(this); |
362 base::RunLoop run_loop; | 367 base::RunLoop run_loop; |
363 DownloadTargetDeterminer::Start( | 368 DownloadTargetDeterminer::Start( |
364 item, download_prefs_.get(), delegate(), | 369 item, initial_virtual_path, download_prefs_.get(), delegate(), |
365 base::Bind(&DownloadTargetDeterminerTest::DownloadTargetVerifier, | 370 base::Bind(&DownloadTargetDeterminerTest::DownloadTargetVerifier, |
366 factory.GetWeakPtr(), run_loop.QuitClosure(), test_case)); | 371 factory.GetWeakPtr(), run_loop.QuitClosure(), test_case)); |
367 run_loop.Run(); | 372 run_loop.Run(); |
368 ::testing::Mock::VerifyAndClearExpectations(delegate()); | 373 ::testing::Mock::VerifyAndClearExpectations(delegate()); |
369 } | 374 } |
370 | 375 |
371 void DownloadTargetDeterminerTest::RunTestCasesWithActiveItem( | 376 void DownloadTargetDeterminerTest::RunTestCasesWithActiveItem( |
372 const DownloadTestCase test_cases[], | 377 const DownloadTestCase test_cases[], |
373 size_t test_case_count) { | 378 size_t test_case_count) { |
374 for (size_t i = 0; i < test_case_count; ++i) { | 379 for (size_t i = 0; i < test_case_count; ++i) { |
375 scoped_ptr<content::MockDownloadItem> item( | 380 scoped_ptr<content::MockDownloadItem> item( |
376 CreateActiveDownloadItem(i, test_cases[i])); | 381 CreateActiveDownloadItem(i, test_cases[i])); |
377 SCOPED_TRACE(testing::Message() << "Running test case " << i); | 382 SCOPED_TRACE(testing::Message() << "Running test case " << i); |
378 RunTestCase(test_cases[i], item.get()); | 383 RunTestCase(test_cases[i], base::FilePath(), item.get()); |
379 } | 384 } |
380 } | 385 } |
381 | 386 |
382 void DownloadTargetDeterminerTest::DownloadTargetVerifier( | 387 void DownloadTargetDeterminerTest::DownloadTargetVerifier( |
383 const base::Closure& closure, | 388 const base::Closure& closure, |
384 const DownloadTestCase& test_case, | 389 const DownloadTestCase& test_case, |
385 const base::FilePath& local_path, | 390 const base::FilePath& local_path, |
386 DownloadItem::TargetDisposition disposition, | 391 DownloadItem::TargetDisposition disposition, |
387 content::DownloadDangerType danger_type, | 392 content::DownloadDangerType danger_type, |
388 const base::FilePath& intermediate_path) { | 393 const base::FilePath& intermediate_path) { |
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
953 SCOPED_TRACE(testing::Message() << "Running test case " << i); | 958 SCOPED_TRACE(testing::Message() << "Running test case " << i); |
954 const DownloadTestCase& test_case = kInactiveTestCases[i]; | 959 const DownloadTestCase& test_case = kInactiveTestCases[i]; |
955 scoped_ptr<content::MockDownloadItem> item( | 960 scoped_ptr<content::MockDownloadItem> item( |
956 CreateActiveDownloadItem(i, test_case)); | 961 CreateActiveDownloadItem(i, test_case)); |
957 EXPECT_CALL(*item.get(), GetState()) | 962 EXPECT_CALL(*item.get(), GetState()) |
958 .WillRepeatedly(Return(content::DownloadItem::CANCELLED)); | 963 .WillRepeatedly(Return(content::DownloadItem::CANCELLED)); |
959 // Even though one is a SAVE_AS download, no prompt will be displayed to | 964 // Even though one is a SAVE_AS download, no prompt will be displayed to |
960 // the user because the download is inactive. | 965 // the user because the download is inactive. |
961 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, _, _)) | 966 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, _, _)) |
962 .Times(0); | 967 .Times(0); |
963 RunTestCase(kInactiveTestCases[i], item.get()); | 968 RunTestCase(test_case, base::FilePath(), item.get()); |
964 } | 969 } |
965 } | 970 } |
966 | 971 |
967 // If the reserved path could not be verified, then the user should see a | 972 // If the reserved path could not be verified, then the user should see a |
968 // prompt. | 973 // prompt. |
969 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ReservationFailed) { | 974 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ReservationFailed) { |
970 const DownloadTestCase kReservationFailedCases[] = { | 975 const DownloadTestCase kReservationFailedCases[] = { |
971 { | 976 { |
972 // 0: Automatic download. Since the reservation fails, the disposition of | 977 // 0: Automatic download. Since the reservation fails, the disposition of |
973 // the target is to prompt, but the returned path is used. | 978 // the target is to prompt, but the returned path is used. |
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1402 // First case: An extension sets the conflict_action to OVERWRITE. | 1407 // First case: An extension sets the conflict_action to OVERWRITE. |
1403 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _)) | 1408 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _)) |
1404 .WillOnce(WithArg<2>( | 1409 .WillOnce(WithArg<2>( |
1405 ScheduleCallback2(overridden_path, | 1410 ScheduleCallback2(overridden_path, |
1406 DownloadPathReservationTracker::OVERWRITE))); | 1411 DownloadPathReservationTracker::OVERWRITE))); |
1407 EXPECT_CALL(*delegate(), ReserveVirtualPath( | 1412 EXPECT_CALL(*delegate(), ReserveVirtualPath( |
1408 _, full_overridden_path, true, DownloadPathReservationTracker::OVERWRITE, | 1413 _, full_overridden_path, true, DownloadPathReservationTracker::OVERWRITE, |
1409 _)).WillOnce(WithArg<4>( | 1414 _)).WillOnce(WithArg<4>( |
1410 ScheduleCallback2(full_overridden_path, true))); | 1415 ScheduleCallback2(full_overridden_path, true))); |
1411 | 1416 |
1412 RunTestCase(test_case, item.get()); | 1417 RunTestCase(test_case, base::FilePath(), item.get()); |
1413 | 1418 |
1414 // Second case: An extension sets the conflict_action to PROMPT. | 1419 // Second case: An extension sets the conflict_action to PROMPT. |
1415 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _)) | 1420 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _)) |
1416 .WillOnce(WithArg<2>( | 1421 .WillOnce(WithArg<2>( |
1417 ScheduleCallback2(overridden_path, | 1422 ScheduleCallback2(overridden_path, |
1418 DownloadPathReservationTracker::PROMPT))); | 1423 DownloadPathReservationTracker::PROMPT))); |
1419 EXPECT_CALL(*delegate(), ReserveVirtualPath( | 1424 EXPECT_CALL(*delegate(), ReserveVirtualPath( |
1420 _, full_overridden_path, true, DownloadPathReservationTracker::PROMPT, _)) | 1425 _, full_overridden_path, true, DownloadPathReservationTracker::PROMPT, _)) |
1421 .WillOnce(WithArg<4>( | 1426 .WillOnce(WithArg<4>( |
1422 ScheduleCallback2(full_overridden_path, true))); | 1427 ScheduleCallback2(full_overridden_path, true))); |
1423 RunTestCase(test_case, item.get()); | 1428 RunTestCase(test_case, base::FilePath(), item.get()); |
1424 } | 1429 } |
1425 | 1430 |
1426 // Test that relative paths returned by extensions are always relative to the | 1431 // Test that relative paths returned by extensions are always relative to the |
1427 // default downloads path. | 1432 // default downloads path. |
1428 TEST_F(DownloadTargetDeterminerTest, | 1433 TEST_F(DownloadTargetDeterminerTest, |
1429 TargetDeterminer_NotifyExtensionsDefaultPath) { | 1434 TargetDeterminer_NotifyExtensionsDefaultPath) { |
1430 const DownloadTestCase kNotifyExtensionsTestCase = { | 1435 const DownloadTestCase kNotifyExtensionsTestCase = { |
1431 SAVE_AS, | 1436 SAVE_AS, |
1432 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | 1437 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
1433 "http://example.com/foo.txt", "text/plain", | 1438 "http://example.com/foo.txt", "text/plain", |
(...skipping 17 matching lines...) Expand all Loading... |
1451 FILE_PATH_LITERAL("last_selected"))); | 1456 FILE_PATH_LITERAL("last_selected"))); |
1452 | 1457 |
1453 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _)) | 1458 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _)) |
1454 .WillOnce(WithArg<2>( | 1459 .WillOnce(WithArg<2>( |
1455 ScheduleCallback2(overridden_path, | 1460 ScheduleCallback2(overridden_path, |
1456 DownloadPathReservationTracker::UNIQUIFY))); | 1461 DownloadPathReservationTracker::UNIQUIFY))); |
1457 EXPECT_CALL(*delegate(), | 1462 EXPECT_CALL(*delegate(), |
1458 PromptUserForDownloadPath(_, full_overridden_path, _)) | 1463 PromptUserForDownloadPath(_, full_overridden_path, _)) |
1459 .WillOnce(WithArg<2>( | 1464 .WillOnce(WithArg<2>( |
1460 ScheduleCallback(full_overridden_path))); | 1465 ScheduleCallback(full_overridden_path))); |
1461 RunTestCase(test_case, item.get()); | 1466 RunTestCase(test_case, base::FilePath(), item.get()); |
1462 } | 1467 } |
| 1468 |
| 1469 TEST_F(DownloadTargetDeterminerTest, |
| 1470 TargetDeterminer_InitialVirtualPathUnsafe) { |
| 1471 const base::FilePath::CharType* kInitialPath = |
| 1472 FILE_PATH_LITERAL("some_path/bar.html"); |
| 1473 |
| 1474 const DownloadTestCase kInitialPathTestCase = { |
| 1475 // 0: Save As Save. The path generated based on the DownloadItem is safe, |
| 1476 // but the initial path is unsafe. However, the download is not considered |
| 1477 // dangerous since the user has been prompted. |
| 1478 SAVE_AS, |
| 1479 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 1480 "http://example.com/foo.txt", "text/plain", |
| 1481 FILE_PATH_LITERAL(""), |
| 1482 |
| 1483 FILE_PATH_LITERAL(""), |
| 1484 kInitialPath, |
| 1485 DownloadItem::TARGET_DISPOSITION_PROMPT, |
| 1486 |
| 1487 EXPECT_CRDOWNLOAD |
| 1488 }; |
| 1489 |
| 1490 const DownloadTestCase& test_case = kInitialPathTestCase; |
| 1491 scoped_ptr<content::MockDownloadItem> item( |
| 1492 CreateActiveDownloadItem(1, test_case)); |
| 1493 EXPECT_CALL(*item, GetLastReason()) |
| 1494 .WillRepeatedly(Return( |
| 1495 content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED)); |
| 1496 EXPECT_CALL(*item, GetTargetDisposition()) |
| 1497 .WillRepeatedly(Return(DownloadItem::TARGET_DISPOSITION_PROMPT)); |
| 1498 RunTestCase(test_case, GetPathInDownloadDir(kInitialPath), item.get()); |
| 1499 } |
| 1500 |
| 1501 // Prompting behavior for resumed downloads is based on the last interrupt |
| 1502 // reason. If the reason indicates that the target path may not be suitable for |
| 1503 // the download (ACCESS_DENIED, NO_SPACE, etc..), then the user should be |
| 1504 // prompted, and not otherwise. These test cases shouldn't result in prompting |
| 1505 // since the error is set to NETWORK_FAILED. |
| 1506 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ResumedNoPrompt) { |
| 1507 // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital |
| 1508 // path. |
| 1509 const base::FilePath::CharType* kInitialPath = |
| 1510 FILE_PATH_LITERAL("some_path/bar.txt"); |
| 1511 |
| 1512 const DownloadTestCase kResumedTestCases[] = { |
| 1513 { |
| 1514 // 0: Automatic Safe: Initial path is ignored since the user has not been |
| 1515 // prompted before. |
| 1516 AUTOMATIC, |
| 1517 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 1518 "http://example.com/foo.txt", "text/plain", |
| 1519 FILE_PATH_LITERAL(""), |
| 1520 |
| 1521 FILE_PATH_LITERAL(""), |
| 1522 FILE_PATH_LITERAL("foo.txt"), |
| 1523 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 1524 |
| 1525 EXPECT_CRDOWNLOAD |
| 1526 }, |
| 1527 |
| 1528 { |
| 1529 // 1: Save_As Safe: Initial path used. |
| 1530 SAVE_AS, |
| 1531 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 1532 "http://example.com/foo.txt", "text/plain", |
| 1533 FILE_PATH_LITERAL(""), |
| 1534 |
| 1535 FILE_PATH_LITERAL(""), |
| 1536 kInitialPath, |
| 1537 DownloadItem::TARGET_DISPOSITION_PROMPT, |
| 1538 |
| 1539 EXPECT_CRDOWNLOAD |
| 1540 }, |
| 1541 |
| 1542 { |
| 1543 // 2: Automatic Dangerous: Initial path is ignored since the user hasn't |
| 1544 // been prompted before. |
| 1545 AUTOMATIC, |
| 1546 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, |
| 1547 "http://example.com/foo.html", "", |
| 1548 FILE_PATH_LITERAL(""), |
| 1549 |
| 1550 FILE_PATH_LITERAL(""), |
| 1551 FILE_PATH_LITERAL("foo.html"), |
| 1552 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 1553 |
| 1554 EXPECT_UNCONFIRMED |
| 1555 }, |
| 1556 |
| 1557 { |
| 1558 // 3: Forced Safe: Initial path is ignored due to the forced path. |
| 1559 FORCED, |
| 1560 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 1561 "http://example.com/foo.txt", "", |
| 1562 FILE_PATH_LITERAL("forced-foo.txt"), |
| 1563 |
| 1564 FILE_PATH_LITERAL(""), |
| 1565 FILE_PATH_LITERAL("forced-foo.txt"), |
| 1566 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 1567 |
| 1568 EXPECT_LOCAL_PATH |
| 1569 }, |
| 1570 }; |
| 1571 |
| 1572 // The test assumes that .html files have a danger level of |
| 1573 // AllowOnUserGesture. |
| 1574 ASSERT_EQ(download_util::AllowOnUserGesture, |
| 1575 download_util::GetFileDangerLevel( |
| 1576 base::FilePath(FILE_PATH_LITERAL("foo.html")))); |
| 1577 for (size_t i = 0; i < arraysize(kResumedTestCases); ++i) { |
| 1578 SCOPED_TRACE(testing::Message() << "Running test case " << i); |
| 1579 const DownloadTestCase& test_case = kResumedTestCases[i]; |
| 1580 scoped_ptr<content::MockDownloadItem> item( |
| 1581 CreateActiveDownloadItem(i, test_case)); |
| 1582 base::FilePath expected_path = |
| 1583 GetPathInDownloadDir(test_case.expected_local_path); |
| 1584 ON_CALL(*item.get(), GetLastReason()) |
| 1585 .WillByDefault(Return( |
| 1586 content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED)); |
| 1587 // Extensions should be notified if a new path is being generated and there |
| 1588 // is no forced path. In the test cases above, this is true for tests with |
| 1589 // type == AUTOMATIC. |
| 1590 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _)) |
| 1591 .Times(test_case.test_type == AUTOMATIC ? 1 : 0); |
| 1592 EXPECT_CALL(*delegate(), ReserveVirtualPath(_, expected_path, false, _, _)); |
| 1593 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, expected_path, _)) |
| 1594 .Times(0); |
| 1595 EXPECT_CALL(*delegate(), DetermineLocalPath(_, expected_path, _)); |
| 1596 EXPECT_CALL(*delegate(), CheckDownloadUrl(_, expected_path, _)); |
| 1597 RunTestCase(test_case, GetPathInDownloadDir(kInitialPath), item.get()); |
| 1598 } |
| 1599 |
| 1600 } |
| 1601 |
| 1602 // Test that a forced download doesn't prompt, even if the interrupt reason |
| 1603 // suggests that the target path may not be suitable for downloads. |
| 1604 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ResumedForcedDownload) { |
| 1605 const base::FilePath::CharType* kInitialPath = |
| 1606 FILE_PATH_LITERAL("some_path/bar.txt"); |
| 1607 const DownloadTestCase kResumedForcedDownload = { |
| 1608 // 3: Forced Safe |
| 1609 FORCED, |
| 1610 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 1611 "http://example.com/foo.txt", "", |
| 1612 FILE_PATH_LITERAL("forced-foo.txt"), |
| 1613 |
| 1614 FILE_PATH_LITERAL(""), |
| 1615 FILE_PATH_LITERAL("forced-foo.txt"), |
| 1616 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 1617 |
| 1618 EXPECT_LOCAL_PATH |
| 1619 }; |
| 1620 |
| 1621 const DownloadTestCase& test_case = kResumedForcedDownload; |
| 1622 base::FilePath expected_path = |
| 1623 GetPathInDownloadDir(test_case.expected_local_path); |
| 1624 scoped_ptr<content::MockDownloadItem> item( |
| 1625 CreateActiveDownloadItem(0, test_case)); |
| 1626 ON_CALL(*item.get(), GetLastReason()) |
| 1627 .WillByDefault(Return(content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE)); |
| 1628 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _)) |
| 1629 .Times(test_case.test_type == AUTOMATIC ? 1 : 0); |
| 1630 EXPECT_CALL(*delegate(), ReserveVirtualPath(_, expected_path, false, _, _)); |
| 1631 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, _, _)) |
| 1632 .Times(0); |
| 1633 EXPECT_CALL(*delegate(), DetermineLocalPath(_, expected_path, _)); |
| 1634 EXPECT_CALL(*delegate(), CheckDownloadUrl(_, expected_path, _)); |
| 1635 RunTestCase(test_case, GetPathInDownloadDir(kInitialPath), item.get()); |
| 1636 } |
| 1637 |
| 1638 // Prompting behavior for resumed downloads is based on the last interrupt |
| 1639 // reason. If the reason indicates that the target path may not be suitable for |
| 1640 // the download (ACCESS_DENIED, NO_SPACE, etc..), then the user should be |
| 1641 // prompted, and not otherwise. These test cases result in prompting since the |
| 1642 // error is set to NO_SPACE. |
| 1643 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ResumedWithPrompt) { |
| 1644 // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital |
| 1645 // path. |
| 1646 const base::FilePath::CharType* kInitialPath = |
| 1647 FILE_PATH_LITERAL("some_path/bar.txt"); |
| 1648 |
| 1649 const DownloadTestCase kResumedTestCases[] = { |
| 1650 { |
| 1651 // 0: Automatic Safe |
| 1652 AUTOMATIC, |
| 1653 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 1654 "http://example.com/foo.txt", "text/plain", |
| 1655 FILE_PATH_LITERAL(""), |
| 1656 |
| 1657 FILE_PATH_LITERAL(""), |
| 1658 FILE_PATH_LITERAL("foo.txt"), |
| 1659 DownloadItem::TARGET_DISPOSITION_PROMPT, |
| 1660 |
| 1661 EXPECT_CRDOWNLOAD |
| 1662 }, |
| 1663 |
| 1664 { |
| 1665 // 1: Save_As Safe |
| 1666 SAVE_AS, |
| 1667 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 1668 "http://example.com/foo.txt", "text/plain", |
| 1669 FILE_PATH_LITERAL(""), |
| 1670 |
| 1671 FILE_PATH_LITERAL(""), |
| 1672 kInitialPath, |
| 1673 DownloadItem::TARGET_DISPOSITION_PROMPT, |
| 1674 |
| 1675 EXPECT_CRDOWNLOAD |
| 1676 }, |
| 1677 |
| 1678 { |
| 1679 // 2: Automatic Dangerous |
| 1680 AUTOMATIC, |
| 1681 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 1682 "http://example.com/foo.html", "", |
| 1683 FILE_PATH_LITERAL(""), |
| 1684 |
| 1685 FILE_PATH_LITERAL(""), |
| 1686 FILE_PATH_LITERAL("foo.html"), |
| 1687 DownloadItem::TARGET_DISPOSITION_PROMPT, |
| 1688 |
| 1689 EXPECT_CRDOWNLOAD |
| 1690 }, |
| 1691 }; |
| 1692 |
| 1693 // The test assumes that .html files have a danger level of |
| 1694 // AllowOnUserGesture. |
| 1695 ASSERT_EQ(download_util::AllowOnUserGesture, |
| 1696 download_util::GetFileDangerLevel( |
| 1697 base::FilePath(FILE_PATH_LITERAL("foo.html")))); |
| 1698 for (size_t i = 0; i < arraysize(kResumedTestCases); ++i) { |
| 1699 SCOPED_TRACE(testing::Message() << "Running test case " << i); |
| 1700 download_prefs()->SetSaveFilePath(test_download_dir()); |
| 1701 const DownloadTestCase& test_case = kResumedTestCases[i]; |
| 1702 base::FilePath expected_path = |
| 1703 GetPathInDownloadDir(test_case.expected_local_path); |
| 1704 scoped_ptr<content::MockDownloadItem> item( |
| 1705 CreateActiveDownloadItem(i, test_case)); |
| 1706 ON_CALL(*item.get(), GetLastReason()) |
| 1707 .WillByDefault(Return( |
| 1708 content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE)); |
| 1709 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _)) |
| 1710 .Times(test_case.test_type == AUTOMATIC ? 1 : 0); |
| 1711 EXPECT_CALL(*delegate(), ReserveVirtualPath(_, expected_path, false, _, _)); |
| 1712 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, expected_path, _)); |
| 1713 EXPECT_CALL(*delegate(), DetermineLocalPath(_, expected_path, _)); |
| 1714 EXPECT_CALL(*delegate(), CheckDownloadUrl(_, expected_path, _)); |
| 1715 RunTestCase(test_case, GetPathInDownloadDir(kInitialPath), item.get()); |
| 1716 } |
| 1717 } |
| 1718 |
| 1719 // Used with TargetDeterminer_IntermediateNameForResumed test. Verifies that |
| 1720 // |intermediate_path| == |expected_intermediate_path| if the latter is |
| 1721 // non-empty. |
| 1722 void IntermediatePathVerifier( |
| 1723 const base::FilePath& expected_intermediate_path, |
| 1724 const content::DownloadTargetCallback& callback, |
| 1725 const base::FilePath& target_path, |
| 1726 content::DownloadItem::TargetDisposition disposition, |
| 1727 content::DownloadDangerType danger_type, |
| 1728 const base::FilePath& intermediate_path) { |
| 1729 if (!expected_intermediate_path.empty()) |
| 1730 EXPECT_EQ(expected_intermediate_path, intermediate_path); |
| 1731 callback.Run(target_path, disposition, danger_type, intermediate_path); |
| 1732 } |
| 1733 |
| 1734 // Test intermediate filename generation for resumed downloads. |
| 1735 TEST_F(DownloadTargetDeterminerTest, |
| 1736 TargetDeterminer_IntermediateNameForResumed) { |
| 1737 // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital |
| 1738 // path. |
| 1739 const base::FilePath::CharType kInitialPath[] = |
| 1740 FILE_PATH_LITERAL("some_path/bar.txt"); |
| 1741 |
| 1742 struct IntermediateNameTestCase { |
| 1743 // General test case settings. |
| 1744 DownloadTestCase general; |
| 1745 |
| 1746 // Value of DownloadItem::GetFullPath() during test run, relative |
| 1747 // to test download path. |
| 1748 const base::FilePath::CharType* initial_intermediate_path; |
| 1749 |
| 1750 // Expected intermediate path relatvie to the test download path. An exact |
| 1751 // match is performed if this string is non-empty. Ignored otherwise. |
| 1752 const base::FilePath::CharType* expected_intermediate_path; |
| 1753 } kIntermediateNameTestCases[] = { |
| 1754 { |
| 1755 { |
| 1756 // 0: Automatic Safe |
| 1757 AUTOMATIC, |
| 1758 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 1759 "http://example.com/foo.txt", "text/plain", |
| 1760 FILE_PATH_LITERAL(""), |
| 1761 |
| 1762 FILE_PATH_LITERAL(""), |
| 1763 FILE_PATH_LITERAL("foo.txt"), |
| 1764 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 1765 |
| 1766 EXPECT_CRDOWNLOAD |
| 1767 }, |
| 1768 FILE_PATH_LITERAL("bar.txt.crdownload"), |
| 1769 FILE_PATH_LITERAL("foo.txt.crdownload") |
| 1770 }, |
| 1771 |
| 1772 { |
| 1773 { |
| 1774 // 1: Save_As Safe |
| 1775 SAVE_AS, |
| 1776 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 1777 "http://example.com/foo.txt", "text/plain", |
| 1778 FILE_PATH_LITERAL(""), |
| 1779 |
| 1780 FILE_PATH_LITERAL(""), |
| 1781 kInitialPath, |
| 1782 DownloadItem::TARGET_DISPOSITION_PROMPT, |
| 1783 |
| 1784 EXPECT_CRDOWNLOAD |
| 1785 }, |
| 1786 FILE_PATH_LITERAL("foo.txt.crdownload"), |
| 1787 FILE_PATH_LITERAL("some_path/bar.txt.crdownload") |
| 1788 }, |
| 1789 |
| 1790 { |
| 1791 { |
| 1792 // 2: Automatic Dangerous |
| 1793 AUTOMATIC, |
| 1794 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, |
| 1795 "http://example.com/foo.html", "", |
| 1796 FILE_PATH_LITERAL(""), |
| 1797 |
| 1798 FILE_PATH_LITERAL(""), |
| 1799 FILE_PATH_LITERAL("foo.html"), |
| 1800 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 1801 |
| 1802 EXPECT_UNCONFIRMED |
| 1803 }, |
| 1804 FILE_PATH_LITERAL("Unconfirmed abcd.crdownload"), |
| 1805 FILE_PATH_LITERAL("Unconfirmed abcd.crdownload") |
| 1806 }, |
| 1807 |
| 1808 { |
| 1809 { |
| 1810 // 3: Automatic Dangerous |
| 1811 AUTOMATIC, |
| 1812 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, |
| 1813 "http://example.com/foo.html", "", |
| 1814 FILE_PATH_LITERAL(""), |
| 1815 |
| 1816 FILE_PATH_LITERAL(""), |
| 1817 FILE_PATH_LITERAL("foo.html"), |
| 1818 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 1819 |
| 1820 EXPECT_UNCONFIRMED |
| 1821 }, |
| 1822 FILE_PATH_LITERAL("other_path/Unconfirmed abcd.crdownload"), |
| 1823 // Rely on the EXPECT_UNCONFIRMED check in the general test settings. A |
| 1824 // new intermediate path of the form "Unconfirmed <number>.crdownload" |
| 1825 // should be generated for this case since the initial intermediate path |
| 1826 // is in the wrong directory. |
| 1827 FILE_PATH_LITERAL("") |
| 1828 }, |
| 1829 |
| 1830 { |
| 1831 { |
| 1832 // 3: Forced Safe: Initial path is ignored due to the forced path. |
| 1833 FORCED, |
| 1834 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 1835 "http://example.com/foo.txt", "", |
| 1836 FILE_PATH_LITERAL("forced-foo.txt"), |
| 1837 |
| 1838 FILE_PATH_LITERAL(""), |
| 1839 FILE_PATH_LITERAL("forced-foo.txt"), |
| 1840 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 1841 |
| 1842 EXPECT_LOCAL_PATH |
| 1843 }, |
| 1844 FILE_PATH_LITERAL("forced-foo.txt"), |
| 1845 FILE_PATH_LITERAL("forced-foo.txt") |
| 1846 }, |
| 1847 }; |
| 1848 |
| 1849 // The test assumes that .html files have a danger level of |
| 1850 // AllowOnUserGesture. |
| 1851 ASSERT_EQ(download_util::AllowOnUserGesture, |
| 1852 download_util::GetFileDangerLevel( |
| 1853 base::FilePath(FILE_PATH_LITERAL("foo.html")))); |
| 1854 |
| 1855 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kIntermediateNameTestCases); ++i) { |
| 1856 SCOPED_TRACE(testing::Message() << "Running test case " << i); |
| 1857 const IntermediateNameTestCase& test_case = kIntermediateNameTestCases[i]; |
| 1858 scoped_ptr<content::MockDownloadItem> item( |
| 1859 CreateActiveDownloadItem(i, test_case.general)); |
| 1860 |
| 1861 ON_CALL(*item.get(), GetLastReason()) |
| 1862 .WillByDefault(Return( |
| 1863 content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED)); |
| 1864 ON_CALL(*item.get(), GetFullPath()) |
| 1865 .WillByDefault(ReturnRefOfCopy( |
| 1866 GetPathInDownloadDir(test_case.initial_intermediate_path))); |
| 1867 ON_CALL(*item.get(), GetDangerType()) |
| 1868 .WillByDefault(Return(test_case.general.expected_danger_type)); |
| 1869 |
| 1870 base::WeakPtrFactory<DownloadTargetDeterminerTest> factory(this); |
| 1871 base::RunLoop run_loop; |
| 1872 content::DownloadTargetCallback verifier_callback = |
| 1873 base::Bind(&DownloadTargetDeterminerTest::DownloadTargetVerifier, |
| 1874 factory.GetWeakPtr(), |
| 1875 run_loop.QuitClosure(), |
| 1876 test_case.general); |
| 1877 content::DownloadTargetCallback test_callback = |
| 1878 base::Bind(&IntermediatePathVerifier, |
| 1879 GetPathInDownloadDir(test_case.expected_intermediate_path), |
| 1880 verifier_callback); |
| 1881 DownloadTargetDeterminer::Start(item.get(), |
| 1882 GetPathInDownloadDir(kInitialPath), |
| 1883 download_prefs(), |
| 1884 delegate(), |
| 1885 test_callback); |
| 1886 run_loop.Run(); |
| 1887 ::testing::Mock::VerifyAndClearExpectations(delegate()); |
| 1888 } |
| 1889 } |
| 1890 |
1463 } // namespace | 1891 } // namespace |
OLD | NEW |