Chromium Code Reviews| Index: chrome/browser/download/download_browsertest.cc |
| diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc |
| index 5248ecb403d6ac37f38e01a8171da31e3bce596b..fc3638daa6777088512d1b825d1623fe10f9ec40 100644 |
| --- a/chrome/browser/download/download_browsertest.cc |
| +++ b/chrome/browser/download/download_browsertest.cc |
| @@ -56,6 +56,7 @@ const FilePath kLargeThemePath(FILE_PATH_LITERAL("extensions/theme2.crx")); |
| enum DangerousDownloadAction { |
| ON_DANGEROUS_DOWNLOAD_ACCEPT, // Accept the download |
| ON_DANGEROUS_DOWNLOAD_DENY, // Deny the download |
| + ON_DANGEROUS_DOWNLOAD_IGNORE, // Don't do anything; calling code will handle. |
| ON_DANGEROUS_DOWNLOAD_FAIL // Fail if a dangerous download is seen |
| }; |
| @@ -71,7 +72,7 @@ void DenyDangerousDownload(scoped_refptr<DownloadManager> download_manager, |
| int32 download_id) { |
| DownloadItem* download = download_manager->GetDownloadItem(download_id); |
| ASSERT_TRUE(download->IsPartialDownload()); |
| - download->Cancel(true); |
| + download->Cancel(); |
| download->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD); |
| } |
| @@ -90,8 +91,10 @@ void DenyDangerousDownload(scoped_refptr<DownloadManager> download_manager, |
| class DownloadsObserver : public DownloadManager::Observer, |
| public DownloadItem::Observer { |
| public: |
| + typedef std::set<DownloadItem::DownloadState> StateSet; |
| + |
| // Create an object that will be considered finished when |wait_count| |
| - // download items have entered state |download_finished_state|. |
| + // download items have entered any states in |download_finished_states|. |
| // If |finish_on_select_file| is true, the object will also be |
| // considered finished if the DownloadManager raises a |
| // SelectFileDialogDisplayed() notification. |
| @@ -100,20 +103,21 @@ class DownloadsObserver : public DownloadManager::Observer, |
| // to treat as completion events. |
| DownloadsObserver(DownloadManager* download_manager, |
| size_t wait_count, |
| - DownloadItem::DownloadState download_finished_state, |
| + StateSet download_finished_states, |
| bool finish_on_select_file, |
| DangerousDownloadAction dangerous_download_action) |
| : download_manager_(download_manager), |
| wait_count_(wait_count), |
| finished_downloads_at_construction_(0), |
| waiting_(false), |
| - download_finished_state_(download_finished_state), |
| + download_finished_states_(download_finished_states), |
| finish_on_select_file_(finish_on_select_file), |
| select_file_dialog_seen_(false), |
| dangerous_download_action_(dangerous_download_action) { |
| download_manager_->AddObserver(this); // Will call initial ModelChanged(). |
| finished_downloads_at_construction_ = finished_downloads_.size(); |
| - EXPECT_NE(DownloadItem::REMOVING, download_finished_state) |
| + EXPECT_TRUE(download_finished_states.find(DownloadItem::REMOVING) == |
| + download_finished_states.end()) |
| << "Waiting for REMOVING is not supported. Try COMPLETE."; |
| } |
| @@ -192,12 +196,16 @@ class DownloadsObserver : public DownloadManager::Observer, |
| ADD_FAILURE() << "Unexpected dangerous download item."; |
| break; |
| + case ON_DANGEROUS_DOWNLOAD_IGNORE: |
| + break; |
| + |
| default: |
| NOTREACHED(); |
| } |
| } |
| - if (download->state() == download_finished_state_) { |
| + if (download_finished_states_.find(download->state()) != |
| + download_finished_states_.end()) { |
| DownloadInFinalState(download); |
| } |
| } |
| @@ -300,8 +308,8 @@ class DownloadsObserver : public DownloadManager::Observer, |
| // all downloads completing. |
| bool waiting_; |
| - // The state on which to consider the DownloadItem finished. |
| - DownloadItem::DownloadState download_finished_state_; |
| + // The states on which to consider the DownloadItem finished. |
| + StateSet download_finished_states_; |
| // True if we should transition the DownloadsObserver to finished if |
| // the select file dialog comes up. |
| @@ -489,6 +497,132 @@ class CancelTestDataCollector |
| DISALLOW_COPY_AND_ASSIGN(CancelTestDataCollector); |
| }; |
| +static const DownloadItem::DownloadState kTerminalStates[] = { |
| + DownloadItem::CANCELLED, |
| + DownloadItem::INTERRUPTED, |
| + DownloadItem::COMPLETE, |
| +}; |
| + |
| +static const DownloadItem::DownloadState kInProgressStates[] = { |
| + DownloadItem::IN_PROGRESS, |
| +}; |
| + |
| +// Get History Information. |
| +class DownloadsHistoryDataCollector { |
| + public: |
| + explicit DownloadsHistoryDataCollector(int64 download_db_handle, |
| + DownloadManager* manager) |
| + : result_valid_(false), |
| + download_db_handle_(download_db_handle) { |
| + HistoryService* hs = |
|
ahendrickson
2011/07/11 20:05:48
DCHECK(manager)
Randy Smith (Not in Mondays)
2011/07/13 21:11:38
Done.
|
| + manager->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS); |
| + DCHECK(hs); |
| + hs->QueryDownloads( |
| + &callback_consumer_, |
| + NewCallback(this, |
| + &DownloadsHistoryDataCollector::OnQueryDownloadsComplete)); |
| + |
| + // Cannot complete immediately because the history backend runs on a |
| + // separate thread, so we can assume that the RunMessageLoop below will |
| + // be exited by the Quit in OnQueryDownloadsComplete. |
| + ui_test_utils::RunMessageLoop(); |
| + } |
| + |
| + bool GetDownloadsHistoryEntry(DownloadHistoryInfo* result) { |
| + DCHECK(result); |
| + *result = result_; |
| + return result_valid_; |
| + } |
| + |
| + private: |
| + void OnQueryDownloadsComplete( |
| + std::vector<DownloadHistoryInfo>* entries) { |
| + result_valid_ = false; |
| + for (std::vector<DownloadHistoryInfo>::const_iterator it = entries->begin(); |
| + it != entries->end(); ++it) { |
| + if (it->db_handle == download_db_handle_) { |
| + result_ = *it; |
| + result_valid_ = true; |
|
ahendrickson
2011/07/11 20:05:48
Add a break statement after this line?
Randy Smith (Not in Mondays)
2011/07/13 21:11:38
Done.
|
| + } |
| + } |
| + MessageLoopForUI::current()->Quit(); |
| + } |
| + |
| + DownloadHistoryInfo result_; |
| + bool result_valid_; |
| + int64 download_db_handle_; |
| + CancelableRequestConsumer callback_consumer_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(DownloadsHistoryDataCollector); |
| +}; |
| + |
| +// Mock that simulates a permissions dialog where the user denies |
| +// permission to install. TODO(skerner): This could be shared with |
| +// extensions tests. Find a common place for this class. |
| +class MockAbortExtensionInstallUI : public ExtensionInstallUI { |
| + public: |
| + MockAbortExtensionInstallUI() : ExtensionInstallUI(NULL) {} |
| + |
| + // Simulate a user abort on an extension installation. |
| + virtual void ConfirmInstall(Delegate* delegate, const Extension* extension) { |
| + delegate->InstallUIAbort(true); |
| + MessageLoopForUI::current()->Quit(); |
| + } |
| + |
| + virtual void OnInstallSuccess(const Extension* extension, SkBitmap* icon) {} |
| + virtual void OnInstallFailure(const std::string& error) {} |
| +}; |
| + |
| +// Mock that simulates a permissions dialog where the user allows |
| +// installation. |
| +class MockAutoConfirmExtensionInstallUI : public ExtensionInstallUI { |
| + public: |
| + explicit MockAutoConfirmExtensionInstallUI(Profile* profile) : |
| + ExtensionInstallUI(profile) {} |
| + |
| + // Proceed without confirmation prompt. |
| + virtual void ConfirmInstall(Delegate* delegate, const Extension* extension) { |
| + delegate->InstallUIProceed(); |
| + } |
| + |
| + virtual void OnInstallSuccess(const Extension* extension, SkBitmap* icon) {} |
| + virtual void OnInstallFailure(const std::string& error) {} |
| +}; |
| + |
| +// While an object of this class exists, it will mock out download |
| +// opening for all downloads created on the specified download manager. |
|
ahendrickson
2011/07/11 20:05:48
This can't be used twice in a row, right? For the
Randy Smith (Not in Mondays)
2011/07/13 21:11:38
Not quite--if there are *any* instances of this cl
|
| +class MockDownloadOpeningObserver : public DownloadManager::Observer { |
| + public: |
| + explicit MockDownloadOpeningObserver(DownloadManager* manager) |
| + : download_manager_(manager) { |
| + download_manager_->AddObserver(this); |
| + } |
| + |
| + ~MockDownloadOpeningObserver() { |
| + download_manager_->RemoveObserver(this); |
| + } |
| + |
| + // DownloadManager::Observer |
| + virtual void ModelChanged() { |
| + std::vector<DownloadItem*> downloads; |
| + download_manager_->SearchDownloads(string16(), &downloads); |
| + |
| + for (std::vector<DownloadItem*>::iterator it = downloads.begin(); |
| + it != downloads.end(); ++it) { |
| + (*it)->TestMockDownloadOpen(); |
| + } |
| + } |
| + |
| + private: |
| + DownloadManager* download_manager_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(MockDownloadOpeningObserver); |
| +}; |
| + |
| +} // namespace |
| + |
| +// Not in anonymous namespace so that friend class from DownloadManager |
| +// can target it. |
| class DownloadTest : public InProcessBrowserTest { |
| public: |
| enum SelectExpectation { |
| @@ -565,6 +699,12 @@ class DownloadTest : public InProcessBrowserTest { |
| return true; |
| } |
| + // For tests that want to test system reaction to files |
| + // going away underneath them. |
| + void DeleteDownloadsDirectory() { |
| + EXPECT_TRUE(downloads_directory_.Delete()); |
| + } |
| + |
| DownloadPrefs* GetDownloadPrefs(Browser* browser) { |
| return browser->profile()->GetDownloadManager()->download_prefs(); |
| } |
| @@ -582,12 +722,29 @@ class DownloadTest : public InProcessBrowserTest { |
| browser->profile()->GetDownloadManager(); |
| return new DownloadsObserver( |
| download_manager, num_downloads, |
| - DownloadItem::COMPLETE, // Really done |
| - false, // Bail on select file |
| + DownloadsObserver::StateSet( |
| + kTerminalStates, kTerminalStates + arraysize(kTerminalStates)), |
| + true, // Bail on select file |
| ON_DANGEROUS_DOWNLOAD_FAIL); |
| } |
| // Create a DownloadsObserver that will wait for the |
| + // specified number of downloads to finish, and is |
| + // ok with dangerous downloads. Note that use of this |
| + // waiter is conditional on accepting the dangerous download. |
| + DownloadsObserver* CreateDangerousWaiter( |
| + Browser* browser, int num_downloads) { |
| + DownloadManager* download_manager = |
| + browser->profile()->GetDownloadManager(); |
| + return new DownloadsObserver( |
| + download_manager, num_downloads, |
| + DownloadsObserver::StateSet( |
| + kTerminalStates, kTerminalStates + arraysize(kTerminalStates)), |
| + true, // Bail on select file |
| + ON_DANGEROUS_DOWNLOAD_IGNORE); |
| + } |
| + |
| + // Create a DownloadsObserver that will wait for the |
| // specified number of downloads to start. |
| DownloadsObserver* CreateInProgressWaiter(Browser* browser, |
| int num_downloads) { |
| @@ -595,9 +752,11 @@ class DownloadTest : public InProcessBrowserTest { |
| browser->profile()->GetDownloadManager(); |
| return new DownloadsObserver( |
| download_manager, num_downloads, |
| - DownloadItem::IN_PROGRESS, // Has started |
| + DownloadsObserver::StateSet( |
| + kInProgressStates, |
| + kInProgressStates + arraysize(kInProgressStates)), |
| true, // Bail on select file |
| - ON_DANGEROUS_DOWNLOAD_FAIL); |
| + ON_DANGEROUS_DOWNLOAD_IGNORE); |
| } |
| // Create a DownloadsObserver that will wait for the |
| @@ -608,11 +767,13 @@ class DownloadTest : public InProcessBrowserTest { |
| int num_downloads, |
| DownloadItem::DownloadState final_state, |
| DangerousDownloadAction dangerous_download_action) { |
| + DownloadsObserver::StateSet states; |
| + states.insert(final_state); |
| DownloadManager* download_manager = |
| browser->profile()->GetDownloadManager(); |
| return new DownloadsObserver( |
| download_manager, num_downloads, |
| - final_state, |
| + states, |
| true, // Bail on select file |
| dangerous_download_action); |
| } |
| @@ -767,12 +928,22 @@ class DownloadTest : public InProcessBrowserTest { |
| return true; |
| } |
| - void GetDownloads(Browser* browser, std::vector<DownloadItem*>* downloads) { |
| + void GetPersistentDownloads(Browser* browser, |
| + std::vector<DownloadItem*>* downloads) { |
| DCHECK(downloads); |
| + downloads->clear(); |
| DownloadManager* manager = browser->profile()->GetDownloadManager(); |
| manager->SearchDownloads(string16(), downloads); |
| } |
| + void GetInProgressDownloads(Browser* browser, |
| + std::vector<DownloadItem*>* downloads) { |
| + downloads->clear(); |
| + DCHECK(downloads); |
| + DownloadManager* manager = browser->profile()->GetDownloadManager(); |
| + manager->GetInProgressDownloads(downloads); |
| + } |
| + |
| // Check that the download UI (shelf on non-chromeos or panel on chromeos) |
| // is visible or not as expected. Additionally, check that the filename |
| // is present in the UI (currently only on chromeos). |
| @@ -822,120 +993,6 @@ class DownloadTest : public InProcessBrowserTest { |
| ScopedTempDir downloads_directory_; |
| }; |
| -// Get History Information. |
| -class DownloadsHistoryDataCollector { |
| - public: |
| - explicit DownloadsHistoryDataCollector(int64 download_db_handle, |
| - DownloadManager* manager) |
| - : result_valid_(false), |
| - download_db_handle_(download_db_handle) { |
| - HistoryService* hs = |
| - manager->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS); |
| - DCHECK(hs); |
| - hs->QueryDownloads( |
| - &callback_consumer_, |
| - NewCallback(this, |
| - &DownloadsHistoryDataCollector::OnQueryDownloadsComplete)); |
| - |
| - // Cannot complete immediately because the history backend runs on a |
| - // separate thread, so we can assume that the RunMessageLoop below will |
| - // be exited by the Quit in OnQueryDownloadsComplete. |
| - ui_test_utils::RunMessageLoop(); |
| - } |
| - |
| - bool GetDownloadsHistoryEntry(DownloadHistoryInfo* result) { |
| - DCHECK(result); |
| - *result = result_; |
| - return result_valid_; |
| - } |
| - |
| - private: |
| - void OnQueryDownloadsComplete( |
| - std::vector<DownloadHistoryInfo>* entries) { |
| - result_valid_ = false; |
| - for (std::vector<DownloadHistoryInfo>::const_iterator it = entries->begin(); |
| - it != entries->end(); ++it) { |
| - if (it->db_handle == download_db_handle_) { |
| - result_ = *it; |
| - result_valid_ = true; |
| - } |
| - } |
| - MessageLoopForUI::current()->Quit(); |
| - } |
| - |
| - DownloadHistoryInfo result_; |
| - bool result_valid_; |
| - int64 download_db_handle_; |
| - CancelableRequestConsumer callback_consumer_; |
| - |
| - DISALLOW_COPY_AND_ASSIGN(DownloadsHistoryDataCollector); |
| -}; |
| - |
| -// Mock that simulates a permissions dialog where the user denies |
| -// permission to install. TODO(skerner): This could be shared with |
| -// extensions tests. Find a common place for this class. |
| -class MockAbortExtensionInstallUI : public ExtensionInstallUI { |
| - public: |
| - MockAbortExtensionInstallUI() : ExtensionInstallUI(NULL) {} |
| - |
| - // Simulate a user abort on an extension installation. |
| - virtual void ConfirmInstall(Delegate* delegate, const Extension* extension) { |
| - delegate->InstallUIAbort(true); |
| - MessageLoopForUI::current()->Quit(); |
| - } |
| - |
| - virtual void OnInstallSuccess(const Extension* extension, SkBitmap* icon) {} |
| - virtual void OnInstallFailure(const std::string& error) {} |
| -}; |
| - |
| -// Mock that simulates a permissions dialog where the user allows |
| -// installation. |
| -class MockAutoConfirmExtensionInstallUI : public ExtensionInstallUI { |
| - public: |
| - explicit MockAutoConfirmExtensionInstallUI(Profile* profile) : |
| - ExtensionInstallUI(profile) {} |
| - |
| - // Proceed without confirmation prompt. |
| - virtual void ConfirmInstall(Delegate* delegate, const Extension* extension) { |
| - delegate->InstallUIProceed(); |
| - } |
| - |
| - virtual void OnInstallSuccess(const Extension* extension, SkBitmap* icon) {} |
| - virtual void OnInstallFailure(const std::string& error) {} |
| -}; |
| - |
| -} // namespace |
| - |
| -// While an object of this class exists, it will mock out download |
| -// opening for all downloads created on the specified download manager. |
| -class MockDownloadOpeningObserver : public DownloadManager::Observer { |
| - public: |
| - explicit MockDownloadOpeningObserver(DownloadManager* manager) |
| - : download_manager_(manager) { |
| - download_manager_->AddObserver(this); |
| - } |
| - |
| - ~MockDownloadOpeningObserver() { |
| - download_manager_->RemoveObserver(this); |
| - } |
| - |
| - // DownloadManager::Observer |
| - virtual void ModelChanged() { |
| - std::vector<DownloadItem*> downloads; |
| - download_manager_->SearchDownloads(string16(), &downloads); |
| - |
| - for (std::vector<DownloadItem*>::iterator it = downloads.begin(); |
| - it != downloads.end(); ++it) { |
| - (*it)->TestMockDownloadOpen(); |
| - } |
| - } |
| - |
| - private: |
| - DownloadManager* download_manager_; |
| - |
| - DISALLOW_COPY_AND_ASSIGN(MockDownloadOpeningObserver); |
| -}; |
| - |
| // NOTES: |
| // |
| // Files for these tests are found in DIR_TEST_DATA (currently |
| @@ -979,21 +1036,104 @@ IN_PROC_BROWSER_TEST_F(DownloadTest, CheckInternetZone) { |
| } |
| #endif |
| -// Put up a Select File dialog when the file is downloaded, due to its MIME |
| -// type. |
| -// |
| -// This test runs correctly, but leaves behind turds in the test user's |
| -// download directory because of http://crbug.com/62099. No big loss; it |
| -// was primarily confirming DownloadsObserver wait on select file dialog |
| -// functionality anyway. |
| -IN_PROC_BROWSER_TEST_F(DownloadTest, DISABLED_DownloadMimeTypeSelect) { |
| +// Put up a Select File dialog when the file is downloaded, due to |
| +// prompt_for_download==true argument to InitialSetup(). |
| +// Confirm that we can cancel the download in that state. |
| +IN_PROC_BROWSER_TEST_F(DownloadTest, CancelFromFileSelection) { |
| ASSERT_TRUE(InitialSetup(true)); |
| FilePath file(FILE_PATH_LITERAL("download-test1.lib")); |
| GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); |
| - // Download the file and wait. We expect the Select File dialog to appear |
| - // due to the MIME type. |
| + // Download the file and wait. We expect the Select File dialog to appear. |
| DownloadAndWait(browser(), url, EXPECT_SELECT_DIALOG); |
| + // To allow Select File dialog to be fully raised. |
| + MessageLoopForUI::current()->RunAllPending(); |
| + |
| + std::vector<DownloadItem*> active_downloads, history_downloads; |
| + GetInProgressDownloads(browser(), &active_downloads); |
| + ASSERT_EQ(1u, active_downloads.size()); |
| + EXPECT_EQ(DownloadItem::IN_PROGRESS, active_downloads[0]->state()); |
| + GetPersistentDownloads(browser(), &history_downloads); |
| + EXPECT_EQ(0u, history_downloads.size()); |
| + |
| + // This should remove the download as it hasn't yet been entered into |
| + // the history. |
| + active_downloads[0]->Cancel(); |
| + |
| + GetInProgressDownloads(browser(), &active_downloads); |
| + EXPECT_EQ(0u, active_downloads.size()); |
| + GetPersistentDownloads(browser(), &history_downloads); |
| + EXPECT_EQ(0u, history_downloads.size()); |
| + |
| + // Check state. |
| + EXPECT_EQ(1, browser()->tab_count()); |
| + // Since we exited while the Select File dialog was visible, there should not |
| + // be anything in the download shelf and so it should not be visible. |
| + CheckDownloadUI(browser(), false, false, FilePath()); |
| +} |
| + |
| +// Put up a Select File dialog when the file is downloaded, due to |
| +// prompt_for_download==true argument to InitialSetup(). |
| +// Confirm that we can remove the download in that state. |
| +IN_PROC_BROWSER_TEST_F(DownloadTest, RemoveFromFileSelection) { |
| + ASSERT_TRUE(InitialSetup(true)); |
| + FilePath file(FILE_PATH_LITERAL("download-test1.lib")); |
| + GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); |
| + |
| + // Download the file and wait. We expect the Select File dialog to appear. |
| + DownloadAndWait(browser(), url, EXPECT_SELECT_DIALOG); |
| + |
| + std::vector<DownloadItem*> active_downloads, history_downloads; |
| + GetInProgressDownloads(browser(), &active_downloads); |
| + ASSERT_EQ(1u, active_downloads.size()); |
| + EXPECT_EQ(DownloadItem::IN_PROGRESS, active_downloads[0]->state()); |
| + GetPersistentDownloads(browser(), &history_downloads); |
| + EXPECT_EQ(0u, history_downloads.size()); |
| + |
| + // Confirm the file can be successfully removed from the select file |
| + // dialog blocked state. |
| + active_downloads[0]->Remove(); |
| + |
| + GetInProgressDownloads(browser(), &active_downloads); |
| + EXPECT_EQ(0u, active_downloads.size()); |
| + GetPersistentDownloads(browser(), &history_downloads); |
| + EXPECT_EQ(0u, history_downloads.size()); |
| + |
| + EXPECT_EQ(1, browser()->tab_count()); |
| + // Since we exited while the Select File dialog was visible, there should not |
| + // be anything in the download shelf and so it should not be visible. |
| + CheckDownloadUI(browser(), false, false, FilePath()); |
| +} |
| + |
| +// Put up a Select File dialog when the file is downloaded, due to |
| +// prompt_for_download==true argument to InitialSetup(). |
| +// Confirm that an error coming in from the network works properly |
| +// when in that state. |
| +IN_PROC_BROWSER_TEST_F(DownloadTest, InterruptFromFileSelection) { |
| + ASSERT_TRUE(InitialSetup(true)); |
| + GURL url(URLRequestSlowDownloadJob::kKnownSizeUrl); |
| + |
| + // Download the file and wait. We expect the Select File dialog to appear. |
| + DownloadAndWait(browser(), url, EXPECT_SELECT_DIALOG); |
| + |
| + std::vector<DownloadItem*> active_downloads, history_downloads; |
| + GetInProgressDownloads(browser(), &active_downloads); |
| + ASSERT_EQ(1u, active_downloads.size()); |
| + EXPECT_EQ(DownloadItem::IN_PROGRESS, active_downloads[0]->state()); |
| + GetPersistentDownloads(browser(), &history_downloads); |
| + EXPECT_EQ(0u, history_downloads.size()); |
| + |
| + // Complete the download with error. |
| + GURL error_url(URLRequestSlowDownloadJob::kErrorFinishDownloadUrl); |
| + ui_test_utils::NavigateToURL(browser(), error_url); |
| + MessageLoopForUI::current()->RunAllPending(); |
| + |
| + // Confirm that a download error before entry into history |
| + // deletes the download. |
| + GetInProgressDownloads(browser(), &active_downloads); |
| + EXPECT_EQ(0u, active_downloads.size()); |
| + GetPersistentDownloads(browser(), &history_downloads); |
| + EXPECT_EQ(0u, history_downloads.size()); |
| // Check state. |
| EXPECT_EQ(1, browser()->tab_count()); |
| @@ -1430,8 +1570,7 @@ IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadCancelled) { |
| observer->WaitForFinished(); |
| std::vector<DownloadItem*> downloads; |
| - browser()->profile()->GetDownloadManager()->SearchDownloads( |
| - string16(), &downloads); |
| + GetPersistentDownloads(browser(), &downloads); |
| ASSERT_EQ(1u, downloads.size()); |
| ASSERT_EQ(DownloadItem::IN_PROGRESS, downloads[0]->state()); |
| CheckDownloadUI(browser(), true, true, FilePath()); |
| @@ -1454,6 +1593,182 @@ IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadCancelled) { |
| CheckDownloadUI(browser(), false, true, FilePath()); |
| } |
| +// Do a dangerous download and confirm that the download does |
| +// not complete until user accept, and that all states are |
| +// correct along the way. |
| +IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadDangerous) { |
| + ASSERT_TRUE(InitialSetup(false)); |
| + FilePath file(FILE_PATH_LITERAL("download-dangerous.jar")); |
| + GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); |
| + |
| + EXPECT_EQ(1, browser()->tab_count()); |
| + |
| + scoped_ptr<DownloadsObserver> observer( |
| + CreateInProgressWaiter(browser(), 1)); |
| + ui_test_utils::NavigateToURL(browser(), url); |
| + observer->WaitForFinished(); |
| + |
| + // We should have one download, in history, and it should |
| + // still be dangerous. |
| + std::vector<DownloadItem*> downloads; |
| + GetPersistentDownloads(browser(), &downloads); |
| + ASSERT_EQ(1u, downloads.size()); |
| + DownloadItem* download = downloads[0]; |
| + EXPECT_EQ(DownloadItem::IN_PROGRESS, download->state()); |
| + EXPECT_EQ(DownloadItem::DANGEROUS, download->safety_state()); |
| + EXPECT_EQ(DownloadItem::DANGEROUS_FILE, download->GetDangerType()); |
| + // In ChromeOS, popup will be up, but file name will be unrecognizable. |
| + CheckDownloadUI(browser(), true, true, FilePath()); |
| + |
| + // See if accepting completes the download and changes the safety |
| + // state. |
| + scoped_ptr<DownloadsObserver> completion_observer( |
| + CreateDangerousWaiter(browser(), 1)); |
| + AcceptDangerousDownload(browser()->profile()->GetDownloadManager(), |
| + download->id()); |
| + completion_observer->WaitForFinished(); |
| + |
| + GetPersistentDownloads(browser(), &downloads); |
| + ASSERT_EQ(1u, downloads.size()); |
| + ASSERT_EQ(downloads[0], download); |
| + EXPECT_EQ(DownloadItem::COMPLETE, download->state()); |
| + EXPECT_EQ(DownloadItem::DANGEROUS_BUT_VALIDATED, download->safety_state()); |
| + CheckDownloadUI(browser(), true, true, file); |
| +} |
| + |
| +// Confirm that a dangerous download that gets a file error before |
| +// completion ends in the right state (currently cancelled because file |
| +// errors are non-resumable). Note that this is really testing |
| +// to make sure errors from the final rename are propagated properly. |
| +IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadDangerousFileError) { |
| + ASSERT_TRUE(InitialSetup(false)); |
| + FilePath file(FILE_PATH_LITERAL("download-dangerous.jar")); |
| + GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); |
| + |
| + EXPECT_EQ(1, browser()->tab_count()); |
| + |
| + scoped_ptr<DownloadsObserver> observer( |
| + CreateInProgressWaiter(browser(), 1)); |
| + ui_test_utils::NavigateToURL(browser(), url); |
| + observer->WaitForFinished(); |
| + |
| + // We should have one download, in history, and it should |
| + // still be dangerous. |
| + std::vector<DownloadItem*> downloads; |
| + GetPersistentDownloads(browser(), &downloads); |
| + ASSERT_EQ(1u, downloads.size()); |
| + DownloadItem* download = downloads[0]; |
| + EXPECT_EQ(DownloadItem::IN_PROGRESS, download->state()); |
| + EXPECT_EQ(DownloadItem::DANGEROUS, download->safety_state()); |
| + EXPECT_EQ(DownloadItem::DANGEROUS_FILE, download->GetDangerType()); |
| + // In ChromeOS, popup will be up, but file name will be unrecognizable. |
| + CheckDownloadUI(browser(), true, true, FilePath()); |
| + |
| + // Accept it after nuking the directory into which it's being downloaded; |
| + // that should complete the download with an error. |
| + DeleteDownloadsDirectory(); |
| + scoped_ptr<DownloadsObserver> completion_observer( |
| + CreateDangerousWaiter(browser(), 1)); |
| + AcceptDangerousDownload(browser()->profile()->GetDownloadManager(), |
| + download->id()); |
| + completion_observer->WaitForFinished(); |
| + |
| + GetPersistentDownloads(browser(), &downloads); |
| + ASSERT_EQ(1u, downloads.size()); |
| + ASSERT_EQ(downloads[0], download); |
| + // Persistent errors currently -> CANCELLED. |
| + EXPECT_EQ(DownloadItem::CANCELLED, download->state()); |
| + EXPECT_EQ(DownloadItem::DANGEROUS_BUT_VALIDATED, download->safety_state()); |
| + // In ChromeOS, popup will still be up, but the file will have been |
| + // deleted. |
| + CheckDownloadUI(browser(), true, true, FilePath()); |
| +} |
| + |
| +// Confirm that declining a dangerous download erases it from living memory. |
| +IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadDangerousDecline) { |
| + ASSERT_TRUE(InitialSetup(false)); |
| + FilePath file(FILE_PATH_LITERAL("download-dangerous.jar")); |
| + GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); |
| + |
| + EXPECT_EQ(1, browser()->tab_count()); |
| + |
| + scoped_ptr<DownloadsObserver> observer( |
| + CreateInProgressWaiter(browser(), 1)); |
| + ui_test_utils::NavigateToURL(browser(), url); |
| + observer->WaitForFinished(); |
| + |
| + // We should have one download, in history, and it should |
| + // still be dangerous. |
| + std::vector<DownloadItem*> downloads; |
| + GetPersistentDownloads(browser(), &downloads); |
| + ASSERT_EQ(1u, downloads.size()); |
| + DownloadItem* download = downloads[0]; |
| + EXPECT_EQ(DownloadItem::IN_PROGRESS, download->state()); |
| + EXPECT_EQ(DownloadItem::DANGEROUS, download->safety_state()); |
| + EXPECT_EQ(DownloadItem::DANGEROUS_FILE, download->GetDangerType()); |
| + CheckDownloadUI(browser(), true, true, file); |
| + |
| + DenyDangerousDownload(browser()->profile()->GetDownloadManager(), |
| + download->id()); |
| + |
| + GetPersistentDownloads(browser(), &downloads); |
| + ASSERT_EQ(0u, downloads.size()); |
| + CheckDownloadUI(browser(), false, true, FilePath()); |
| +} |
| + |
| +// Fail a download with a network error partway through, and make sure the |
| +// state is INTERRUPTED and the error is propagated. |
| +IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadInterrupted) { |
| + ASSERT_TRUE(InitialSetup(false)); |
| + GURL url(URLRequestSlowDownloadJob::kKnownSizeUrl); |
| + |
| + scoped_ptr<DownloadsObserver> observer( |
| + CreateInProgressWaiter(browser(), 1)); |
| + ui_test_utils::NavigateToURL(browser(), url); |
| + observer->WaitForFinished(); |
| + |
| + std::vector<DownloadItem*> downloads; |
| + GetPersistentDownloads(browser(), &downloads); |
| + ASSERT_EQ(1u, downloads.size()); |
| + ASSERT_EQ(DownloadItem::IN_PROGRESS, downloads[0]->state()); |
| + FilePath filename; |
| + net::FileURLToFilePath(url, &filename); |
| + CheckDownloadUI(browser(), true, true, filename); |
| + |
| + // Fail the download |
| + GURL error_url(URLRequestSlowDownloadJob::kErrorFinishDownloadUrl); |
| + ui_test_utils::NavigateToURL(browser(), error_url); |
| + MessageLoopForUI::current()->RunAllPending(); |
| + |
| + // Should still be visible, with INTERRUPTED state. |
| + GetPersistentDownloads(browser(), &downloads); |
| + ASSERT_EQ(1u, downloads.size()); |
| + DownloadItem* download = downloads[0]; |
| + ASSERT_EQ(DownloadItem::INTERRUPTED, download->state()); |
| + // TODO(rdsmith): Confirm error provided by URLRequest is shown |
| + // in DownloadItem. |
| + CheckDownloadUI(browser(), true, true, FilePath()); |
| + |
| + // Confirm cancel does nothing. |
| + download->Cancel(); |
| + MessageLoopForUI::current()->RunAllPending(); |
| + |
| + GetPersistentDownloads(browser(), &downloads); |
| + ASSERT_EQ(1u, downloads.size()); |
| + ASSERT_EQ(download, downloads[0]); |
| + ASSERT_EQ(DownloadItem::INTERRUPTED, download->state()); |
| + CheckDownloadUI(browser(), true, true, filename); |
| + |
| + // Confirm remove gets rid of it. |
| + download->Remove(); |
| + download = NULL; |
| + MessageLoopForUI::current()->RunAllPending(); |
| + |
| + GetPersistentDownloads(browser(), &downloads); |
| + ASSERT_EQ(0u, downloads.size()); |
| + CheckDownloadUI(browser(), false, true, FilePath()); |
| +} |
| + |
| // Confirm a download makes it into the history properly. |
| IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadHistoryCheck) { |
| ASSERT_TRUE(InitialSetup(false)); |
| @@ -1468,7 +1783,7 @@ IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadHistoryCheck) { |
| // Get details of what downloads have just happened. |
| std::vector<DownloadItem*> downloads; |
| - GetDownloads(browser(), &downloads); |
| + GetPersistentDownloads(browser(), &downloads); |
| ASSERT_EQ(1u, downloads.size()); |
| int64 db_handle = downloads[0]->db_handle(); |
| @@ -1564,8 +1879,7 @@ IN_PROC_BROWSER_TEST_F(DownloadTest, AutoOpen) { |
| // Find the download and confirm it was opened. |
| std::vector<DownloadItem*> downloads; |
| - browser()->profile()->GetDownloadManager()->SearchDownloads( |
| - string16(), &downloads); |
| + GetPersistentDownloads(browser(), &downloads); |
| ASSERT_EQ(1u, downloads.size()); |
| EXPECT_EQ(DownloadItem::COMPLETE, downloads[0]->state()); |
| EXPECT_TRUE(downloads[0]->opened()); |