1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/bind.h" 6 #include "base/files/file_path.h" 7 #include "chrome/browser/download/download_danger_prompt.h" 8 #include "chrome/browser/ui/browser.h" 9 #include "chrome/browser/ui/browser_commands.h" 10 #include "chrome/browser/ui/browser_tabstrip.h" 11 #include "chrome/browser/ui/tabs/tab_strip_model.h" 12 #include "chrome/test/base/in_process_browser_test.h" 13 #include "chrome/test/base/ui_test_utils.h" 14 #include "content/public/test/mock_download_item.h" 15 #include "testing/gmock/include/gmock/gmock.h" 16 #include "testing/gtest/include/gtest/gtest.h" 17 18 using ::testing::_; 19 using ::testing::ByRef; 20 using ::testing::Eq; 21 using ::testing::Return; 22 using ::testing::SaveArg; 23 24 class DownloadDangerPromptTest : public InProcessBrowserTest { 25 public: 26 DownloadDangerPromptTest() 27 : prompt_(NULL), 28 expected_action_(DownloadDangerPrompt::CANCEL), 29 did_receive_callback_(false) { 30 } 31 32 virtual ~DownloadDangerPromptTest() { 33 } 34 35 // Opens a new tab and waits for navigations to finish. If there are pending 36 // navigations, the constrained prompt might be dismissed when the navigation 37 // completes. 38 void OpenNewTab() { 39 ui_test_utils::NavigateToURLWithDisposition( 40 browser(), GURL("about:blank"), 41 NEW_FOREGROUND_TAB, 42 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB | 43 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 44 } 45 46 void SetUpExpectations(DownloadDangerPrompt::Action expected_action) { 47 did_receive_callback_ = false; 48 expected_action_ = expected_action; 49 SetUpDownloadItemExpectations(); 50 CreatePrompt(); 51 } 52 53 void VerifyExpectations() { 54 content::RunAllPendingInMessageLoop(); 55 // At the end of each test, we expect no more activity from the prompt. The 56 // prompt shouldn't exist anymore either. 57 EXPECT_TRUE(did_receive_callback_); 58 EXPECT_FALSE(prompt_); 59 testing::Mock::VerifyAndClearExpectations(&download_); 60 } 61 62 void SimulatePromptAction(DownloadDangerPrompt::Action action) { 63 prompt_->InvokeActionForTesting(action); 64 } 65 66 content::MockDownloadItem& download() { return download_; } 67 68 DownloadDangerPrompt* prompt() { return prompt_; } 69 70 private: 71 void SetUpDownloadItemExpectations() { 72 EXPECT_CALL(download_, GetFileNameToReportUser()).WillRepeatedly(Return( 73 base::FilePath(FILE_PATH_LITERAL("evil.exe")))); 74 EXPECT_CALL(download_, GetDangerType()) 75 .WillRepeatedly(Return(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL)); 76 } 77 78 void CreatePrompt() { 79 prompt_ = DownloadDangerPrompt::Create( 80 &download_, 81 browser()->tab_strip_model()->GetActiveWebContents(), 82 false, 83 base::Bind(&DownloadDangerPromptTest::PromptCallback, this)); 84 content::RunAllPendingInMessageLoop(); 85 } 86 87 void PromptCallback(DownloadDangerPrompt::Action action) { 88 EXPECT_FALSE(did_receive_callback_); 89 EXPECT_EQ(expected_action_, action); 90 did_receive_callback_ = true; 91 prompt_ = NULL; 92 } 93 94 content::MockDownloadItem download_; 95 DownloadDangerPrompt* prompt_; 96 DownloadDangerPrompt::Action expected_action_; 97 bool did_receive_callback_; 98 99 DISALLOW_COPY_AND_ASSIGN(DownloadDangerPromptTest); 100 }; 101 102 IN_PROC_BROWSER_TEST_F(DownloadDangerPromptTest, TestAll) { 103 OpenNewTab(); 104 105 // Clicking the Accept button should invoke the ACCEPT action. 106 SetUpExpectations(DownloadDangerPrompt::ACCEPT); 107 SimulatePromptAction(DownloadDangerPrompt::ACCEPT); 108 VerifyExpectations(); 109 110 // Clicking the Cancel button should invoke the CANCEL action. 111 SetUpExpectations(DownloadDangerPrompt::CANCEL); 112 SimulatePromptAction(DownloadDangerPrompt::CANCEL); 113 VerifyExpectations(); 114 115 // If the download is no longer dangerous (because it was accepted), the 116 // dialog should DISMISS itself. 117 SetUpExpectations(DownloadDangerPrompt::DISMISS); 118 EXPECT_CALL(download(), IsDangerous()).WillOnce(Return(false)); 119 download().NotifyObserversDownloadUpdated(); 120 VerifyExpectations(); 121 122 // If the download is in a terminal state then the dialog should DISMISS 123 // itself. 124 SetUpExpectations(DownloadDangerPrompt::DISMISS); 125 EXPECT_CALL(download(), IsDangerous()).WillOnce(Return(true)); 126 EXPECT_CALL(download(), IsDone()).WillOnce(Return(true)); 127 download().NotifyObserversDownloadUpdated(); 128 VerifyExpectations(); 129 130 // If the download is dangerous and is not in a terminal state, don't dismiss 131 // the dialog. 132 SetUpExpectations(DownloadDangerPrompt::ACCEPT); 133 EXPECT_CALL(download(), IsDangerous()).WillOnce(Return(true)); 134 EXPECT_CALL(download(), IsDone()).WillOnce(Return(false)); 135 download().NotifyObserversDownloadUpdated(); 136 SimulatePromptAction(DownloadDangerPrompt::ACCEPT); 137 VerifyExpectations(); 138 139 // If the containing tab is closed, the dialog should DISMISS itself. 140 OpenNewTab(); 141 SetUpExpectations(DownloadDangerPrompt::DISMISS); 142 chrome::CloseTab(browser()); 143 VerifyExpectations(); 144 } 145