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 331fb0e600faee41c2a49711bb6055fbf19927d7..b24607fe8c4612e200f4c35afd89fd647d569824 100644 |
| --- a/chrome/browser/download/download_browsertest.cc |
| +++ b/chrome/browser/download/download_browsertest.cc |
| @@ -32,6 +32,7 @@ |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/chrome_notification_types.h" |
| #include "chrome/browser/download/chrome_download_manager_delegate.h" |
| +#include "chrome/browser/download/download_commands.h" |
| #include "chrome/browser/download/download_crx_util.h" |
| #include "chrome/browser/download/download_history.h" |
| #include "chrome/browser/download/download_item_model.h" |
| @@ -75,6 +76,7 @@ |
| #include "components/infobars/core/confirm_infobar_delegate.h" |
| #include "components/infobars/core/infobar.h" |
| #include "components/prefs/pref_service.h" |
| +#include "content/public/browser/download_danger_type.h" |
| #include "content/public/browser/download_interrupt_reasons.h" |
| #include "content/public/browser/download_item.h" |
| #include "content/public/browser/download_manager.h" |
| @@ -248,6 +250,57 @@ class DownloadTestObserverResumable : public content::DownloadTestObserver { |
| DISALLOW_COPY_AND_ASSIGN(DownloadTestObserverResumable); |
| }; |
| +// DownloadTestObserverTerminal subclass for testing. |
| +class DownloadTestObserverAcceptUncommon |
| + : public content::DownloadTestObserverTerminal { |
| + public: |
| + DownloadTestObserverAcceptUncommon( |
| + DownloadManager* download_manager, |
| + size_t wait_count, |
| + content::DownloadTestObserver::DangerousDownloadAction |
| + dangerous_download_action) |
| + : content::DownloadTestObserverTerminal(download_manager, |
| + wait_count, |
| + dangerous_download_action), |
| + weak_factory_(this) {} |
| + ~DownloadTestObserverAcceptUncommon() override {} |
| + |
| + void OnDownloadUpdated(DownloadItem* download) override { |
| + // Real UI code gets the user's response after returning from the observer. |
| + if (download->IsDangerous() && |
| + !ContainsKey(dangerous_downloads_seen(), download->GetId())) { |
| + dangerous_downloads_seen().insert(download->GetId()); |
|
asanka
2016/03/11 03:43:26
This is inserting an item into a temporary set tha
Jialiu Lin
2016/03/11 05:03:48
Oops, should be return by reference instead. fixed
|
| + |
| + switch (dangerous_download_action()) { |
| + case ON_DANGEROUS_DOWNLOAD_ACCEPT: |
| + BrowserThread::PostTask( |
| + BrowserThread::UI, FROM_HERE, |
| + base::Bind( |
| + &DownloadTestObserverAcceptUncommon::AcceptDangerousDownload, |
| + weak_factory_.GetWeakPtr(), download->GetId())); |
| + break; |
| + default: |
| + NOTREACHED(); |
| + } |
| + } |
| + |
| + if (IsDownloadInFinalState(download)) |
| + DownloadInFinalState(download); |
| + } |
| + |
| + private: |
| + void AcceptDangerousDownload(uint32_t download_id) { |
| + if (!download_manager()) |
| + return; |
| + DownloadItem* download = download_manager()->GetDownload(download_id); |
| + if (download && download->IsDangerous() && !download->IsDone()) { |
| + DownloadCommands(download).ExecuteCommand(DownloadCommands::KEEP); |
| + } |
| + } |
| + |
| + base::WeakPtrFactory<DownloadTestObserverAcceptUncommon> weak_factory_; |
| +}; |
| + |
| // IDs and paths of CRX files used in tests. |
| const char kGoodCrxId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf"; |
| const char kGoodCrxPath[] = "extensions/good.crx"; |
| @@ -388,13 +441,49 @@ class HistoryObserver : public DownloadHistory::Observer { |
| DISALLOW_COPY_AND_ASSIGN(HistoryObserver); |
| }; |
| +class FakeSafeBrowsingService : public safe_browsing::SafeBrowsingService { |
| + public: |
| + FakeSafeBrowsingService() {} |
| + |
| + std::string GetDownloadReport() const { return report_; } |
| + |
| + protected: |
| + ~FakeSafeBrowsingService() override {} |
| + |
| + void SendSerializedDownloadReport(const std::string& report) override { |
| + report_ = report; |
| + } |
| + |
| + std::string report_; |
| +}; |
| + |
| +// Factory that creates FakeSafeBrowsingService instances. |
| +class TestSafeBrowsingServiceFactory |
| + : public safe_browsing::SafeBrowsingServiceFactory { |
| + public: |
| + TestSafeBrowsingServiceFactory() : fake_safe_browsing_service_(nullptr) {} |
| + ~TestSafeBrowsingServiceFactory() override {} |
| + |
| + safe_browsing::SafeBrowsingService* CreateSafeBrowsingService() override { |
| + if (!fake_safe_browsing_service_) { |
| + fake_safe_browsing_service_ = new FakeSafeBrowsingService(); |
| + } |
| + return fake_safe_browsing_service_.get(); |
| + } |
| + |
| + scoped_refptr<FakeSafeBrowsingService> fake_safe_browsing_service() { |
| + return fake_safe_browsing_service_; |
| + } |
| + |
| + private: |
| + scoped_refptr<FakeSafeBrowsingService> fake_safe_browsing_service_; |
| +}; |
| + |
| class DownloadTest : public InProcessBrowserTest { |
| public: |
| - // Choice of navigation or direct fetch. Used by |DownloadFileCheckErrors()|. |
| - enum DownloadMethod { |
| - DOWNLOAD_NAVIGATE, |
| - DOWNLOAD_DIRECT |
| - }; |
| + // Choice of navigation or direct fetch. Used by |
| + // |DownloadFileCheckErrors()|. |
| + enum DownloadMethod { DOWNLOAD_NAVIGATE, DOWNLOAD_DIRECT }; |
| // Information passed in to |DownloadFileCheckErrors()|. |
| struct DownloadInfo { |
| @@ -406,8 +495,10 @@ class DownloadTest : public InProcessBrowserTest { |
| DownloadMethod download_method; // Navigation or Direct. |
| // Download interrupt reason (NONE is OK). |
| content::DownloadInterruptReason reason; |
| - bool show_download_item; // True if the download item appears on the shelf. |
| - bool should_redirect_to_documents; // True if we save it in "My Documents". |
| + bool show_download_item; // True if the download item appears on the |
| + // shelf. |
| + bool should_redirect_to_documents; // True if we save it in "My |
| + // Documents". |
| }; |
| struct FileErrorInjectInfo { |
| @@ -415,13 +506,25 @@ class DownloadTest : public InProcessBrowserTest { |
| content::TestFileErrorInjector::FileErrorInfo error_info; |
| }; |
| - DownloadTest() {} |
| + DownloadTest() |
| + : test_safe_browsing_factory_(new TestSafeBrowsingServiceFactory()) {} |
| + |
| + void SetUp() override { |
| + safe_browsing::SafeBrowsingService::RegisterFactory( |
|
asanka
2016/03/11 03:43:26
Why is this necessary to be in SetUp() instead of
Jialiu Lin
2016/03/11 05:03:48
Because the registerFactory function needs to be c
|
| + test_safe_browsing_factory_.get()); |
| + InProcessBrowserTest::SetUp(); |
| + } |
| + |
| + void TearDown() override { |
| + safe_browsing::SafeBrowsingService::RegisterFactory(nullptr); |
| + InProcessBrowserTest::TearDown(); |
| + } |
| void SetUpOnMainThread() override { |
| base::FeatureList::ClearInstanceForTesting(); |
| scoped_ptr<base::FeatureList> feature_list(new base::FeatureList); |
| - feature_list->InitializeFromCommandLine( |
| - features::kDownloadResumption.name, std::string()); |
| + feature_list->InitializeFromCommandLine(features::kDownloadResumption.name, |
|
asanka
2016/03/11 03:43:26
Nit: There's a number of formatting only changes t
Jialiu Lin
2016/03/11 05:03:48
No problem.... seems I need to be more careful wit
|
| + std::string()); |
| base::FeatureList::SetInstance(std::move(feature_list)); |
| BrowserThread::PostTask( |
| BrowserThread::IO, FROM_HERE, |
| @@ -430,8 +533,10 @@ class DownloadTest : public InProcessBrowserTest { |
| } |
| void TearDownOnMainThread() override { |
| - // Needs to be torn down on the main thread. file_activity_observer_ holds a |
| - // reference to the ChromeDownloadManagerDelegate which should be destroyed |
| + // Needs to be torn down on the main thread. file_activity_observer_ holds |
| + // a |
| + // reference to the ChromeDownloadManagerDelegate which should be |
| + // destroyed |
| // on the UI thread. |
| file_activity_observer_.reset(); |
| } |
| @@ -458,8 +563,8 @@ class DownloadTest : public InProcessBrowserTest { |
| EXPECT_TRUE(created_downloads_dir); |
| if (!created_downloads_dir) |
| return false; |
| - browser()->profile()->GetPrefs()->SetBoolean( |
| - prefs::kPromptForDownload, false); |
| + browser()->profile()->GetPrefs()->SetBoolean(prefs::kPromptForDownload, |
| + false); |
| DownloadManager* manager = DownloadManagerForBrowser(browser()); |
| DownloadPrefs::FromDownloadManager(manager)->ResetAutoOpen(); |
| @@ -483,9 +588,7 @@ class DownloadTest : public InProcessBrowserTest { |
| return test_file_directory; |
| } |
| - base::FilePath GetDownloadsDirectory() { |
| - return downloads_directory_.path(); |
| - } |
| + base::FilePath GetDownloadsDirectory() { return downloads_directory_.path(); } |
| // Location of the file source (the place from which it is downloaded). |
| base::FilePath OriginFile(base::FilePath file) { |
| @@ -499,7 +602,8 @@ class DownloadTest : public InProcessBrowserTest { |
| // Must be called after browser creation. Creates a temporary |
| // directory for downloads that is auto-deleted on destruction. |
| - // Returning false indicates a failure of the function, and should be asserted |
| + // Returning false indicates a failure of the function, and should be |
| + // asserted |
| // in the caller. |
| bool CreateAndSetDownloadsDirectory(Browser* browser) { |
| if (!browser) |
| @@ -509,11 +613,9 @@ class DownloadTest : public InProcessBrowserTest { |
| return false; |
| browser->profile()->GetPrefs()->SetFilePath( |
| - prefs::kDownloadDefaultDirectory, |
| - downloads_directory_.path()); |
| + prefs::kDownloadDefaultDirectory, downloads_directory_.path()); |
| browser->profile()->GetPrefs()->SetFilePath( |
| - prefs::kSaveFileDefaultDirectory, |
| - downloads_directory_.path()); |
| + prefs::kSaveFileDefaultDirectory, downloads_directory_.path()); |
| return true; |
| } |
| @@ -529,8 +631,8 @@ class DownloadTest : public InProcessBrowserTest { |
| // Create a DownloadTestObserverTerminal that will wait for the |
| // specified number of downloads to finish. |
| - content::DownloadTestObserver* CreateWaiter( |
| - Browser* browser, int num_downloads) { |
| + content::DownloadTestObserver* CreateWaiter(Browser* browser, |
| + int num_downloads) { |
| DownloadManager* download_manager = DownloadManagerForBrowser(browser); |
| return new content::DownloadTestObserverTerminal( |
| download_manager, num_downloads, |
| @@ -539,11 +641,11 @@ class DownloadTest : public InProcessBrowserTest { |
| // Create a DownloadTestObserverInProgress that will wait for the |
| // specified number of downloads to start. |
| - content::DownloadTestObserver* CreateInProgressWaiter( |
| - Browser* browser, int num_downloads) { |
| + content::DownloadTestObserver* CreateInProgressWaiter(Browser* browser, |
| + int num_downloads) { |
| DownloadManager* download_manager = DownloadManagerForBrowser(browser); |
| - return new content::DownloadTestObserverInProgress( |
| - download_manager, num_downloads); |
| + return new content::DownloadTestObserverInProgress(download_manager, |
| + num_downloads); |
| } |
| // Create a DownloadTestObserverTerminal that will wait for the |
| @@ -559,6 +661,19 @@ class DownloadTest : public InProcessBrowserTest { |
| download_manager, num_downloads, dangerous_download_action); |
| } |
| + // Create a DownloadTestObserverAcceptUncommon that will wait for the |
| + // specified number of downloads to finish, or for |
| + // an uncommon download warning to be shown. |
| + content::DownloadTestObserver* UncommonDownloadWaiter( |
| + Browser* browser, |
| + int num_downloads, |
| + content::DownloadTestObserver::DangerousDownloadAction |
| + dangerous_download_action) { |
| + DownloadManager* download_manager = DownloadManagerForBrowser(browser); |
| + return new DownloadTestObserverAcceptUncommon( |
| + download_manager, num_downloads, dangerous_download_action); |
| + } |
| + |
| void CheckDownloadStatesForBrowser(Browser* browser, |
| size_t num, |
| DownloadItem::DownloadState state) { |
| @@ -596,9 +711,7 @@ class DownloadTest : public InProcessBrowserTest { |
| CreateWaiter(browser, 1)); |
| // This call will block until the condition specified by |
| // |browser_test_flags|, but will not wait for the download to finish. |
| - ui_test_utils::NavigateToURLWithDisposition(browser, |
| - url, |
| - disposition, |
| + ui_test_utils::NavigateToURLWithDisposition(browser, url, disposition, |
| browser_test_flags); |
| // Waits for the download to complete. |
| observer->WaitForFinished(); |
| @@ -608,18 +721,16 @@ class DownloadTest : public InProcessBrowserTest { |
| } |
| // Download a file in the current tab, then wait for the download to finish. |
| - void DownloadAndWait(Browser* browser, |
| - const GURL& url) { |
| + void DownloadAndWait(Browser* browser, const GURL& url) { |
| DownloadAndWaitWithDisposition( |
| - browser, |
| - url, |
| - CURRENT_TAB, |
| + browser, url, CURRENT_TAB, |
| ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
| } |
| // Should only be called when the download is known to have finished |
| // (in error or not). |
| - // Returning false indicates a failure of the function, and should be asserted |
| + // Returning false indicates a failure of the function, and should be |
| + // asserted |
| // in the caller. |
| bool CheckDownload(Browser* browser, |
| const base::FilePath& downloaded_filename, |
| @@ -664,8 +775,7 @@ class DownloadTest : public InProcessBrowserTest { |
| content::DownloadTestObserver* CreateInProgressDownloadObserver( |
| size_t download_count) { |
| DownloadManager* manager = DownloadManagerForBrowser(browser()); |
| - return new content::DownloadTestObserverInProgress( |
| - manager, download_count); |
| + return new content::DownloadTestObserverInProgress(manager, download_count); |
| } |
| DownloadItem* CreateSlowTestDownload() { |
| @@ -706,9 +816,9 @@ class DownloadTest : public InProcessBrowserTest { |
| EXPECT_TRUE(type == SIZE_TEST_TYPE_UNKNOWN || type == SIZE_TEST_TYPE_KNOWN); |
| if (type != SIZE_TEST_TYPE_KNOWN && type != SIZE_TEST_TYPE_UNKNOWN) |
| return false; |
| - GURL url(type == SIZE_TEST_TYPE_KNOWN ? |
| - net::URLRequestSlowDownloadJob::kKnownSizeUrl : |
| - net::URLRequestSlowDownloadJob::kUnknownSizeUrl); |
| + GURL url(type == SIZE_TEST_TYPE_KNOWN |
| + ? net::URLRequestSlowDownloadJob::kKnownSizeUrl |
| + : net::URLRequestSlowDownloadJob::kUnknownSizeUrl); |
| // TODO(ahendrickson) -- |expected_title_in_progress| and |
| // |expected_title_finished| need to be checked. |
| @@ -733,15 +843,14 @@ class DownloadTest : public InProcessBrowserTest { |
| // of a given member (for example, via the name in |DownloadItemView|'s |
| // GetAccessibleState() member function), by index. |
| // - Iterate over browser->window()->GetDownloadShelf()'s members |
| - // to see if any match the status text we want. Start with the last one. |
| + // to see if any match the status text we want. Start with the last |
| + // one. |
| // Allow the request to finish. We do this by loading a second URL in a |
| // separate tab. |
| GURL finish_url(net::URLRequestSlowDownloadJob::kFinishDownloadUrl); |
| ui_test_utils::NavigateToURLWithDisposition( |
| - browser, |
| - finish_url, |
| - NEW_FOREGROUND_TAB, |
| + browser, finish_url, NEW_FOREGROUND_TAB, |
| ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
| observer->WaitForFinished(); |
| EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE)); |
| @@ -906,9 +1015,9 @@ class DownloadTest : public InProcessBrowserTest { |
| downloads_expected++; |
| observer->WaitForFinished(); |
| DownloadItem::DownloadState final_state = |
| - (download_info.reason == content::DOWNLOAD_INTERRUPT_REASON_NONE) ? |
| - DownloadItem::COMPLETE : |
| - DownloadItem::INTERRUPTED; |
| + (download_info.reason == content::DOWNLOAD_INTERRUPT_REASON_NONE) |
| + ? DownloadItem::COMPLETE |
| + : DownloadItem::INTERRUPTED; |
| EXPECT_EQ(1u, observer->NumDownloadsSeenInState(final_state)); |
| } |
| @@ -939,16 +1048,15 @@ class DownloadTest : public InProcessBrowserTest { |
| EXPECT_TRUE(base::PathExists(my_downloaded_file)); |
| EXPECT_TRUE(base::DeleteFile(my_downloaded_file, false)); |
| - EXPECT_EQ(download_info.should_redirect_to_documents ? |
| - std::string::npos : |
| - 0u, |
| - my_downloaded_file.value().find(destination_folder.value())); |
| + EXPECT_EQ( |
| + download_info.should_redirect_to_documents ? std::string::npos : 0u, |
| + my_downloaded_file.value().find(destination_folder.value())); |
| if (download_info.should_redirect_to_documents) { |
| // If it's not where we asked it to be, it should be in the |
| // My Documents folder. |
| base::FilePath my_docs_folder; |
| - EXPECT_TRUE(PathService::Get(chrome::DIR_USER_DOCUMENTS, |
| - &my_docs_folder)); |
| + EXPECT_TRUE( |
| + PathService::Get(chrome::DIR_USER_DOCUMENTS, &my_docs_folder)); |
| EXPECT_EQ(0u, |
| my_downloaded_file.value().find(my_docs_folder.value())); |
| } |
| @@ -1022,7 +1130,8 @@ class DownloadTest : public InProcessBrowserTest { |
| } |
| // This method: |
| - // * Starts a mock download by navigating browser() to a URLRequestMockHTTPJob |
| + // * Starts a mock download by navigating browser() to a |
| + // URLRequestMockHTTPJob |
| // mock URL. |
| // * Injects |error| on the first write using |error_injector|. |
| // * Waits for the download to be interrupted. |
| @@ -1038,8 +1147,8 @@ class DownloadTest : public InProcessBrowserTest { |
| error_injector->InjectError(error_info); |
| scoped_ptr<content::DownloadTestObserver> observer( |
| - new DownloadTestObserverResumable( |
| - DownloadManagerForBrowser(browser()), 1)); |
| + new DownloadTestObserverResumable(DownloadManagerForBrowser(browser()), |
| + 1)); |
| GURL url = URLRequestMockHTTPJob::GetMockUrl(kDownloadTest1Path); |
| ui_test_utils::NavigateToURL(browser(), url); |
| @@ -1059,6 +1168,9 @@ class DownloadTest : public InProcessBrowserTest { |
| return download; |
| } |
| + protected: |
| + scoped_ptr<TestSafeBrowsingServiceFactory> test_safe_browsing_factory_; |
| + |
| private: |
| static void EnsureNoPendingDownloadJobsOnIO(bool* result) { |
| if (net::URLRequestSlowDownloadJob::NumberOutstandingRequests()) |
| @@ -3270,6 +3382,49 @@ IN_PROC_BROWSER_TEST_F(DownloadTest, FeedbackService) { |
| GetDownloads(browser(), &updated_downloads); |
| ASSERT_TRUE(updated_downloads.empty()); |
| } |
| + |
| +IN_PROC_BROWSER_TEST_F(DownloadTest, SendUncommonDownloadAcceptReport) { |
| + browser()->profile()->GetPrefs()->SetBoolean(prefs::kSafeBrowsingEnabled, |
| + true); |
| + // Make a dangerous file. |
| + GURL download_url( |
| + net::URLRequestMockHTTPJob::GetMockUrl(kDangerousMockFilePath)); |
| + scoped_ptr<content::DownloadTestObserver> dangerous_observer( |
| + UncommonDownloadWaiter( |
| + browser(), 1, |
| + content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_ACCEPT)); |
| + scoped_ptr<content::DownloadTestObserver> in_progress_observer( |
| + new content::DownloadTestObserverInProgress( |
| + DownloadManagerForBrowser(browser()), 1)); |
| + |
| + ui_test_utils::NavigateToURL(browser(), download_url); |
| + in_progress_observer->WaitForFinished(); |
| + |
| + std::vector<DownloadItem*> downloads; |
| + DownloadManagerForBrowser(browser())->GetAllDownloads(&downloads); |
| + ASSERT_EQ(1u, downloads.size()); |
| + DownloadItem* download = downloads[0]; |
| + // Simulates an uncommon download. |
| + download->OnContentCheckCompleted( |
| + content::DownloadDangerType::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT); |
| + ASSERT_EQ(download->GetDangerType(), |
| + content::DownloadDangerType::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT); |
| + dangerous_observer->WaitForFinished(); |
| + |
| + safe_browsing::ClientSafeBrowsingReportRequest actual_report; |
| + actual_report.ParseFromString( |
| + test_safe_browsing_factory_->fake_safe_browsing_service() |
| + ->GetDownloadReport()); |
| + EXPECT_EQ(safe_browsing::ClientSafeBrowsingReportRequest:: |
| + DANGEROUS_DOWNLOAD_WARNING, |
| + actual_report.type()); |
| + EXPECT_EQ(safe_browsing::ClientDownloadResponse::UNCOMMON, |
| + actual_report.download_verdict()); |
| + EXPECT_EQ(download->GetURL().spec(), actual_report.url()); |
| + EXPECT_TRUE(actual_report.did_proceed()); |
| + |
| + download->Cancel(true); |
| +} |
| #endif // FULL_SAFE_BROWSING |
| class DownloadTestWithShelf : public DownloadTest { |