OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/file_path.h" | 5 #include "base/file_path.h" |
6 #include "base/file_util.h" | 6 #include "base/file_util.h" |
7 #include "base/memory/ref_counted.h" | 7 #include "base/memory/ref_counted.h" |
8 #include "base/path_service.h" | 8 #include "base/path_service.h" |
9 #include "base/scoped_temp_dir.h" | 9 #include "base/scoped_temp_dir.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
11 #include "base/test/test_file_util.h" | 11 #include "base/test/test_file_util.h" |
12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
13 #include "chrome/browser/browser_process.h" | 13 #include "chrome/browser/browser_process.h" |
| 14 #include "chrome/browser/download/chrome_download_manager_delegate.h" |
14 #include "chrome/browser/download/download_crx_util.h" | 15 #include "chrome/browser/download/download_crx_util.h" |
15 #include "chrome/browser/download/download_history.h" | 16 #include "chrome/browser/download/download_history.h" |
16 #include "chrome/browser/download/download_prefs.h" | 17 #include "chrome/browser/download/download_prefs.h" |
17 #include "chrome/browser/download/download_shelf.h" | 18 #include "chrome/browser/download/download_shelf.h" |
18 #include "chrome/browser/download/download_util.h" | 19 #include "chrome/browser/download/download_util.h" |
19 #include "chrome/browser/extensions/extension_install_ui.h" | 20 #include "chrome/browser/extensions/extension_install_ui.h" |
20 #include "chrome/browser/extensions/extension_service.h" | 21 #include "chrome/browser/extensions/extension_service.h" |
21 #include "chrome/browser/history/history.h" | 22 #include "chrome/browser/history/history.h" |
22 #include "chrome/browser/prefs/pref_service.h" | 23 #include "chrome/browser/prefs/pref_service.h" |
23 #include "chrome/browser/profiles/profile.h" | 24 #include "chrome/browser/profiles/profile.h" |
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 } | 484 } |
484 | 485 |
485 ResourceDispatcherHost* resource_dispatcher_host_; | 486 ResourceDispatcherHost* resource_dispatcher_host_; |
486 DownloadFileManager* download_file_manager_; | 487 DownloadFileManager* download_file_manager_; |
487 int rdh_pending_requests_; | 488 int rdh_pending_requests_; |
488 int dfm_pending_downloads_; | 489 int dfm_pending_downloads_; |
489 | 490 |
490 DISALLOW_COPY_AND_ASSIGN(CancelTestDataCollector); | 491 DISALLOW_COPY_AND_ASSIGN(CancelTestDataCollector); |
491 }; | 492 }; |
492 | 493 |
| 494 class PickSuggestedFileDelegate : public ChromeDownloadManagerDelegate { |
| 495 public: |
| 496 explicit PickSuggestedFileDelegate(Profile* profile) |
| 497 : ChromeDownloadManagerDelegate(profile) { |
| 498 SetDownloadManager(profile->GetDownloadManager()); |
| 499 } |
| 500 |
| 501 virtual void ChooseDownloadPath(TabContents* tab_contents, |
| 502 const FilePath& suggested_path, |
| 503 void* data) OVERRIDE { |
| 504 if (download_manager_) |
| 505 download_manager_->FileSelected(suggested_path, data); |
| 506 } |
| 507 }; |
| 508 |
| 509 // Get History Information. |
| 510 class DownloadsHistoryDataCollector { |
| 511 public: |
| 512 DownloadsHistoryDataCollector(int64 download_db_handle, |
| 513 DownloadManager* manager) |
| 514 : result_valid_(false), |
| 515 download_db_handle_(download_db_handle) { |
| 516 HistoryService* hs = |
| 517 Profile::FromBrowserContext(manager->browser_context())-> |
| 518 GetHistoryService(Profile::EXPLICIT_ACCESS); |
| 519 DCHECK(hs); |
| 520 hs->QueryDownloads( |
| 521 &callback_consumer_, |
| 522 NewCallback(this, |
| 523 &DownloadsHistoryDataCollector::OnQueryDownloadsComplete)); |
| 524 |
| 525 // TODO(rdsmith): Move message loop out of constructor. |
| 526 // Cannot complete immediately because the history backend runs on a |
| 527 // separate thread, so we can assume that the RunMessageLoop below will |
| 528 // be exited by the Quit in OnQueryDownloadsComplete. |
| 529 ui_test_utils::RunMessageLoop(); |
| 530 } |
| 531 |
| 532 bool GetDownloadsHistoryEntry(DownloadPersistentStoreInfo* result) { |
| 533 DCHECK(result); |
| 534 *result = result_; |
| 535 return result_valid_; |
| 536 } |
| 537 |
| 538 private: |
| 539 void OnQueryDownloadsComplete( |
| 540 std::vector<DownloadPersistentStoreInfo>* entries) { |
| 541 result_valid_ = false; |
| 542 for (std::vector<DownloadPersistentStoreInfo>::const_iterator it = |
| 543 entries->begin(); |
| 544 it != entries->end(); ++it) { |
| 545 if (it->db_handle == download_db_handle_) { |
| 546 result_ = *it; |
| 547 result_valid_ = true; |
| 548 } |
| 549 } |
| 550 MessageLoopForUI::current()->Quit(); |
| 551 } |
| 552 |
| 553 DownloadPersistentStoreInfo result_; |
| 554 bool result_valid_; |
| 555 int64 download_db_handle_; |
| 556 CancelableRequestConsumer callback_consumer_; |
| 557 |
| 558 DISALLOW_COPY_AND_ASSIGN(DownloadsHistoryDataCollector); |
| 559 }; |
| 560 |
| 561 // Mock that simulates a permissions dialog where the user denies |
| 562 // permission to install. TODO(skerner): This could be shared with |
| 563 // extensions tests. Find a common place for this class. |
| 564 class MockAbortExtensionInstallUI : public ExtensionInstallUI { |
| 565 public: |
| 566 MockAbortExtensionInstallUI() : ExtensionInstallUI(NULL) {} |
| 567 |
| 568 // Simulate a user abort on an extension installation. |
| 569 virtual void ConfirmInstall(Delegate* delegate, const Extension* extension) { |
| 570 delegate->InstallUIAbort(true); |
| 571 MessageLoopForUI::current()->Quit(); |
| 572 } |
| 573 |
| 574 virtual void OnInstallSuccess(const Extension* extension, SkBitmap* icon) {} |
| 575 virtual void OnInstallFailure(const std::string& error) {} |
| 576 }; |
| 577 |
| 578 // Mock that simulates a permissions dialog where the user allows |
| 579 // installation. |
| 580 class MockAutoConfirmExtensionInstallUI : public ExtensionInstallUI { |
| 581 public: |
| 582 explicit MockAutoConfirmExtensionInstallUI(Profile* profile) |
| 583 : ExtensionInstallUI(profile) {} |
| 584 |
| 585 // Proceed without confirmation prompt. |
| 586 virtual void ConfirmInstall(Delegate* delegate, const Extension* extension) { |
| 587 delegate->InstallUIProceed(); |
| 588 } |
| 589 |
| 590 virtual void OnInstallSuccess(const Extension* extension, SkBitmap* icon) {} |
| 591 virtual void OnInstallFailure(const std::string& error) {} |
| 592 }; |
| 593 |
| 594 } // namespace |
| 595 |
| 596 // While an object of this class exists, it will mock out download |
| 597 // opening for all downloads created on the specified download manager. |
| 598 class MockDownloadOpeningObserver : public DownloadManager::Observer { |
| 599 public: |
| 600 explicit MockDownloadOpeningObserver(DownloadManager* manager) |
| 601 : download_manager_(manager) { |
| 602 download_manager_->AddObserver(this); |
| 603 } |
| 604 |
| 605 ~MockDownloadOpeningObserver() { |
| 606 download_manager_->RemoveObserver(this); |
| 607 } |
| 608 |
| 609 // DownloadManager::Observer |
| 610 virtual void ModelChanged() { |
| 611 std::vector<DownloadItem*> downloads; |
| 612 download_manager_->SearchDownloads(string16(), &downloads); |
| 613 |
| 614 for (std::vector<DownloadItem*>::iterator it = downloads.begin(); |
| 615 it != downloads.end(); ++it) { |
| 616 (*it)->TestMockDownloadOpen(); |
| 617 } |
| 618 } |
| 619 |
| 620 private: |
| 621 DownloadManager* download_manager_; |
| 622 |
| 623 DISALLOW_COPY_AND_ASSIGN(MockDownloadOpeningObserver); |
| 624 }; |
| 625 |
493 class DownloadTest : public InProcessBrowserTest { | 626 class DownloadTest : public InProcessBrowserTest { |
494 public: | 627 public: |
495 enum SelectExpectation { | 628 enum SelectExpectation { |
496 EXPECT_NO_SELECT_DIALOG = -1, | 629 EXPECT_NO_SELECT_DIALOG = -1, |
497 EXPECT_NOTHING, | 630 EXPECT_NOTHING, |
498 EXPECT_SELECT_DIALOG | 631 EXPECT_SELECT_DIALOG |
499 }; | 632 }; |
500 | 633 |
501 DownloadTest() { | 634 DownloadTest() { |
502 EnableDOMAutomation(); | 635 EnableDOMAutomation(); |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
807 } | 940 } |
808 static void ExpectWindowCountAfterDownload(size_t expected) { | 941 static void ExpectWindowCountAfterDownload(size_t expected) { |
809 #if defined(OS_CHROMEOS) | 942 #if defined(OS_CHROMEOS) |
810 // On ChromeOS, a download panel is created to display | 943 // On ChromeOS, a download panel is created to display |
811 // download information, and this counts as a window. | 944 // download information, and this counts as a window. |
812 expected++; | 945 expected++; |
813 #endif | 946 #endif |
814 EXPECT_EQ(expected, BrowserList::size()); | 947 EXPECT_EQ(expected, BrowserList::size()); |
815 } | 948 } |
816 | 949 |
| 950 // Arrange for select file calls on the given browser from the |
| 951 // download manager to always choose the suggested file. |
| 952 void NullSelectFile(Browser* browser) { |
| 953 PickSuggestedFileDelegate* new_delegate = |
| 954 new PickSuggestedFileDelegate(browser->profile()); |
| 955 |
| 956 DownloadManager* manager = browser->profile()->GetDownloadManager(); |
| 957 |
| 958 new_delegate->SetDownloadManager(manager); |
| 959 manager->set_delegate(new_delegate); |
| 960 |
| 961 // Gives ownership to Profile. |
| 962 browser->profile()->SetDownloadManagerDelegate(new_delegate); |
| 963 } |
| 964 |
817 private: | 965 private: |
818 // Location of the test data. | 966 // Location of the test data. |
819 FilePath test_dir_; | 967 FilePath test_dir_; |
820 | 968 |
821 // Location of the downloads directory for these tests | 969 // Location of the downloads directory for these tests |
822 ScopedTempDir downloads_directory_; | 970 ScopedTempDir downloads_directory_; |
823 }; | 971 }; |
824 | 972 |
825 // Get History Information. | |
826 class DownloadsHistoryDataCollector { | |
827 public: | |
828 DownloadsHistoryDataCollector(int64 download_db_handle, | |
829 DownloadManager* manager) | |
830 : result_valid_(false), | |
831 download_db_handle_(download_db_handle) { | |
832 HistoryService* hs = | |
833 Profile::FromBrowserContext(manager->browser_context())-> | |
834 GetHistoryService(Profile::EXPLICIT_ACCESS); | |
835 DCHECK(hs); | |
836 hs->QueryDownloads( | |
837 &callback_consumer_, | |
838 NewCallback(this, | |
839 &DownloadsHistoryDataCollector::OnQueryDownloadsComplete)); | |
840 | |
841 // Cannot complete immediately because the history backend runs on a | |
842 // separate thread, so we can assume that the RunMessageLoop below will | |
843 // be exited by the Quit in OnQueryDownloadsComplete. | |
844 ui_test_utils::RunMessageLoop(); | |
845 } | |
846 | |
847 bool GetDownloadsHistoryEntry(DownloadPersistentStoreInfo* result) { | |
848 DCHECK(result); | |
849 *result = result_; | |
850 return result_valid_; | |
851 } | |
852 | |
853 private: | |
854 void OnQueryDownloadsComplete( | |
855 std::vector<DownloadPersistentStoreInfo>* entries) { | |
856 result_valid_ = false; | |
857 for (std::vector<DownloadPersistentStoreInfo>::const_iterator it = | |
858 entries->begin(); | |
859 it != entries->end(); ++it) { | |
860 if (it->db_handle == download_db_handle_) { | |
861 result_ = *it; | |
862 result_valid_ = true; | |
863 } | |
864 } | |
865 MessageLoopForUI::current()->Quit(); | |
866 } | |
867 | |
868 DownloadPersistentStoreInfo result_; | |
869 bool result_valid_; | |
870 int64 download_db_handle_; | |
871 CancelableRequestConsumer callback_consumer_; | |
872 | |
873 DISALLOW_COPY_AND_ASSIGN(DownloadsHistoryDataCollector); | |
874 }; | |
875 | |
876 // Mock that simulates a permissions dialog where the user denies | |
877 // permission to install. TODO(skerner): This could be shared with | |
878 // extensions tests. Find a common place for this class. | |
879 class MockAbortExtensionInstallUI : public ExtensionInstallUI { | |
880 public: | |
881 MockAbortExtensionInstallUI() : ExtensionInstallUI(NULL) {} | |
882 | |
883 // Simulate a user abort on an extension installation. | |
884 virtual void ConfirmInstall(Delegate* delegate, const Extension* extension) { | |
885 delegate->InstallUIAbort(true); | |
886 MessageLoopForUI::current()->Quit(); | |
887 } | |
888 | |
889 virtual void OnInstallSuccess(const Extension* extension, SkBitmap* icon) {} | |
890 virtual void OnInstallFailure(const std::string& error) {} | |
891 }; | |
892 | |
893 // Mock that simulates a permissions dialog where the user allows | |
894 // installation. | |
895 class MockAutoConfirmExtensionInstallUI : public ExtensionInstallUI { | |
896 public: | |
897 explicit MockAutoConfirmExtensionInstallUI(Profile* profile) | |
898 : ExtensionInstallUI(profile) {} | |
899 | |
900 // Proceed without confirmation prompt. | |
901 virtual void ConfirmInstall(Delegate* delegate, const Extension* extension) { | |
902 delegate->InstallUIProceed(); | |
903 } | |
904 | |
905 virtual void OnInstallSuccess(const Extension* extension, SkBitmap* icon) {} | |
906 virtual void OnInstallFailure(const std::string& error) {} | |
907 }; | |
908 | |
909 } // namespace | |
910 | |
911 // While an object of this class exists, it will mock out download | |
912 // opening for all downloads created on the specified download manager. | |
913 class MockDownloadOpeningObserver : public DownloadManager::Observer { | |
914 public: | |
915 explicit MockDownloadOpeningObserver(DownloadManager* manager) | |
916 : download_manager_(manager) { | |
917 download_manager_->AddObserver(this); | |
918 } | |
919 | |
920 ~MockDownloadOpeningObserver() { | |
921 download_manager_->RemoveObserver(this); | |
922 } | |
923 | |
924 // DownloadManager::Observer | |
925 virtual void ModelChanged() { | |
926 std::vector<DownloadItem*> downloads; | |
927 download_manager_->SearchDownloads(string16(), &downloads); | |
928 | |
929 for (std::vector<DownloadItem*>::iterator it = downloads.begin(); | |
930 it != downloads.end(); ++it) { | |
931 (*it)->TestMockDownloadOpen(); | |
932 } | |
933 } | |
934 | |
935 private: | |
936 DownloadManager* download_manager_; | |
937 | |
938 DISALLOW_COPY_AND_ASSIGN(MockDownloadOpeningObserver); | |
939 }; | |
940 | |
941 // NOTES: | 973 // NOTES: |
942 // | 974 // |
943 // Files for these tests are found in DIR_TEST_DATA (currently | 975 // Files for these tests are found in DIR_TEST_DATA (currently |
944 // "chrome\test\data\", see chrome_paths.cc). | 976 // "chrome\test\data\", see chrome_paths.cc). |
945 // Mock responses have extension .mock-http-headers appended to the file name. | 977 // Mock responses have extension .mock-http-headers appended to the file name. |
946 | 978 |
947 // Download a file due to the associated MIME type. | 979 // Download a file due to the associated MIME type. |
948 IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadMimeType) { | 980 IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadMimeType) { |
949 ASSERT_TRUE(InitialSetup(false)); | 981 ASSERT_TRUE(InitialSetup(false)); |
950 FilePath file(FILE_PATH_LITERAL("download-test1.lib")); | 982 FilePath file(FILE_PATH_LITERAL("download-test1.lib")); |
(...skipping 23 matching lines...) Expand all Loading... |
974 // as CheckDownload will delete the output file. | 1006 // as CheckDownload will delete the output file. |
975 EXPECT_EQ(1, browser()->tab_count()); | 1007 EXPECT_EQ(1, browser()->tab_count()); |
976 FilePath downloaded_file(DestinationFile(browser(), file)); | 1008 FilePath downloaded_file(DestinationFile(browser(), file)); |
977 if (file_util::VolumeSupportsADS(downloaded_file)) | 1009 if (file_util::VolumeSupportsADS(downloaded_file)) |
978 EXPECT_TRUE(file_util::HasInternetZoneIdentifier(downloaded_file)); | 1010 EXPECT_TRUE(file_util::HasInternetZoneIdentifier(downloaded_file)); |
979 CheckDownload(browser(), file, file); | 1011 CheckDownload(browser(), file, file); |
980 CheckDownloadUI(browser(), true, true, file); | 1012 CheckDownloadUI(browser(), true, true, file); |
981 } | 1013 } |
982 #endif | 1014 #endif |
983 | 1015 |
984 // Put up a Select File dialog when the file is downloaded, due to its MIME | 1016 // Put up a Select File dialog when the file is downloaded, due to |
985 // type. | 1017 // downloads preferences settings. |
986 // | 1018 IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadMimeTypeSelect) { |
987 // This test runs correctly, but leaves behind turds in the test user's | |
988 // download directory because of http://crbug.com/62099. No big loss; it | |
989 // was primarily confirming DownloadsObserver wait on select file dialog | |
990 // functionality anyway. | |
991 IN_PROC_BROWSER_TEST_F(DownloadTest, DISABLED_DownloadMimeTypeSelect) { | |
992 ASSERT_TRUE(InitialSetup(true)); | 1019 ASSERT_TRUE(InitialSetup(true)); |
993 FilePath file(FILE_PATH_LITERAL("download-test1.lib")); | 1020 FilePath file(FILE_PATH_LITERAL("download-test1.lib")); |
994 GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); | 1021 GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); |
995 | 1022 |
| 1023 NullSelectFile(browser()); |
| 1024 |
996 // Download the file and wait. We expect the Select File dialog to appear | 1025 // Download the file and wait. We expect the Select File dialog to appear |
997 // due to the MIME type. | 1026 // due to the MIME type, but we still wait until the download completes. |
998 DownloadAndWait(browser(), url, EXPECT_SELECT_DIALOG); | 1027 scoped_ptr<DownloadsObserver> observer( |
| 1028 new DownloadsObserver( |
| 1029 browser()->profile()->GetDownloadManager(), |
| 1030 1, |
| 1031 DownloadItem::COMPLETE, // Really done |
| 1032 false, // Continue on select file. |
| 1033 ON_DANGEROUS_DOWNLOAD_FAIL)); |
| 1034 ui_test_utils::NavigateToURLWithDisposition( |
| 1035 browser(), url, CURRENT_TAB, |
| 1036 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
| 1037 observer->WaitForFinished(); |
| 1038 EXPECT_TRUE(observer->select_file_dialog_seen()); |
999 | 1039 |
1000 // Check state. | 1040 // Check state. |
1001 EXPECT_EQ(1, browser()->tab_count()); | 1041 EXPECT_EQ(1, browser()->tab_count()); |
1002 // Since we exited while the Select File dialog was visible, there should not | 1042 CheckDownload(browser(), file, file); |
1003 // be anything in the download shelf and so it should not be visible. | 1043 CheckDownloadUI(browser(), true, true, file); |
1004 CheckDownloadUI(browser(), false, false, FilePath()); | |
1005 } | 1044 } |
1006 | 1045 |
1007 // Access a file with a viewable mime-type, verify that a download | 1046 // Access a file with a viewable mime-type, verify that a download |
1008 // did not initiate. | 1047 // did not initiate. |
1009 IN_PROC_BROWSER_TEST_F(DownloadTest, NoDownload) { | 1048 IN_PROC_BROWSER_TEST_F(DownloadTest, NoDownload) { |
1010 ASSERT_TRUE(InitialSetup(false)); | 1049 ASSERT_TRUE(InitialSetup(false)); |
1011 FilePath file(FILE_PATH_LITERAL("download-test2.html")); | 1050 FilePath file(FILE_PATH_LITERAL("download-test2.html")); |
1012 GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); | 1051 GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); |
1013 FilePath file_path(DestinationFile(browser(), file)); | 1052 FilePath file_path(DestinationFile(browser(), file)); |
1014 | 1053 |
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1731 EXPECT_EQ(1u, observer->NumDangerousDownloadsSeen()); | 1770 EXPECT_EQ(1u, observer->NumDangerousDownloadsSeen()); |
1732 | 1771 |
1733 // Download shelf should close. Download panel stays open on ChromeOS. | 1772 // Download shelf should close. Download panel stays open on ChromeOS. |
1734 CheckDownloadUI(browser(), false, true, FilePath()); | 1773 CheckDownloadUI(browser(), false, true, FilePath()); |
1735 | 1774 |
1736 // Check that the extension was installed. | 1775 // Check that the extension was installed. |
1737 ExtensionService* extension_service = | 1776 ExtensionService* extension_service = |
1738 browser()->profile()->GetExtensionService(); | 1777 browser()->profile()->GetExtensionService(); |
1739 ASSERT_TRUE(extension_service->GetExtensionById(kLargeThemeCrxId, false)); | 1778 ASSERT_TRUE(extension_service->GetExtensionById(kLargeThemeCrxId, false)); |
1740 } | 1779 } |
OLD | NEW |