Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(342)

Unified Diff: chrome/browser/download/download_browsertest.cc

Issue 7294013: Modified cancel and interrupt processing to avoid race with history. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Incorporated comments, fixed some stuff from try jobs. Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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());

Powered by Google App Engine
This is Rietveld 408576698