| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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_util.h" | |
| 6 #include "base/files/file_path.h" | 5 #include "base/files/file_path.h" |
| 7 #include "base/files/scoped_temp_dir.h" | 6 #include "base/files/scoped_temp_dir.h" |
| 8 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
| 9 #include "base/observer_list.h" | |
| 10 #include "base/prefs/pref_service.h" | 8 #include "base/prefs/pref_service.h" |
| 11 #include "base/stl_util.h" | 9 #include "base/run_loop.h" |
| 12 #include "base/string_util.h" | |
| 13 #include "base/value_conversions.h" | |
| 14 #include "chrome/browser/download/chrome_download_manager_delegate.h" | 10 #include "chrome/browser/download/chrome_download_manager_delegate.h" |
| 15 #include "chrome/browser/download/download_prefs.h" | 11 #include "chrome/browser/download/download_prefs.h" |
| 16 #include "chrome/browser/download/download_util.h" | |
| 17 #include "chrome/browser/safe_browsing/download_protection_service.h" | |
| 18 #include "chrome/common/extensions/extension.h" | |
| 19 #include "chrome/common/pref_names.h" | 12 #include "chrome/common/pref_names.h" |
| 20 #include "chrome/test/base/chrome_render_view_host_test_harness.h" | 13 #include "chrome/test/base/chrome_render_view_host_test_harness.h" |
| 21 #include "chrome/test/base/testing_pref_service_syncable.h" | 14 #include "chrome/test/base/testing_pref_service_syncable.h" |
| 22 #include "chrome/test/base/testing_profile.h" | 15 #include "chrome/test/base/testing_profile.h" |
| 23 #include "content/public/browser/web_contents.h" | 16 #include "content/public/browser/web_contents.h" |
| 24 #include "content/public/browser/web_contents_delegate.h" | 17 #include "content/public/browser/web_contents_delegate.h" |
| 25 #include "content/public/test/mock_download_item.h" | 18 #include "content/public/test/mock_download_item.h" |
| 26 #include "content/public/test/mock_download_manager.h" | 19 #include "content/public/test/mock_download_manager.h" |
| 27 #include "content/public/test/test_browser_thread.h" | 20 #include "content/public/test/test_browser_thread.h" |
| 28 #include "content/public/test/test_renderer_host.h" | 21 #include "content/public/test/test_renderer_host.h" |
| 29 #include "content/public/test/web_contents_tester.h" | 22 #include "content/public/test/web_contents_tester.h" |
| 30 #include "testing/gmock/include/gmock/gmock.h" | 23 #include "testing/gmock/include/gmock/gmock.h" |
| 31 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
| 32 | 25 |
| 33 using ::testing::AtMost; | 26 using ::testing::AtMost; |
| 34 using ::testing::Invoke; | 27 using ::testing::Invoke; |
| 35 using ::testing::Ref; | 28 using ::testing::Ref; |
| 36 using ::testing::Return; | 29 using ::testing::Return; |
| 37 using ::testing::ReturnPointee; | 30 using ::testing::ReturnPointee; |
| 38 using ::testing::ReturnRef; | 31 using ::testing::ReturnRef; |
| 39 using ::testing::ReturnRefOfCopy; | 32 using ::testing::ReturnRefOfCopy; |
| 40 using ::testing::SetArgPointee; | 33 using ::testing::SetArgPointee; |
| 41 using ::testing::WithArg; | 34 using ::testing::WithArg; |
| 42 using ::testing::_; | 35 using ::testing::_; |
| 43 using content::DownloadItem; | 36 using content::DownloadItem; |
| 44 using safe_browsing::DownloadProtectionService; | |
| 45 | 37 |
| 46 namespace { | 38 namespace { |
| 47 | 39 |
| 48 class MockWebContentsDelegate : public content::WebContentsDelegate { | 40 class MockWebContentsDelegate : public content::WebContentsDelegate { |
| 49 public: | 41 public: |
| 50 virtual ~MockWebContentsDelegate() {} | 42 virtual ~MockWebContentsDelegate() {} |
| 51 }; | 43 }; |
| 52 | 44 |
| 53 // Google Mock action that posts a task to the current message loop that invokes | 45 // Google Mock action that posts a task to the current message loop that invokes |
| 54 // the first argument of the mocked method as a callback. Said argument must be | 46 // the first argument of the mocked method as a callback. Said argument must be |
| 55 // a base::Callback<void(ParamType)>. |result| must be of |ParamType| and is | 47 // a base::Callback<void(ParamType)>. |result| must be of |ParamType| and is |
| 56 // bound as that parameter. | 48 // bound as that parameter. |
| 57 // Example: | 49 // Example: |
| 58 // class FooClass { | 50 // class FooClass { |
| 59 // public: | 51 // public: |
| 60 // virtual void Foo(base::Callback<void(bool)> callback); | 52 // virtual void Foo(base::Callback<void(bool)> callback); |
| 61 // }; | 53 // }; |
| 62 // ... | 54 // ... |
| 63 // EXPECT_CALL(mock_fooclass_instance, Foo(callback)) | 55 // EXPECT_CALL(mock_fooclass_instance, Foo(callback)) |
| 64 // .WillOnce(ScheduleCallback(false)); | 56 // .WillOnce(ScheduleCallback(false)); |
| 65 ACTION_P(ScheduleCallback, result) { | 57 ACTION_P(ScheduleCallback, result) { |
| 66 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(arg0, result)); | 58 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(arg0, result)); |
| 67 } | 59 } |
| 68 | 60 |
| 69 // Used with DownloadTestCase. Indicates the type of test case. The expectations | 61 // Similar to ScheduleCallback, but binds 2 arguments. |
| 70 // for the test is set based on the type. | 62 ACTION_P2(ScheduleCallback2, result0, result1) { |
| 71 enum TestCaseType { | 63 MessageLoop::current()->PostTask( |
| 72 SAVE_AS, | 64 FROM_HERE, base::Bind(arg0, result0, result1)); |
| 73 AUTOMATIC, | 65 } |
| 74 FORCED // Requires that forced_file_path be non-empty. | 66 |
| 67 struct DownloadTarget { |
| 68 base::FilePath target_path; |
| 69 base::FilePath intermediate_path; |
| 70 DownloadItem::TargetDisposition target_disposition; |
| 71 content::DownloadDangerType danger_type; |
| 75 }; | 72 }; |
| 76 | 73 |
| 77 // Used with DownloadTestCase. Indicates whether the a file should be | |
| 78 // overwritten. | |
| 79 enum TestCaseExpectOverwrite { | |
| 80 EXPECT_OVERWRITE, | |
| 81 EXPECT_NO_OVERWRITE | |
| 82 }; | |
| 83 | |
| 84 // Used with DownloadTestCase. Type of intermediate filename to expect. | |
| 85 enum TestCaseExpectIntermediate { | |
| 86 EXPECT_CRDOWNLOAD, // Expect path/to/target.crdownload. | |
| 87 EXPECT_UNCONFIRMED, // Expect path/to/Unconfirmed xxx.crdownload. | |
| 88 EXPECT_TARGET_PATH, // Expect target path. | |
| 89 }; | |
| 90 | |
| 91 // Typical download test case. Used with | |
| 92 // ChromeDownloadManagerDelegateTest::RunTestCase(). | |
| 93 struct DownloadTestCase { | |
| 94 // Type of test. | |
| 95 TestCaseType test_type; | |
| 96 | |
| 97 // The |danger_type| is the expected danger type for the download as | |
| 98 // determined by CDMD. This value is also used to determine the behavior of | |
| 99 // DownloadProtectionService::IsSupportedDownload(), CDMD::CheckDownloadUrl() | |
| 100 // as necessary for flagging the download with as a dangerous download of type | |
| 101 // |danger_type|. | |
| 102 content::DownloadDangerType danger_type; | |
| 103 | |
| 104 // Value of DownloadItem::GetURL() | |
| 105 const char* url; | |
| 106 | |
| 107 // Value of DownloadItem::GetMimeType() | |
| 108 const char* mime_type; | |
| 109 | |
| 110 // Should be non-empty if |test_type| == FORCED. Value of GetForcedFilePath(). | |
| 111 const base::FilePath::CharType* forced_file_path; | |
| 112 | |
| 113 // Expected final download path. Specified relative to the test download path. | |
| 114 // If the user is presented with a file chooser, this path will also be the | |
| 115 // response sent back from the file chooser. | |
| 116 const base::FilePath::CharType* expected_target_path; | |
| 117 | |
| 118 // The path to expect as the suggested path if the user will be prompted for a | |
| 119 // download path. | |
| 120 const base::FilePath::CharType* expected_prompt_path; | |
| 121 | |
| 122 // Expected target disposition. If this is TARGET_DISPOSITION_PROMPT, then the | |
| 123 // test run will expect ChromeDownloadManagerDelegate to prompt the user for a | |
| 124 // download location. | |
| 125 DownloadItem::TargetDisposition expected_disposition; | |
| 126 | |
| 127 // Type of intermediate path to expect. | |
| 128 TestCaseExpectIntermediate expected_intermediate; | |
| 129 }; | |
| 130 | |
| 131 #if defined(FULL_SAFE_BROWSING) | |
| 132 // DownloadProtectionService with mock methods. Since the SafeBrowsingService is | |
| 133 // set to NULL, it is not safe to call any non-mocked methods other than | |
| 134 // SetEnabled() and enabled(). | |
| 135 class TestDownloadProtectionService | |
| 136 : public safe_browsing::DownloadProtectionService { | |
| 137 public: | |
| 138 TestDownloadProtectionService() | |
| 139 : safe_browsing::DownloadProtectionService(NULL, NULL) {} | |
| 140 MOCK_METHOD2(CheckClientDownload, | |
| 141 void(content::DownloadItem*, | |
| 142 const DownloadProtectionService::CheckDownloadCallback&)); | |
| 143 MOCK_METHOD2(CheckDownloadUrl, | |
| 144 void(const content::DownloadItem&, | |
| 145 const DownloadProtectionService::CheckDownloadCallback&)); | |
| 146 MOCK_CONST_METHOD2(IsSupportedDownload, | |
| 147 bool(const content::DownloadItem&, | |
| 148 const base::FilePath&)); | |
| 149 }; | |
| 150 #endif | |
| 151 | |
| 152 // Subclass of the ChromeDownloadManagerDelegate that uses a mock | 74 // Subclass of the ChromeDownloadManagerDelegate that uses a mock |
| 153 // DownloadProtectionService and IsDangerousFile. | 75 // DownloadProtectionService. |
| 154 class TestChromeDownloadManagerDelegate : public ChromeDownloadManagerDelegate { | 76 class TestChromeDownloadManagerDelegate : public ChromeDownloadManagerDelegate { |
| 155 public: | 77 public: |
| 156 explicit TestChromeDownloadManagerDelegate(Profile* profile) | 78 explicit TestChromeDownloadManagerDelegate(Profile* profile) |
| 157 : ChromeDownloadManagerDelegate(profile) { | 79 : ChromeDownloadManagerDelegate(profile) { |
| 158 #if defined(FULL_SAFE_BROWSING) | |
| 159 download_protection_service_.reset(new TestDownloadProtectionService()); | |
| 160 download_protection_service_->SetEnabled(true); | |
| 161 #endif | |
| 162 } | 80 } |
| 163 | 81 |
| 164 virtual safe_browsing::DownloadProtectionService* | 82 virtual safe_browsing::DownloadProtectionService* |
| 165 GetDownloadProtectionService() OVERRIDE { | 83 GetDownloadProtectionService() OVERRIDE { |
| 166 #if defined(FULL_SAFE_BROWSING) | |
| 167 return download_protection_service_.get(); | |
| 168 #else | |
| 169 return NULL; | 84 return NULL; |
| 170 #endif | |
| 171 } | 85 } |
| 172 | 86 |
| 173 virtual bool IsDangerousFile(const DownloadItem& download, | 87 virtual void NotifyExtensions( |
| 174 const base::FilePath& suggested_path, | 88 content::DownloadItem* download, |
| 175 bool visited_referrer_before) OVERRIDE { | 89 const base::FilePath& suggested_virtual_path, |
| 176 // The implementaion of ChromeDownloadManagerDelegate::IsDangerousFile() is | 90 const NotifyExtensionsCallback& callback) OVERRIDE { |
| 177 // sensitive to a number of external factors (e.g. whether off-store | 91 callback.Run(base::FilePath(), |
| 178 // extension installs are allowed, whether a given extension download is | 92 DownloadPathReservationTracker::UNIQUIFY); |
| 179 // approved, whether the user wants files of a given type to be opened | |
| 180 // automatically etc...). We should test these specifically, but for other | |
| 181 // tests, we keep the IsDangerousFile() test simple so as not to make the | |
| 182 // tests flaky. | |
| 183 return suggested_path.MatchesExtension(FILE_PATH_LITERAL(".jar")) || | |
| 184 suggested_path.MatchesExtension(FILE_PATH_LITERAL(".exe")); | |
| 185 } | 93 } |
| 186 | 94 |
| 187 virtual void GetReservedPath( | 95 virtual void ReserveVirtualPath( |
| 188 content::DownloadItem& download, | 96 content::DownloadItem* download, |
| 189 const base::FilePath& target_path, | 97 const base::FilePath& target_path, |
| 190 const base::FilePath& default_download_path, | |
| 191 DownloadPathReservationTracker::FilenameConflictAction conflict_action, | 98 DownloadPathReservationTracker::FilenameConflictAction conflict_action, |
| 192 const DownloadPathReservationTracker::ReservedPathCallback& callback) | 99 const DownloadPathReservationTracker::ReservedPathCallback& callback) |
| 193 OVERRIDE { | 100 OVERRIDE { |
| 194 // Pretend the path reservation succeeded without any change to | 101 // Pretend the path reservation succeeded without any change to |
| 195 // |target_path|. | 102 // |target_path|. |
| 196 MessageLoop::current()->PostTask(FROM_HERE, | 103 MessageLoop::current()->PostTask(FROM_HERE, |
| 197 base::Bind(callback, target_path, true)); | 104 base::Bind(callback, target_path, true)); |
| 198 } | 105 } |
| 199 | 106 |
| 200 // During tests, we want to mock the behavior of this method. | 107 virtual void PromptUserForDownloadPath( |
| 201 MOCK_METHOD3(ChooseDownloadPath, | 108 DownloadItem* download, |
| 202 void(content::DownloadItem*, | 109 const base::FilePath& suggested_path, |
| 203 const base::FilePath&, | 110 const DownloadTargetDeterminerDelegate::FileSelectedCallback& callback) |
| 204 const FileSelectedCallback&)); | 111 OVERRIDE { |
| 112 base::FilePath return_path = MockPromptUserForDownloadPath(download, |
| 113 suggested_path, |
| 114 callback); |
| 115 OnDownloadPathSelected(callback, return_path); |
| 116 } |
| 205 | 117 |
| 206 #if defined(FULL_SAFE_BROWSING) | 118 MOCK_METHOD3( |
| 207 // A TestDownloadProtectionService* is convenient for setting up mocks. | 119 MockPromptUserForDownloadPath, |
| 208 TestDownloadProtectionService* test_download_protection_service() { | 120 base::FilePath( |
| 209 return download_protection_service_.get(); | 121 content::DownloadItem*, |
| 210 } | 122 const base::FilePath&, |
| 211 #endif | 123 const DownloadTargetDeterminerDelegate::FileSelectedCallback&)); |
| 212 | 124 |
| 213 private: | 125 private: |
| 214 ~TestChromeDownloadManagerDelegate() {} | 126 ~TestChromeDownloadManagerDelegate() {} |
| 215 | |
| 216 #if defined(FULL_SAFE_BROWSING) | |
| 217 scoped_ptr<TestDownloadProtectionService> download_protection_service_; | |
| 218 #endif | |
| 219 }; | 127 }; |
| 220 | 128 |
| 221 class ChromeDownloadManagerDelegateTest : | 129 class ChromeDownloadManagerDelegateTest : |
| 222 public ChromeRenderViewHostTestHarness { | 130 public ChromeRenderViewHostTestHarness { |
| 223 public: | 131 public: |
| 224 ChromeDownloadManagerDelegateTest(); | 132 ChromeDownloadManagerDelegateTest(); |
| 225 | 133 |
| 226 // ::testing::Test | 134 // ::testing::Test |
| 227 virtual void SetUp() OVERRIDE; | 135 virtual void SetUp() OVERRIDE; |
| 228 virtual void TearDown() OVERRIDE; | 136 virtual void TearDown() OVERRIDE; |
| 229 | 137 |
| 230 // Verifies and clears test expectations for |delegate_| and | 138 // Verifies and clears test expectations for |delegate_| and |
| 231 // |download_manager_|. | 139 // |download_manager_|. |
| 232 void VerifyAndClearExpectations(); | 140 void VerifyAndClearExpectations(); |
| 233 | 141 |
| 234 // Creates MockDownloadItem and sets up default expectations. | 142 // Creates MockDownloadItem and sets up default expectations. |
| 235 content::MockDownloadItem* CreateActiveDownloadItem(int32 id); | 143 content::MockDownloadItem* CreateActiveDownloadItem(int32 id); |
| 236 | 144 |
| 237 // Sets the AutoOpenBasedOnExtension user preference for |path|. | |
| 238 void EnableAutoOpenBasedOnExtension(const base::FilePath& path); | |
| 239 | |
| 240 // Given the relative path |path|, returns the full path under the temporary | 145 // Given the relative path |path|, returns the full path under the temporary |
| 241 // downloads directory. | 146 // downloads directory. |
| 242 base::FilePath GetPathInDownloadDir(const base::FilePath::StringType& path); | 147 base::FilePath GetPathInDownloadDir(const char* path); |
| 243 | |
| 244 // Run |test_case| using |item|. | |
| 245 void RunTestCaseWithDownloadItem(const DownloadTestCase& test_case, | |
| 246 content::MockDownloadItem* item); | |
| 247 | |
| 248 // Run through |test_case_count| tests in |test_cases|. A new MockDownloadItem | |
| 249 // will be created for each test case and destroyed when the test case is | |
| 250 // complete. | |
| 251 void RunTestCases(const DownloadTestCase test_cases[], | |
| 252 size_t test_case_count); | |
| 253 | 148 |
| 254 // Set the kDownloadDefaultDirectory user preference to |path|. | 149 // Set the kDownloadDefaultDirectory user preference to |path|. |
| 255 void SetDefaultDownloadPath(const base::FilePath& path); | 150 void SetDefaultDownloadPath(const base::FilePath& path); |
| 256 | 151 |
| 257 // Set the kDownloadDefaultDirectory managed preference to |path|. | 152 void DetermineDownloadTarget(DownloadItem* download, |
| 258 void SetManagedDownloadPath(const base::FilePath& path); | 153 DownloadTarget* result); |
| 259 | |
| 260 // Set the kPromptForDownload user preference to |prompt|. | |
| 261 void SetPromptForDownload(bool prompt); | |
| 262 | 154 |
| 263 const base::FilePath& default_download_path() const; | 155 const base::FilePath& default_download_path() const; |
| 264 TestChromeDownloadManagerDelegate* delegate(); | 156 TestChromeDownloadManagerDelegate* delegate(); |
| 265 content::MockDownloadManager* download_manager(); | 157 content::MockDownloadManager* download_manager(); |
| 266 DownloadPrefs* download_prefs(); | 158 DownloadPrefs* download_prefs(); |
| 267 | 159 |
| 268 private: | 160 private: |
| 269 // Verifies that |target_path|, |disposition|, |danger_type| and | 161 void OnDownloadTargetDone(DownloadTarget* result, |
| 270 // |intermediate_path| matches the expectations of |test_case|. | 162 const base::FilePath& target_path, |
| 271 void DownloadTargetVerifier(const DownloadTestCase* test_case, | 163 DownloadItem::TargetDisposition disposition, |
| 272 const base::FilePath& target_path, | 164 content::DownloadDangerType danger_type, |
| 273 DownloadItem::TargetDisposition disposition, | 165 const base::FilePath& intermediate_path); |
| 274 content::DownloadDangerType danger_type, | |
| 275 const base::FilePath& intermediate_path); | |
| 276 | 166 |
| 277 TestingPrefServiceSyncable* pref_service_; | 167 TestingPrefServiceSyncable* pref_service_; |
| 278 base::ScopedTempDir test_download_dir_; | 168 base::ScopedTempDir test_download_dir_; |
| 279 content::TestBrowserThread ui_thread_; | 169 content::TestBrowserThread ui_thread_; |
| 280 content::TestBrowserThread file_thread_; | 170 content::TestBrowserThread file_thread_; |
| 281 scoped_refptr<content::MockDownloadManager> download_manager_; | 171 scoped_refptr<content::MockDownloadManager> download_manager_; |
| 282 scoped_refptr<TestChromeDownloadManagerDelegate> delegate_; | 172 scoped_refptr<TestChromeDownloadManagerDelegate> delegate_; |
| 283 MockWebContentsDelegate web_contents_delegate_; | 173 MockWebContentsDelegate web_contents_delegate_; |
| 284 }; | 174 }; |
| 285 | 175 |
| 286 ChromeDownloadManagerDelegateTest::ChromeDownloadManagerDelegateTest() | 176 ChromeDownloadManagerDelegateTest::ChromeDownloadManagerDelegateTest() |
| 287 : ChromeRenderViewHostTestHarness(), | 177 : ChromeRenderViewHostTestHarness(), |
| 288 ui_thread_(content::BrowserThread::UI, &message_loop_), | 178 ui_thread_(content::BrowserThread::UI, &message_loop_), |
| 289 file_thread_(content::BrowserThread::FILE, &message_loop_), | 179 file_thread_(content::BrowserThread::FILE, &message_loop_), |
| 290 download_manager_(new content::MockDownloadManager) { | 180 download_manager_(new ::testing::NiceMock<content::MockDownloadManager>) { |
| 291 EXPECT_CALL(*download_manager_, GetAllDownloads(_)).WillRepeatedly(Return()); | |
| 292 EXPECT_CALL(*download_manager_, AddObserver(_)).WillRepeatedly(Return()); | |
| 293 EXPECT_CALL(*download_manager_, RemoveObserver(_)).WillRepeatedly(Return()); | |
| 294 } | 181 } |
| 295 | 182 |
| 296 void ChromeDownloadManagerDelegateTest::SetUp() { | 183 void ChromeDownloadManagerDelegateTest::SetUp() { |
| 297 ChromeRenderViewHostTestHarness::SetUp(); | 184 ChromeRenderViewHostTestHarness::SetUp(); |
| 298 | 185 |
| 299 CHECK(profile()); | 186 CHECK(profile()); |
| 300 delegate_ = new TestChromeDownloadManagerDelegate(profile()); | 187 delegate_ = new TestChromeDownloadManagerDelegate(profile()); |
| 301 EXPECT_CALL(*download_manager_.get(), GetAllDownloads(_)) | |
| 302 .WillRepeatedly(Return()); | |
| 303 EXPECT_CALL(*download_manager_.get(), AddObserver(_)) | |
| 304 .WillRepeatedly(Return()); | |
| 305 delegate_->SetDownloadManager(download_manager_.get()); | 188 delegate_->SetDownloadManager(download_manager_.get()); |
| 306 pref_service_ = profile()->GetTestingPrefService(); | 189 pref_service_ = profile()->GetTestingPrefService(); |
| 307 web_contents()->SetDelegate(&web_contents_delegate_); | 190 web_contents()->SetDelegate(&web_contents_delegate_); |
| 308 | 191 |
| 309 ASSERT_TRUE(test_download_dir_.CreateUniqueTempDir()); | 192 ASSERT_TRUE(test_download_dir_.CreateUniqueTempDir()); |
| 310 SetDefaultDownloadPath(test_download_dir_.path()); | 193 SetDefaultDownloadPath(test_download_dir_.path()); |
| 311 } | 194 } |
| 312 | 195 |
| 313 void ChromeDownloadManagerDelegateTest::TearDown() { | 196 void ChromeDownloadManagerDelegateTest::TearDown() { |
| 314 message_loop_.RunUntilIdle(); | 197 message_loop_.RunUntilIdle(); |
| 315 delegate_->Shutdown(); | 198 delegate_->Shutdown(); |
| 316 ChromeRenderViewHostTestHarness::TearDown(); | 199 ChromeRenderViewHostTestHarness::TearDown(); |
| 317 } | 200 } |
| 318 | 201 |
| 319 void ChromeDownloadManagerDelegateTest::VerifyAndClearExpectations() { | 202 void ChromeDownloadManagerDelegateTest::VerifyAndClearExpectations() { |
| 320 ::testing::Mock::VerifyAndClearExpectations(delegate_); | 203 ::testing::Mock::VerifyAndClearExpectations(delegate_); |
| 321 ::testing::Mock::VerifyAndClearExpectations(download_manager_); | |
| 322 EXPECT_CALL(*download_manager_, RemoveObserver(_)).WillRepeatedly(Return()); | |
| 323 EXPECT_CALL(*download_manager_, GetAllDownloads(_)) | |
| 324 .WillRepeatedly(Return()); | |
| 325 } | 204 } |
| 326 | 205 |
| 327 content::MockDownloadItem* | 206 content::MockDownloadItem* |
| 328 ChromeDownloadManagerDelegateTest::CreateActiveDownloadItem(int32 id) { | 207 ChromeDownloadManagerDelegateTest::CreateActiveDownloadItem(int32 id) { |
| 329 content::MockDownloadItem* item = | 208 content::MockDownloadItem* item = |
| 330 new ::testing::NiceMock<content::MockDownloadItem>(); | 209 new ::testing::NiceMock<content::MockDownloadItem>(); |
| 210 ON_CALL(*item, GetBrowserContext()) |
| 211 .WillByDefault(Return(profile())); |
| 212 ON_CALL(*item, GetDangerType()) |
| 213 .WillByDefault(Return(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS)); |
| 214 ON_CALL(*item, GetForcedFilePath()) |
| 215 .WillByDefault(ReturnRefOfCopy(base::FilePath())); |
| 331 ON_CALL(*item, GetFullPath()) | 216 ON_CALL(*item, GetFullPath()) |
| 332 .WillByDefault(ReturnRefOfCopy(base::FilePath())); | 217 .WillByDefault(ReturnRefOfCopy(base::FilePath())); |
| 333 ON_CALL(*item, GetHash()) | 218 ON_CALL(*item, GetHash()) |
| 334 .WillByDefault(ReturnRefOfCopy(std::string())); | 219 .WillByDefault(ReturnRefOfCopy(std::string())); |
| 220 ON_CALL(*item, GetId()) |
| 221 .WillByDefault(Return(id)); |
| 335 ON_CALL(*item, GetReferrerUrl()) | 222 ON_CALL(*item, GetReferrerUrl()) |
| 336 .WillByDefault(ReturnRefOfCopy(GURL())); | 223 .WillByDefault(ReturnRefOfCopy(GURL())); |
| 224 ON_CALL(*item, GetState()) |
| 225 .WillByDefault(Return(DownloadItem::IN_PROGRESS)); |
| 337 ON_CALL(*item, GetTransitionType()) | 226 ON_CALL(*item, GetTransitionType()) |
| 338 .WillByDefault(Return(content::PAGE_TRANSITION_LINK)); | 227 .WillByDefault(Return(content::PAGE_TRANSITION_LINK)); |
| 228 ON_CALL(*item, GetWebContents()) |
| 229 .WillByDefault(Return(web_contents())); |
| 339 ON_CALL(*item, HasUserGesture()) | 230 ON_CALL(*item, HasUserGesture()) |
| 340 .WillByDefault(Return(false)); | 231 .WillByDefault(Return(false)); |
| 341 ON_CALL(*item, IsDangerous()) | 232 ON_CALL(*item, IsDangerous()) |
| 342 .WillByDefault(Return(false)); | 233 .WillByDefault(Return(false)); |
| 234 ON_CALL(*item, IsInProgress()) |
| 235 .WillByDefault(Return(true)); |
| 343 ON_CALL(*item, IsTemporary()) | 236 ON_CALL(*item, IsTemporary()) |
| 344 .WillByDefault(Return(false)); | 237 .WillByDefault(Return(false)); |
| 345 ON_CALL(*item, GetWebContents()) | |
| 346 .WillByDefault(Return(web_contents())); | |
| 347 EXPECT_CALL(*item, GetId()) | |
| 348 .WillRepeatedly(Return(id)); | |
| 349 EXPECT_CALL(*item, GetState()) | |
| 350 .WillRepeatedly(Return(DownloadItem::IN_PROGRESS)); | |
| 351 EXPECT_CALL(*item, AddObserver(_)).WillRepeatedly(Return()); | |
| 352 EXPECT_CALL(*item, RemoveObserver(_)).WillRepeatedly(Return()); | |
| 353 EXPECT_CALL(*download_manager_, GetDownload(id)) | 238 EXPECT_CALL(*download_manager_, GetDownload(id)) |
| 354 .WillRepeatedly(Return(item)); | 239 .WillRepeatedly(Return(item)); |
| 355 return item; | 240 return item; |
| 356 } | 241 } |
| 357 | 242 |
| 358 void ChromeDownloadManagerDelegateTest::EnableAutoOpenBasedOnExtension( | |
| 359 const base::FilePath& path) { | |
| 360 EXPECT_TRUE( | |
| 361 delegate_->download_prefs()->EnableAutoOpenBasedOnExtension(path)); | |
| 362 } | |
| 363 | |
| 364 base::FilePath ChromeDownloadManagerDelegateTest::GetPathInDownloadDir( | 243 base::FilePath ChromeDownloadManagerDelegateTest::GetPathInDownloadDir( |
| 365 const base::FilePath::StringType& relative_path) { | 244 const char* relative_path) { |
| 366 if (relative_path.empty()) | 245 base::FilePath full_path = |
| 367 return base::FilePath(); | 246 test_download_dir_.path().AppendASCII(relative_path); |
| 368 base::FilePath full_path(test_download_dir_.path().Append(relative_path)); | |
| 369 return full_path.NormalizePathSeparators(); | 247 return full_path.NormalizePathSeparators(); |
| 370 } | 248 } |
| 371 | 249 |
| 372 void ChromeDownloadManagerDelegateTest::RunTestCaseWithDownloadItem( | |
| 373 const DownloadTestCase& test_case, | |
| 374 content::MockDownloadItem* item) { | |
| 375 // SetUp DownloadItem | |
| 376 GURL download_url(test_case.url); | |
| 377 std::vector<GURL> url_chain; | |
| 378 url_chain.push_back(download_url); | |
| 379 base::FilePath forced_file_path( | |
| 380 GetPathInDownloadDir(test_case.forced_file_path)); | |
| 381 EXPECT_CALL(*item, GetURL()) | |
| 382 .WillRepeatedly(ReturnRef(download_url)); | |
| 383 EXPECT_CALL(*item, GetUrlChain()) | |
| 384 .WillRepeatedly(ReturnRef(url_chain)); | |
| 385 EXPECT_CALL(*item, GetForcedFilePath()) | |
| 386 .WillRepeatedly(ReturnRef(forced_file_path)); | |
| 387 EXPECT_CALL(*item, GetMimeType()) | |
| 388 .WillRepeatedly(Return(test_case.mime_type)); | |
| 389 std::vector<DownloadItem*> items; | |
| 390 items.push_back(item); | |
| 391 EXPECT_CALL(*download_manager_, GetAllDownloads(_)) | |
| 392 .WillRepeatedly(SetArgPointee<0>(items)); | |
| 393 | |
| 394 #if defined(FULL_SAFE_BROWSING) | |
| 395 // Results of SafeBrowsing URL check. | |
| 396 DownloadProtectionService::DownloadCheckResult url_check_result = | |
| 397 (test_case.danger_type == content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL) ? | |
| 398 DownloadProtectionService::DANGEROUS : | |
| 399 DownloadProtectionService::SAFE; | |
| 400 EXPECT_CALL(*delegate_->test_download_protection_service(), | |
| 401 CheckDownloadUrl(Ref(*item), _)) | |
| 402 .WillOnce(WithArg<1>(ScheduleCallback(url_check_result))); | |
| 403 | |
| 404 // Downloads that are flagged as DANGEROUS_URL aren't checked for dangerous | |
| 405 // content. So we never end up calling IsSupportedDownload for them. | |
| 406 if (test_case.danger_type != content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL) { | |
| 407 bool maybe_dangerous = | |
| 408 (test_case.danger_type == | |
| 409 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT); | |
| 410 EXPECT_CALL(*delegate_->test_download_protection_service(), | |
| 411 IsSupportedDownload(Ref(*item), _)) | |
| 412 .WillOnce(Return(maybe_dangerous)); | |
| 413 } | |
| 414 #else // FULL_SAFE_BROWSING | |
| 415 // If safe browsing is not enabled, then these tests would fail. If such a | |
| 416 // test was added, then fail early. | |
| 417 EXPECT_NE(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, test_case.danger_type); | |
| 418 EXPECT_NE(content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, | |
| 419 test_case.danger_type); | |
| 420 #endif // !FULL_SAFE_BROWSING | |
| 421 | |
| 422 DownloadItem::TargetDisposition initial_disposition = | |
| 423 (test_case.test_type == SAVE_AS) ? | |
| 424 DownloadItem::TARGET_DISPOSITION_PROMPT : | |
| 425 DownloadItem::TARGET_DISPOSITION_OVERWRITE; | |
| 426 EXPECT_CALL(*item, GetTargetFilePath()) | |
| 427 .WillRepeatedly(ReturnRefOfCopy(base::FilePath())); | |
| 428 EXPECT_CALL(*item, GetTargetDisposition()) | |
| 429 .WillRepeatedly(Return(initial_disposition)); | |
| 430 EXPECT_CALL(*item, GetDangerType()) | |
| 431 .WillRepeatedly(Return(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS)); | |
| 432 | |
| 433 if (test_case.expected_disposition == | |
| 434 DownloadItem::TARGET_DISPOSITION_PROMPT) { | |
| 435 base::FilePath expected_prompt_path = GetPathInDownloadDir( | |
| 436 test_case.expected_prompt_path); | |
| 437 base::FilePath expected_target_path = GetPathInDownloadDir( | |
| 438 test_case.expected_target_path); | |
| 439 EXPECT_CALL(*delegate_, | |
| 440 ChooseDownloadPath(item, expected_prompt_path, _)) | |
| 441 .WillOnce(WithArg<2>(ScheduleCallback(expected_target_path))); | |
| 442 } | |
| 443 | |
| 444 // Kick off the test. | |
| 445 base::WeakPtrFactory<ChromeDownloadManagerDelegateTest> factory(this); | |
| 446 EXPECT_TRUE(delegate_->DetermineDownloadTarget( | |
| 447 item, | |
| 448 base::Bind(&ChromeDownloadManagerDelegateTest::DownloadTargetVerifier, | |
| 449 factory.GetWeakPtr(), base::Unretained(&test_case)))); | |
| 450 message_loop_.RunUntilIdle(); | |
| 451 VerifyAndClearExpectations(); | |
| 452 } | |
| 453 | |
| 454 void ChromeDownloadManagerDelegateTest::RunTestCases( | |
| 455 const DownloadTestCase test_cases[], | |
| 456 size_t test_case_count) { | |
| 457 for (size_t i = 0; i < test_case_count; ++i) { | |
| 458 scoped_ptr<content::MockDownloadItem> item(CreateActiveDownloadItem(i)); | |
| 459 SCOPED_TRACE(testing::Message() << "Running test case " << i); | |
| 460 RunTestCaseWithDownloadItem(test_cases[i], item.get()); | |
| 461 } | |
| 462 } | |
| 463 | |
| 464 void ChromeDownloadManagerDelegateTest::SetDefaultDownloadPath( | 250 void ChromeDownloadManagerDelegateTest::SetDefaultDownloadPath( |
| 465 const base::FilePath& path) { | 251 const base::FilePath& path) { |
| 466 pref_service_->SetFilePath(prefs::kDownloadDefaultDirectory, path); | 252 pref_service_->SetFilePath(prefs::kDownloadDefaultDirectory, path); |
| 467 } | 253 } |
| 468 | 254 |
| 469 void ChromeDownloadManagerDelegateTest::SetManagedDownloadPath( | 255 void ChromeDownloadManagerDelegateTest::DetermineDownloadTarget( |
| 470 const base::FilePath& path) { | 256 DownloadItem* download_item, |
| 471 pref_service_->SetManagedPref(prefs::kDownloadDefaultDirectory, | 257 DownloadTarget* result) { |
| 472 base::CreateFilePathValue(path)); | 258 base::WeakPtrFactory<ChromeDownloadManagerDelegateTest> factory(this); |
| 259 delegate()->DetermineDownloadTarget( |
| 260 download_item, |
| 261 base::Bind(&ChromeDownloadManagerDelegateTest::OnDownloadTargetDone, |
| 262 factory.GetWeakPtr(), base::Unretained(result))); |
| 263 base::RunLoop loop_runner; |
| 264 loop_runner.RunUntilIdle(); |
| 473 } | 265 } |
| 474 | 266 |
| 475 void ChromeDownloadManagerDelegateTest::SetPromptForDownload(bool prompt) { | 267 void ChromeDownloadManagerDelegateTest::OnDownloadTargetDone( |
| 476 pref_service_->SetBoolean(prefs::kPromptForDownload, prompt); | 268 DownloadTarget* result, |
| 477 } | |
| 478 | |
| 479 void ChromeDownloadManagerDelegateTest::DownloadTargetVerifier( | |
| 480 const DownloadTestCase* test_case, | |
| 481 const base::FilePath& target_path, | 269 const base::FilePath& target_path, |
| 482 DownloadItem::TargetDisposition disposition, | 270 DownloadItem::TargetDisposition target_disposition, |
| 483 content::DownloadDangerType danger_type, | 271 content::DownloadDangerType danger_type, |
| 484 const base::FilePath& intermediate_path) { | 272 const base::FilePath& intermediate_path) { |
| 485 base::FilePath expected_target_path( | 273 result->target_path = target_path; |
| 486 GetPathInDownloadDir(test_case->expected_target_path)); | 274 result->intermediate_path = intermediate_path; |
| 487 EXPECT_EQ(expected_target_path.value(), target_path.value()); | 275 result->target_disposition = target_disposition; |
| 488 EXPECT_EQ(test_case->expected_disposition, disposition); | 276 result->danger_type = danger_type; |
| 489 EXPECT_EQ(test_case->danger_type, danger_type); | |
| 490 | |
| 491 switch (test_case->expected_intermediate) { | |
| 492 case EXPECT_CRDOWNLOAD: | |
| 493 EXPECT_EQ(download_util::GetCrDownloadPath(target_path).value(), | |
| 494 intermediate_path.value()); | |
| 495 break; | |
| 496 | |
| 497 case EXPECT_UNCONFIRMED: | |
| 498 // The paths (in English) look like: /path/Unconfirmed xxx.crdownload. | |
| 499 // Of this, we only check that the path is: | |
| 500 // 1. Not "/path/target.crdownload", | |
| 501 // 2. Points to the same directory as the target. | |
| 502 // 3. Has extension ".crdownload". | |
| 503 EXPECT_NE(download_util::GetCrDownloadPath(target_path).value(), | |
| 504 intermediate_path.value()); | |
| 505 EXPECT_EQ(target_path.DirName().value(), | |
| 506 intermediate_path.DirName().value()); | |
| 507 EXPECT_TRUE(intermediate_path.MatchesExtension( | |
| 508 FILE_PATH_LITERAL(".crdownload"))); | |
| 509 break; | |
| 510 | |
| 511 case EXPECT_TARGET_PATH: | |
| 512 EXPECT_EQ(target_path.value(), intermediate_path.value()); | |
| 513 break; | |
| 514 } | |
| 515 } | 277 } |
| 516 | 278 |
| 517 const base::FilePath& ChromeDownloadManagerDelegateTest::default_download_path() | 279 const base::FilePath& ChromeDownloadManagerDelegateTest::default_download_path() |
| 518 const { | 280 const { |
| 519 return test_download_dir_.path(); | 281 return test_download_dir_.path(); |
| 520 } | 282 } |
| 521 | 283 |
| 522 TestChromeDownloadManagerDelegate* | 284 TestChromeDownloadManagerDelegate* |
| 523 ChromeDownloadManagerDelegateTest::delegate() { | 285 ChromeDownloadManagerDelegateTest::delegate() { |
| 524 return delegate_.get(); | 286 return delegate_.get(); |
| 525 } | 287 } |
| 526 | 288 |
| 527 content::MockDownloadManager* | 289 content::MockDownloadManager* |
| 528 ChromeDownloadManagerDelegateTest::download_manager() { | 290 ChromeDownloadManagerDelegateTest::download_manager() { |
| 529 return download_manager_.get(); | 291 return download_manager_.get(); |
| 530 } | 292 } |
| 531 | 293 |
| 532 DownloadPrefs* ChromeDownloadManagerDelegateTest::download_prefs() { | 294 DownloadPrefs* ChromeDownloadManagerDelegateTest::download_prefs() { |
| 533 return delegate_->download_prefs(); | 295 return delegate_->download_prefs(); |
| 534 } | 296 } |
| 535 | 297 |
| 536 } // namespace | 298 } // namespace |
| 537 | 299 |
| 538 TEST_F(ChromeDownloadManagerDelegateTest, StartDownload_Basic) { | |
| 539 const DownloadTestCase kBasicTestCases[] = { | |
| 540 { | |
| 541 // 0: Automatic Safe | |
| 542 AUTOMATIC, | |
| 543 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 544 "http://example.com/foo.txt", "text/plain", | |
| 545 FILE_PATH_LITERAL(""), | |
| 546 | |
| 547 FILE_PATH_LITERAL("foo.txt"), | |
| 548 FILE_PATH_LITERAL(""), | |
| 549 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 550 | |
| 551 EXPECT_CRDOWNLOAD | |
| 552 }, | |
| 553 | |
| 554 { | |
| 555 // 1: Save_As Safe | |
| 556 SAVE_AS, | |
| 557 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 558 "http://example.com/foo.txt", "text/plain", | |
| 559 FILE_PATH_LITERAL(""), | |
| 560 | |
| 561 FILE_PATH_LITERAL("foo.txt"), | |
| 562 FILE_PATH_LITERAL("foo.txt"), | |
| 563 DownloadItem::TARGET_DISPOSITION_PROMPT, | |
| 564 | |
| 565 EXPECT_CRDOWNLOAD | |
| 566 }, | |
| 567 | |
| 568 { | |
| 569 // 2: Automatic Dangerous | |
| 570 AUTOMATIC, | |
| 571 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, | |
| 572 "http://example.com/foo.exe", "", | |
| 573 FILE_PATH_LITERAL(""), | |
| 574 | |
| 575 FILE_PATH_LITERAL("foo.exe"), | |
| 576 FILE_PATH_LITERAL(""), | |
| 577 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 578 | |
| 579 EXPECT_UNCONFIRMED | |
| 580 }, | |
| 581 | |
| 582 { | |
| 583 // 3 Forced Safe | |
| 584 FORCED, | |
| 585 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 586 "http://example.com/foo.txt", "", | |
| 587 FILE_PATH_LITERAL("forced-foo.txt"), | |
| 588 | |
| 589 FILE_PATH_LITERAL("forced-foo.txt"), | |
| 590 FILE_PATH_LITERAL(""), | |
| 591 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 592 | |
| 593 EXPECT_TARGET_PATH | |
| 594 }, | |
| 595 | |
| 596 #if defined(FULL_SAFE_BROWSING) | |
| 597 // These test cases are only applicable if safe browsing is enabled. Without | |
| 598 // it, these are equivalent to FORCED/SAFE and SAFE_AS/SAFE respectively. | |
| 599 { | |
| 600 // 4: Forced Dangerous. As above. .jar is considered to be one of the file | |
| 601 // types supportred by safe browsing. | |
| 602 FORCED, | |
| 603 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, | |
| 604 "http://example.com/foo.exe", "", | |
| 605 FILE_PATH_LITERAL("forced-foo.exe"), | |
| 606 | |
| 607 FILE_PATH_LITERAL("forced-foo.exe"), | |
| 608 FILE_PATH_LITERAL(""), | |
| 609 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 610 | |
| 611 EXPECT_UNCONFIRMED | |
| 612 }, | |
| 613 | |
| 614 { | |
| 615 // 5: Save_As Dangerous. | |
| 616 SAVE_AS, | |
| 617 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, | |
| 618 "http://example.com/foo.exe", "", | |
| 619 FILE_PATH_LITERAL(""), | |
| 620 | |
| 621 FILE_PATH_LITERAL("foo.exe"), | |
| 622 FILE_PATH_LITERAL("foo.exe"), | |
| 623 DownloadItem::TARGET_DISPOSITION_PROMPT, | |
| 624 | |
| 625 EXPECT_UNCONFIRMED | |
| 626 } | |
| 627 #endif | |
| 628 }; | |
| 629 | |
| 630 RunTestCases(kBasicTestCases, arraysize(kBasicTestCases)); | |
| 631 } | |
| 632 | |
| 633 #if defined(FULL_SAFE_BROWSING) | |
| 634 // The SafeBrowsing URL check is performed early. Make sure that a download item | |
| 635 // that has been marked as DANGEROUS_URL behaves correctly. | |
| 636 TEST_F(ChromeDownloadManagerDelegateTest, StartDownload_DangerousURL) { | |
| 637 const DownloadTestCase kDangerousURLTestCases[] = { | |
| 638 { | |
| 639 // 0: Automatic Dangerous URL | |
| 640 AUTOMATIC, | |
| 641 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, | |
| 642 "http://phishing.example.com/foo.txt", "", | |
| 643 FILE_PATH_LITERAL(""), | |
| 644 | |
| 645 FILE_PATH_LITERAL("foo.txt"), | |
| 646 FILE_PATH_LITERAL(""), | |
| 647 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 648 | |
| 649 EXPECT_UNCONFIRMED | |
| 650 }, | |
| 651 | |
| 652 { | |
| 653 // 1: Save As Dangerous URL | |
| 654 SAVE_AS, | |
| 655 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, | |
| 656 "http://phishing.example.com/foo.txt", "", | |
| 657 FILE_PATH_LITERAL(""), | |
| 658 | |
| 659 FILE_PATH_LITERAL("foo.txt"), | |
| 660 FILE_PATH_LITERAL("foo.txt"), | |
| 661 DownloadItem::TARGET_DISPOSITION_PROMPT, | |
| 662 | |
| 663 EXPECT_UNCONFIRMED | |
| 664 }, | |
| 665 | |
| 666 { | |
| 667 // 2: Forced Dangerous URL | |
| 668 FORCED, | |
| 669 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, | |
| 670 "http://phishing.example.com/foo.txt", "", | |
| 671 FILE_PATH_LITERAL("forced-foo.txt"), | |
| 672 | |
| 673 FILE_PATH_LITERAL("forced-foo.txt"), | |
| 674 FILE_PATH_LITERAL(""), | |
| 675 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 676 | |
| 677 EXPECT_UNCONFIRMED | |
| 678 }, | |
| 679 | |
| 680 { | |
| 681 // 3: Automatic Dangerous URL + Dangerous file. Dangerous URL takes | |
| 682 // precendence. | |
| 683 AUTOMATIC, | |
| 684 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, | |
| 685 "http://phishing.example.com/foo.jar", "", | |
| 686 FILE_PATH_LITERAL(""), | |
| 687 | |
| 688 FILE_PATH_LITERAL("foo.jar"), | |
| 689 FILE_PATH_LITERAL(""), | |
| 690 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 691 | |
| 692 EXPECT_UNCONFIRMED | |
| 693 }, | |
| 694 | |
| 695 { | |
| 696 // 4: Save As Dangerous URL + Dangerous file | |
| 697 SAVE_AS, | |
| 698 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, | |
| 699 "http://phishing.example.com/foo.jar", "", | |
| 700 FILE_PATH_LITERAL(""), | |
| 701 | |
| 702 FILE_PATH_LITERAL("foo.jar"), | |
| 703 FILE_PATH_LITERAL("foo.jar"), | |
| 704 DownloadItem::TARGET_DISPOSITION_PROMPT, | |
| 705 | |
| 706 EXPECT_UNCONFIRMED | |
| 707 }, | |
| 708 | |
| 709 { | |
| 710 // 5: Forced Dangerous URL + Dangerous file | |
| 711 FORCED, | |
| 712 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, | |
| 713 "http://phishing.example.com/foo.jar", "", | |
| 714 FILE_PATH_LITERAL("forced-foo.jar"), | |
| 715 | |
| 716 FILE_PATH_LITERAL("forced-foo.jar"), | |
| 717 FILE_PATH_LITERAL(""), | |
| 718 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 719 | |
| 720 EXPECT_UNCONFIRMED | |
| 721 }, | |
| 722 }; | |
| 723 | |
| 724 RunTestCases(kDangerousURLTestCases, arraysize(kDangerousURLTestCases)); | |
| 725 } | |
| 726 #endif // FULL_SAFE_BROWSING | |
| 727 | |
| 728 // These test cases are run with "Prompt for download" user preference set to | |
| 729 // true. Even with the preference set, some of these downloads should not cause | |
| 730 // a prompt to appear. | |
| 731 TEST_F(ChromeDownloadManagerDelegateTest, StartDownload_PromptAlways) { | |
| 732 const DownloadTestCase kPromptingTestCases[] = { | |
| 733 { | |
| 734 // 0: Safe Automatic - Should prompt because of "Prompt for download" | |
| 735 // preference setting. | |
| 736 AUTOMATIC, | |
| 737 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 738 "http://example.com/foo.txt", "text/plain", | |
| 739 FILE_PATH_LITERAL(""), | |
| 740 | |
| 741 FILE_PATH_LITERAL("foo.txt"), | |
| 742 FILE_PATH_LITERAL("foo.txt"), | |
| 743 DownloadItem::TARGET_DISPOSITION_PROMPT, | |
| 744 | |
| 745 EXPECT_CRDOWNLOAD | |
| 746 }, | |
| 747 | |
| 748 { | |
| 749 // 1: Automatic Browser Extension download. - Shouldn't prompt for browser | |
| 750 // extension downloads even if "Prompt for download" preference is set. | |
| 751 AUTOMATIC, | |
| 752 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 753 "http://example.com/foo.crx", | |
| 754 extensions::Extension::kMimeType, | |
| 755 FILE_PATH_LITERAL(""), | |
| 756 | |
| 757 FILE_PATH_LITERAL("foo.crx"), | |
| 758 FILE_PATH_LITERAL(""), | |
| 759 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 760 | |
| 761 EXPECT_CRDOWNLOAD | |
| 762 }, | |
| 763 | |
| 764 { | |
| 765 // 2: Automatic User Script - Shouldn't prompt for user script downloads | |
| 766 // even if "Prompt for download" preference is set. | |
| 767 AUTOMATIC, | |
| 768 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 769 "http://example.com/foo.user.js", "", | |
| 770 FILE_PATH_LITERAL(""), | |
| 771 | |
| 772 FILE_PATH_LITERAL("foo.user.js"), | |
| 773 FILE_PATH_LITERAL(""), | |
| 774 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 775 | |
| 776 EXPECT_CRDOWNLOAD | |
| 777 }, | |
| 778 | |
| 779 { | |
| 780 // 3: Automatic - The filename extension is marked as one that we will | |
| 781 // open automatically. Shouldn't prompt. | |
| 782 AUTOMATIC, | |
| 783 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 784 "http://example.com/foo.dummy", "", | |
| 785 FILE_PATH_LITERAL(""), | |
| 786 | |
| 787 FILE_PATH_LITERAL("foo.dummy"), | |
| 788 FILE_PATH_LITERAL(""), | |
| 789 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 790 | |
| 791 EXPECT_CRDOWNLOAD | |
| 792 }, | |
| 793 | |
| 794 #if defined(FULL_SAFE_BROWSING) | |
| 795 // If safe browsing is disabled, this case is equivalent to AUTOMATIC/SAFE | |
| 796 // since the download isn't marked as dangerous when we are going to prompt | |
| 797 // the user. | |
| 798 { | |
| 799 // 4: Dangerous Automatic - Should prompt due to "Prompt for download" | |
| 800 // preference setting. | |
| 801 AUTOMATIC, | |
| 802 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, | |
| 803 "http://example.com/foo.exe", "", | |
| 804 FILE_PATH_LITERAL(""), | |
| 805 | |
| 806 FILE_PATH_LITERAL("foo.exe"), | |
| 807 FILE_PATH_LITERAL("foo.exe"), | |
| 808 DownloadItem::TARGET_DISPOSITION_PROMPT, | |
| 809 | |
| 810 EXPECT_UNCONFIRMED | |
| 811 }, | |
| 812 #endif | |
| 813 }; | |
| 814 | |
| 815 SetPromptForDownload(true); | |
| 816 EnableAutoOpenBasedOnExtension( | |
| 817 base::FilePath(FILE_PATH_LITERAL("dummy.dummy"))); | |
| 818 RunTestCases(kPromptingTestCases, arraysize(kPromptingTestCases)); | |
| 819 } | |
| 820 | |
| 821 // If the download path is managed, then we don't show any prompts. | |
| 822 // Note that if the download path is managed, then PromptForDownload() is false. | |
| 823 TEST_F(ChromeDownloadManagerDelegateTest, StartDownload_ManagedPath) { | |
| 824 const DownloadTestCase kManagedPathTestCases[] = { | |
| 825 { | |
| 826 // 0: Automatic Safe | |
| 827 AUTOMATIC, | |
| 828 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 829 "http://example.com/foo.txt", "text/plain", | |
| 830 FILE_PATH_LITERAL(""), | |
| 831 | |
| 832 FILE_PATH_LITERAL("foo.txt"), | |
| 833 FILE_PATH_LITERAL(""), | |
| 834 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 835 | |
| 836 EXPECT_CRDOWNLOAD | |
| 837 }, | |
| 838 | |
| 839 { | |
| 840 // 1: Save_As Safe | |
| 841 SAVE_AS, | |
| 842 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 843 "http://example.com/foo.txt", "text/plain", | |
| 844 FILE_PATH_LITERAL(""), | |
| 845 | |
| 846 FILE_PATH_LITERAL("foo.txt"), | |
| 847 FILE_PATH_LITERAL(""), | |
| 848 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 849 | |
| 850 EXPECT_CRDOWNLOAD | |
| 851 }, | |
| 852 }; | |
| 853 | |
| 854 SetManagedDownloadPath(default_download_path()); | |
| 855 ASSERT_TRUE(download_prefs()->IsDownloadPathManaged()); | |
| 856 RunTestCases(kManagedPathTestCases, arraysize(kManagedPathTestCases)); | |
| 857 } | |
| 858 | |
| 859 // Test whether the last saved directory is saved if the user was presented with | |
| 860 // a file chooser. | |
| 861 TEST_F(ChromeDownloadManagerDelegateTest, StartDownload_LastSavePath) { | 300 TEST_F(ChromeDownloadManagerDelegateTest, StartDownload_LastSavePath) { |
| 862 const DownloadTestCase kLastSavePathTestCases[] = { | 301 GURL download_url("http://example.com/foo.txt"); |
| 863 { | |
| 864 // Initially the last saved directory is the user's default download path. | |
| 865 | |
| 866 // 0: Start a Save As download. Then respond to the file chooser with | |
| 867 // foo/bar.txt as the target directory. This should cause the foo/ | |
| 868 // directory to be remembered as the last used save directory. | |
| 869 SAVE_AS, | |
| 870 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 871 "http://example.com/foo.txt", "text/plain", | |
| 872 FILE_PATH_LITERAL(""), | |
| 873 | |
| 874 FILE_PATH_LITERAL("foo/bar.txt"), | |
| 875 FILE_PATH_LITERAL("foo.txt"), | |
| 876 DownloadItem::TARGET_DISPOSITION_PROMPT, | |
| 877 | |
| 878 EXPECT_CRDOWNLOAD | |
| 879 }, | |
| 880 | |
| 881 { | |
| 882 // 1: Start another Save As download. This time the suggested path should | |
| 883 // be in the foo/ directory. | |
| 884 SAVE_AS, | |
| 885 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 886 "http://example.com/foo.txt", "text/plain", | |
| 887 FILE_PATH_LITERAL(""), | |
| 888 | |
| 889 FILE_PATH_LITERAL("bar/foo.txt"), | |
| 890 FILE_PATH_LITERAL("foo/foo.txt"), | |
| 891 DownloadItem::TARGET_DISPOSITION_PROMPT, | |
| 892 | |
| 893 EXPECT_CRDOWNLOAD | |
| 894 }, | |
| 895 | |
| 896 { | |
| 897 // 2: Start an automatic download. This should be saved to the user's | |
| 898 // default download directory and not the last used Save As directory. | |
| 899 AUTOMATIC, | |
| 900 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 901 "http://example.com/foo.txt", "text/plain", | |
| 902 FILE_PATH_LITERAL(""), | |
| 903 | |
| 904 FILE_PATH_LITERAL("foo.txt"), | |
| 905 FILE_PATH_LITERAL(""), | |
| 906 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 907 | |
| 908 EXPECT_CRDOWNLOAD | |
| 909 }, | |
| 910 }; | |
| 911 | |
| 912 RunTestCases(kLastSavePathTestCases, arraysize(kLastSavePathTestCases)); | |
| 913 | |
| 914 // Now clear the last download path. | |
| 915 delegate()->ClearLastDownloadPath(); | 302 delegate()->ClearLastDownloadPath(); |
| 916 | 303 |
| 917 // Run the first test case again. Since the last download path was cleared, | 304 scoped_ptr<content::MockDownloadItem> save_as_download( |
| 918 // this test case should behave identically to the first time it was run. | 305 CreateActiveDownloadItem(0)); |
| 919 RunTestCases(kLastSavePathTestCases, 1); | 306 EXPECT_CALL(*save_as_download, GetURL()) |
| 307 .Times(::testing::AnyNumber()) |
| 308 .WillRepeatedly(ReturnRef(download_url)); |
| 309 EXPECT_CALL(*save_as_download, GetTargetDisposition()) |
| 310 .Times(::testing::AnyNumber()) |
| 311 .WillRepeatedly(Return(DownloadItem::TARGET_DISPOSITION_PROMPT)); |
| 312 |
| 313 scoped_ptr<content::MockDownloadItem> automatic_download( |
| 314 CreateActiveDownloadItem(1)); |
| 315 EXPECT_CALL(*automatic_download, GetURL()) |
| 316 .Times(::testing::AnyNumber()) |
| 317 .WillRepeatedly(ReturnRef(download_url)); |
| 318 EXPECT_CALL(*automatic_download, GetTargetDisposition()) |
| 319 .Times(::testing::AnyNumber()) |
| 320 .WillRepeatedly(Return(DownloadItem::TARGET_DISPOSITION_OVERWRITE)); |
| 321 |
| 322 { |
| 323 // When the prompt is displayed for the first download, the user selects a |
| 324 // path in a different directory. |
| 325 DownloadTarget result; |
| 326 base::FilePath expected_prompt_path(GetPathInDownloadDir("foo.txt")); |
| 327 base::FilePath user_selected_path(GetPathInDownloadDir("bar/baz.txt")); |
| 328 EXPECT_CALL(*delegate(), |
| 329 MockPromptUserForDownloadPath(save_as_download.get(), |
| 330 expected_prompt_path, _)) |
| 331 .WillOnce(Return(user_selected_path)); |
| 332 DetermineDownloadTarget(save_as_download.get(), &result); |
| 333 EXPECT_EQ(user_selected_path, result.target_path); |
| 334 VerifyAndClearExpectations(); |
| 335 } |
| 336 |
| 337 { |
| 338 // The prompt path for the second download is the user selected directroy |
| 339 // from the previous download. |
| 340 DownloadTarget result; |
| 341 base::FilePath expected_prompt_path(GetPathInDownloadDir("bar/foo.txt")); |
| 342 EXPECT_CALL(*delegate(), |
| 343 MockPromptUserForDownloadPath(save_as_download.get(), |
| 344 expected_prompt_path, _)) |
| 345 .WillOnce(Return(base::FilePath())); |
| 346 DetermineDownloadTarget(save_as_download.get(), &result); |
| 347 VerifyAndClearExpectations(); |
| 348 } |
| 349 |
| 350 { |
| 351 // Start an automatic download. This one should get the default download |
| 352 // path since the last download path only affects Save As downloads. |
| 353 DownloadTarget result; |
| 354 base::FilePath expected_path(GetPathInDownloadDir("foo.txt")); |
| 355 DetermineDownloadTarget(automatic_download.get(), &result); |
| 356 EXPECT_EQ(expected_path, result.target_path); |
| 357 VerifyAndClearExpectations(); |
| 358 } |
| 359 |
| 360 // Clear the last download path. |
| 361 delegate()->ClearLastDownloadPath(); |
| 362 |
| 363 { |
| 364 // The prompt path for the next download should be the default. |
| 365 DownloadTarget result; |
| 366 base::FilePath expected_prompt_path(GetPathInDownloadDir("foo.txt")); |
| 367 EXPECT_CALL(*delegate(), |
| 368 MockPromptUserForDownloadPath(save_as_download.get(), |
| 369 expected_prompt_path, _)) |
| 370 .WillOnce(Return(base::FilePath())); |
| 371 DetermineDownloadTarget(save_as_download.get(), &result); |
| 372 VerifyAndClearExpectations(); |
| 373 } |
| 920 } | 374 } |
| 921 | |
| 922 // TODO(asanka): Add more tests. | |
| 923 // * Default download path is not writable. | |
| 924 // * Download path doesn't exist. | |
| 925 // * IsDangerousFile(). | |
| 926 // * Filename generation. | |
| OLD | NEW |