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 <stddef.h> | 5 #include <stddef.h> |
6 #include <stdint.h> | 6 #include <stdint.h> |
7 | 7 |
| 8 #include <string> |
| 9 |
8 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
9 #include "base/files/file_util.h" | 11 #include "base/files/file_util.h" |
10 #include "base/files/scoped_temp_dir.h" | 12 #include "base/files/scoped_temp_dir.h" |
11 #include "base/location.h" | 13 #include "base/location.h" |
| 14 #include "base/memory/ptr_util.h" |
12 #include "base/run_loop.h" | 15 #include "base/run_loop.h" |
13 #include "base/single_thread_task_runner.h" | 16 #include "base/single_thread_task_runner.h" |
14 #include "base/threading/thread_task_runner_handle.h" | 17 #include "base/threading/thread_task_runner_handle.h" |
15 #include "build/build_config.h" | 18 #include "build/build_config.h" |
16 #include "chrome/browser/download/chrome_download_manager_delegate.h" | 19 #include "chrome/browser/download/chrome_download_manager_delegate.h" |
17 #include "chrome/browser/download/download_item_model.h" | 20 #include "chrome/browser/download/download_item_model.h" |
18 #include "chrome/browser/download/download_prefs.h" | 21 #include "chrome/browser/download/download_prefs.h" |
19 #include "chrome/browser/download/download_target_info.h" | 22 #include "chrome/browser/download/download_target_info.h" |
| 23 #include "chrome/common/features.h" |
20 #include "chrome/common/pref_names.h" | 24 #include "chrome/common/pref_names.h" |
21 #include "chrome/test/base/chrome_render_view_host_test_harness.h" | 25 #include "chrome/test/base/chrome_render_view_host_test_harness.h" |
22 #include "chrome/test/base/testing_profile.h" | 26 #include "chrome/test/base/testing_profile.h" |
23 #include "components/prefs/pref_service.h" | 27 #include "components/prefs/pref_service.h" |
24 #include "components/sync_preferences/testing_pref_service_syncable.h" | 28 #include "components/sync_preferences/testing_pref_service_syncable.h" |
25 #include "content/public/browser/download_interrupt_reasons.h" | 29 #include "content/public/browser/download_interrupt_reasons.h" |
26 #include "content/public/browser/web_contents.h" | 30 #include "content/public/browser/web_contents.h" |
27 #include "content/public/browser/web_contents_delegate.h" | 31 #include "content/public/browser/web_contents_delegate.h" |
28 #include "content/public/test/mock_download_item.h" | 32 #include "content/public/test/mock_download_item.h" |
29 #include "content/public/test/mock_download_manager.h" | 33 #include "content/public/test/mock_download_manager.h" |
30 #include "content/public/test/test_renderer_host.h" | 34 #include "content/public/test/test_renderer_host.h" |
31 #include "content/public/test/web_contents_tester.h" | 35 #include "content/public/test/web_contents_tester.h" |
32 #include "testing/gmock/include/gmock/gmock.h" | 36 #include "testing/gmock/include/gmock/gmock.h" |
33 #include "testing/gtest/include/gtest/gtest.h" | 37 #include "testing/gtest/include/gtest/gtest.h" |
34 | 38 |
35 #if defined(FULL_SAFE_BROWSING) | 39 #if defined(FULL_SAFE_BROWSING) |
36 #include "chrome/browser/safe_browsing/download_protection_service.h" | 40 #include "chrome/browser/safe_browsing/download_protection_service.h" |
37 #endif | 41 #endif |
38 | 42 |
39 #if !defined(OS_ANDROID) | 43 #if BUILDFLAG(ENABLE_PLUGINS) |
40 #include "content/public/browser/plugin_service.h" | 44 #include "content/public/browser/plugin_service.h" |
41 #endif | 45 #endif |
42 | 46 |
| 47 #if defined(OS_ANDROID) |
| 48 #include "chrome/browser/infobars/infobar_service.h" |
| 49 #include "components/infobars/core/infobar.h" |
| 50 #include "components/infobars/core/infobar_delegate.h" |
| 51 #include "components/infobars/core/infobar_manager.h" |
| 52 #endif |
| 53 |
| 54 using ::testing::AnyNumber; |
43 using ::testing::AtMost; | 55 using ::testing::AtMost; |
| 56 using ::testing::DoAll; |
44 using ::testing::Invoke; | 57 using ::testing::Invoke; |
45 using ::testing::Ref; | 58 using ::testing::Ref; |
46 using ::testing::Return; | 59 using ::testing::Return; |
| 60 using ::testing::ReturnArg; |
47 using ::testing::ReturnPointee; | 61 using ::testing::ReturnPointee; |
48 using ::testing::ReturnRef; | 62 using ::testing::ReturnRef; |
49 using ::testing::ReturnRefOfCopy; | 63 using ::testing::ReturnRefOfCopy; |
50 using ::testing::SetArgPointee; | 64 using ::testing::SetArgPointee; |
51 using ::testing::WithArg; | 65 using ::testing::WithArg; |
52 using ::testing::_; | 66 using ::testing::_; |
53 using content::DownloadItem; | 67 using content::DownloadItem; |
54 using safe_browsing::DownloadFileType; | 68 using safe_browsing::DownloadFileType; |
55 | 69 |
56 namespace { | 70 namespace { |
(...skipping 19 matching lines...) Expand all Loading... |
76 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | 90 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
77 base::Bind(arg0, result)); | 91 base::Bind(arg0, result)); |
78 } | 92 } |
79 | 93 |
80 // Similar to ScheduleCallback, but binds 2 arguments. | 94 // Similar to ScheduleCallback, but binds 2 arguments. |
81 ACTION_P2(ScheduleCallback2, result0, result1) { | 95 ACTION_P2(ScheduleCallback2, result0, result1) { |
82 base::ThreadTaskRunnerHandle::Get()->PostTask( | 96 base::ThreadTaskRunnerHandle::Get()->PostTask( |
83 FROM_HERE, base::Bind(arg0, result0, result1)); | 97 FROM_HERE, base::Bind(arg0, result0, result1)); |
84 } | 98 } |
85 | 99 |
86 // Subclass of the ChromeDownloadManagerDelegate that uses a mock | 100 // Struct for holding the result of calling DetermineDownloadTarget. |
87 // DownloadProtectionService. | 101 struct DetermineDownloadTargetResult { |
| 102 DetermineDownloadTargetResult(); |
| 103 |
| 104 base::FilePath target_path; |
| 105 content::DownloadItem::TargetDisposition disposition; |
| 106 content::DownloadDangerType danger_type; |
| 107 base::FilePath intermediate_path; |
| 108 content::DownloadInterruptReason interrupt_reason; |
| 109 }; |
| 110 |
| 111 DetermineDownloadTargetResult::DetermineDownloadTargetResult() |
| 112 : disposition(content::DownloadItem::TARGET_DISPOSITION_OVERWRITE), |
| 113 danger_type(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS), |
| 114 interrupt_reason(content::DOWNLOAD_INTERRUPT_REASON_NONE) {} |
| 115 |
| 116 // Subclass of the ChromeDownloadManagerDelegate that replaces a few interaction |
| 117 // points for ease of testing. |
88 class TestChromeDownloadManagerDelegate : public ChromeDownloadManagerDelegate { | 118 class TestChromeDownloadManagerDelegate : public ChromeDownloadManagerDelegate { |
89 public: | 119 public: |
90 explicit TestChromeDownloadManagerDelegate(Profile* profile) | 120 explicit TestChromeDownloadManagerDelegate(Profile* profile) |
91 : ChromeDownloadManagerDelegate(profile) { | 121 : ChromeDownloadManagerDelegate(profile) { |
92 ON_CALL(*this, MockCheckDownloadUrl(_, _)) | 122 ON_CALL(*this, MockCheckDownloadUrl(_, _)) |
93 .WillByDefault(Return(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS)); | 123 .WillByDefault(Return(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS)); |
94 ON_CALL(*this, GetDownloadProtectionService()) | 124 ON_CALL(*this, GetDownloadProtectionService()) |
95 .WillByDefault(Return(nullptr)); | 125 .WillByDefault(Return(nullptr)); |
| 126 ON_CALL(*this, MockReserveVirtualPath(_, _, _, _, _)) |
| 127 .WillByDefault(DoAll(SetArgPointee<4>(PathValidationResult::SUCCESS), |
| 128 ReturnArg<1>())); |
96 } | 129 } |
97 | 130 |
98 ~TestChromeDownloadManagerDelegate() override {} | 131 ~TestChromeDownloadManagerDelegate() override {} |
99 | 132 |
| 133 // The concrete implementation talks to the ExtensionDownloadsEventRouter to |
| 134 // dispatch a OnDeterminingFilename event. While we would like to test this as |
| 135 // well in this unit test, we are currently going to rely on the extension |
| 136 // browser test to provide test coverage here. Instead we are going to mock it |
| 137 // out for unit tests. |
100 void NotifyExtensions(content::DownloadItem* download, | 138 void NotifyExtensions(content::DownloadItem* download, |
101 const base::FilePath& suggested_virtual_path, | 139 const base::FilePath& suggested_virtual_path, |
102 const NotifyExtensionsCallback& callback) override { | 140 const NotifyExtensionsCallback& callback) override { |
103 callback.Run(base::FilePath(), | 141 callback.Run(base::FilePath(), |
104 DownloadPathReservationTracker::UNIQUIFY); | 142 DownloadPathReservationTracker::UNIQUIFY); |
105 } | 143 } |
106 | 144 |
| 145 // DownloadPathReservationTracker talks to the underlying file system. For |
| 146 // tests we are going to mock it out so that we can test how |
| 147 // ChromeDownloadManagerDelegate reponds to various DownloadTargetDeterminer |
| 148 // results. |
107 void ReserveVirtualPath( | 149 void ReserveVirtualPath( |
108 content::DownloadItem* download, | 150 content::DownloadItem* download, |
109 const base::FilePath& virtual_path, | 151 const base::FilePath& virtual_path, |
110 bool create_directory, | 152 bool create_directory, |
111 DownloadPathReservationTracker::FilenameConflictAction conflict_action, | 153 DownloadPathReservationTracker::FilenameConflictAction conflict_action, |
112 const DownloadPathReservationTracker::ReservedPathCallback& callback) | 154 const DownloadPathReservationTracker::ReservedPathCallback& callback) |
113 override { | 155 override { |
114 // Pretend the path reservation succeeded without any change to | 156 PathValidationResult result = PathValidationResult::SUCCESS; |
115 // |target_path|. | 157 base::FilePath path_to_return = MockReserveVirtualPath( |
| 158 download, virtual_path, create_directory, conflict_action, &result); |
116 base::ThreadTaskRunnerHandle::Get()->PostTask( | 159 base::ThreadTaskRunnerHandle::Get()->PostTask( |
117 FROM_HERE, base::Bind(callback, virtual_path, true)); | 160 FROM_HERE, base::Bind(callback, result, path_to_return)); |
118 } | 161 } |
119 | 162 |
120 void PromptUserForDownloadPath( | 163 MOCK_METHOD5( |
121 DownloadItem* download, | 164 MockReserveVirtualPath, |
122 const base::FilePath& suggested_path, | 165 base::FilePath(content::DownloadItem*, |
123 const DownloadTargetDeterminerDelegate::FileSelectedCallback& callback) | 166 const base::FilePath&, |
124 override { | 167 bool, |
125 base::FilePath return_path = MockPromptUserForDownloadPath(download, | 168 DownloadPathReservationTracker::FilenameConflictAction, |
126 suggested_path, | 169 PathValidationResult*)); |
127 callback); | |
128 callback.Run(return_path); | |
129 } | |
130 | 170 |
| 171 // The concrete implementation invokes SafeBrowsing's |
| 172 // DownloadProtectionService. Now that SafeBrowsingService is testable, we |
| 173 // should migrate to using TestSafeBrowsingService instead. |
131 void CheckDownloadUrl(DownloadItem* download, | 174 void CheckDownloadUrl(DownloadItem* download, |
132 const base::FilePath& virtual_path, | 175 const base::FilePath& virtual_path, |
133 const CheckDownloadUrlCallback& callback) override { | 176 const CheckDownloadUrlCallback& callback) override { |
134 callback.Run(MockCheckDownloadUrl(download, virtual_path)); | 177 callback.Run(MockCheckDownloadUrl(download, virtual_path)); |
135 } | 178 } |
136 | 179 |
| 180 MOCK_METHOD2(MockCheckDownloadUrl, |
| 181 content::DownloadDangerType(DownloadItem*, |
| 182 const base::FilePath&)); |
| 183 |
137 MOCK_METHOD0(GetDownloadProtectionService, | 184 MOCK_METHOD0(GetDownloadProtectionService, |
138 safe_browsing::DownloadProtectionService*()); | 185 safe_browsing::DownloadProtectionService*()); |
139 | 186 |
140 MOCK_METHOD3( | 187 // The concrete implementation on desktop just invokes a file picker. Android |
141 MockPromptUserForDownloadPath, | 188 // has a non-trivial implementation. The former is tested via browser tests, |
142 base::FilePath( | 189 // and the latter is exercised in this unit test. |
143 DownloadItem*, | 190 MOCK_METHOD4( |
144 const base::FilePath&, | 191 RequestConfirmation, |
145 const DownloadTargetDeterminerDelegate::FileSelectedCallback&)); | 192 void(DownloadItem*, |
| 193 const base::FilePath&, |
| 194 DownloadConfirmationReason, |
| 195 const DownloadTargetDeterminerDelegate::ConfirmationCallback&)); |
146 | 196 |
147 MOCK_METHOD2(MockCheckDownloadUrl, | 197 // For testing the concrete implementation. |
148 content::DownloadDangerType(DownloadItem*, | 198 void RequestConfirmationConcrete( |
149 const base::FilePath&)); | 199 DownloadItem* download_item, |
| 200 const base::FilePath& path, |
| 201 DownloadConfirmationReason reason, |
| 202 const DownloadTargetDeterminerDelegate::ConfirmationCallback& callback) { |
| 203 ChromeDownloadManagerDelegate::RequestConfirmation(download_item, path, |
| 204 reason, callback); |
| 205 } |
150 }; | 206 }; |
151 | 207 |
152 class ChromeDownloadManagerDelegateTest | 208 class ChromeDownloadManagerDelegateTest |
153 : public ChromeRenderViewHostTestHarness { | 209 : public ChromeRenderViewHostTestHarness { |
154 public: | 210 public: |
| 211 // Result of calling DetermineDownloadTarget. |
155 ChromeDownloadManagerDelegateTest(); | 212 ChromeDownloadManagerDelegateTest(); |
156 | 213 |
157 // ::testing::Test | 214 // ::testing::Test |
158 void SetUp() override; | 215 void SetUp() override; |
159 void TearDown() override; | 216 void TearDown() override; |
160 | 217 |
161 // Verifies and clears test expectations for |delegate_| and | 218 // Verifies and clears test expectations for |delegate_| and |
162 // |download_manager_|. | 219 // |download_manager_|. |
163 void VerifyAndClearExpectations(); | 220 void VerifyAndClearExpectations(); |
164 | 221 |
165 // Creates MockDownloadItem and sets up default expectations. | 222 // Creates MockDownloadItem and sets up default expectations. |
166 std::unique_ptr<content::MockDownloadItem> CreateActiveDownloadItem( | 223 std::unique_ptr<content::MockDownloadItem> CreateActiveDownloadItem( |
167 int32_t id); | 224 int32_t id); |
168 | 225 |
169 // Given the relative path |path|, returns the full path under the temporary | 226 // Given the relative path |path|, returns the full path under the temporary |
170 // downloads directory. | 227 // downloads directory. |
171 base::FilePath GetPathInDownloadDir(const char* path); | 228 base::FilePath GetPathInDownloadDir(const char* path); |
172 | 229 |
173 // Set the kDownloadDefaultDirectory user preference to |path|. | 230 // Set the kDownloadDefaultDirectory user preference to |path|. |
174 void SetDefaultDownloadPath(const base::FilePath& path); | 231 void SetDefaultDownloadPath(const base::FilePath& path); |
175 | 232 |
176 void DetermineDownloadTarget(DownloadItem* download, | 233 void DetermineDownloadTarget(DownloadItem* download, |
177 DownloadTargetInfo* result); | 234 DetermineDownloadTargetResult* result); |
178 | 235 |
179 // Invokes ChromeDownloadManagerDelegate::CheckForFileExistence and waits for | 236 // Invokes ChromeDownloadManagerDelegate::CheckForFileExistence and waits for |
180 // the asynchronous callback. The result passed into | 237 // the asynchronous callback. The result passed into |
181 // content::CheckForFileExistenceCallback is the return value from this | 238 // content::CheckForFileExistenceCallback is the return value from this |
182 // method. | 239 // method. |
183 bool CheckForFileExistence(DownloadItem* download); | 240 bool CheckForFileExistence(DownloadItem* download); |
184 | 241 |
185 const base::FilePath& default_download_path() const; | 242 const base::FilePath& default_download_path() const; |
186 TestChromeDownloadManagerDelegate* delegate(); | 243 TestChromeDownloadManagerDelegate* delegate(); |
187 content::MockDownloadManager* download_manager(); | 244 content::MockDownloadManager* download_manager(); |
188 DownloadPrefs* download_prefs(); | 245 DownloadPrefs* download_prefs(); |
189 | 246 |
190 private: | 247 private: |
191 sync_preferences::TestingPrefServiceSyncable* pref_service_; | 248 sync_preferences::TestingPrefServiceSyncable* pref_service_; |
192 base::ScopedTempDir test_download_dir_; | 249 base::ScopedTempDir test_download_dir_; |
193 std::unique_ptr<content::MockDownloadManager> download_manager_; | 250 std::unique_ptr<content::MockDownloadManager> download_manager_; |
194 std::unique_ptr<TestChromeDownloadManagerDelegate> delegate_; | 251 std::unique_ptr<TestChromeDownloadManagerDelegate> delegate_; |
195 MockWebContentsDelegate web_contents_delegate_; | 252 MockWebContentsDelegate web_contents_delegate_; |
196 }; | 253 }; |
197 | 254 |
198 ChromeDownloadManagerDelegateTest::ChromeDownloadManagerDelegateTest() | 255 ChromeDownloadManagerDelegateTest::ChromeDownloadManagerDelegateTest() |
199 : download_manager_(new ::testing::NiceMock<content::MockDownloadManager>) { | 256 : download_manager_(new ::testing::NiceMock<content::MockDownloadManager>) { |
200 } | 257 } |
201 | 258 |
202 void ChromeDownloadManagerDelegateTest::SetUp() { | 259 void ChromeDownloadManagerDelegateTest::SetUp() { |
203 ChromeRenderViewHostTestHarness::SetUp(); | 260 ChromeRenderViewHostTestHarness::SetUp(); |
204 | 261 |
205 CHECK(profile()); | 262 CHECK(profile()); |
206 delegate_.reset(new TestChromeDownloadManagerDelegate(profile())); | 263 delegate_ = |
| 264 base::MakeUnique<::testing::NiceMock<TestChromeDownloadManagerDelegate>>( |
| 265 profile()); |
207 delegate_->SetDownloadManager(download_manager_.get()); | 266 delegate_->SetDownloadManager(download_manager_.get()); |
208 pref_service_ = profile()->GetTestingPrefService(); | 267 pref_service_ = profile()->GetTestingPrefService(); |
209 web_contents()->SetDelegate(&web_contents_delegate_); | 268 web_contents()->SetDelegate(&web_contents_delegate_); |
210 | 269 |
211 ASSERT_TRUE(test_download_dir_.CreateUniqueTempDir()); | 270 ASSERT_TRUE(test_download_dir_.CreateUniqueTempDir()); |
212 SetDefaultDownloadPath(test_download_dir_.GetPath()); | 271 SetDefaultDownloadPath(test_download_dir_.GetPath()); |
213 } | 272 } |
214 | 273 |
215 void ChromeDownloadManagerDelegateTest::TearDown() { | 274 void ChromeDownloadManagerDelegateTest::TearDown() { |
216 base::RunLoop().RunUntilIdle(); | 275 base::RunLoop().RunUntilIdle(); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 test_download_dir_.GetPath().AppendASCII(relative_path); | 326 test_download_dir_.GetPath().AppendASCII(relative_path); |
268 return full_path.NormalizePathSeparators(); | 327 return full_path.NormalizePathSeparators(); |
269 } | 328 } |
270 | 329 |
271 void ChromeDownloadManagerDelegateTest::SetDefaultDownloadPath( | 330 void ChromeDownloadManagerDelegateTest::SetDefaultDownloadPath( |
272 const base::FilePath& path) { | 331 const base::FilePath& path) { |
273 pref_service_->SetFilePath(prefs::kDownloadDefaultDirectory, path); | 332 pref_service_->SetFilePath(prefs::kDownloadDefaultDirectory, path); |
274 pref_service_->SetFilePath(prefs::kSaveFileDefaultDirectory, path); | 333 pref_service_->SetFilePath(prefs::kSaveFileDefaultDirectory, path); |
275 } | 334 } |
276 | 335 |
277 void StoreDownloadTargetInfo(const base::Closure& closure, | 336 void StoreDownloadTargetInfo( |
278 DownloadTargetInfo* target_info, | 337 const base::Closure& closure, |
279 const base::FilePath& target_path, | 338 DetermineDownloadTargetResult* result, |
280 DownloadItem::TargetDisposition target_disposition, | 339 const base::FilePath& target_path, |
281 content::DownloadDangerType danger_type, | 340 DownloadItem::TargetDisposition target_disposition, |
282 const base::FilePath& intermediate_path) { | 341 content::DownloadDangerType danger_type, |
283 target_info->target_path = target_path; | 342 const base::FilePath& intermediate_path, |
284 target_info->target_disposition = target_disposition; | 343 content::DownloadInterruptReason interrupt_reason) { |
285 target_info->danger_type = danger_type; | 344 result->target_path = target_path; |
286 target_info->intermediate_path = intermediate_path; | 345 result->disposition = target_disposition; |
| 346 result->danger_type = danger_type; |
| 347 result->intermediate_path = intermediate_path; |
| 348 result->interrupt_reason = interrupt_reason; |
287 closure.Run(); | 349 closure.Run(); |
288 } | 350 } |
289 | 351 |
290 void ChromeDownloadManagerDelegateTest::DetermineDownloadTarget( | 352 void ChromeDownloadManagerDelegateTest::DetermineDownloadTarget( |
291 DownloadItem* download_item, | 353 DownloadItem* download_item, |
292 DownloadTargetInfo* result) { | 354 DetermineDownloadTargetResult* result) { |
293 base::RunLoop loop_runner; | 355 base::RunLoop loop_runner; |
294 delegate()->DetermineDownloadTarget( | 356 delegate()->DetermineDownloadTarget( |
295 download_item, | 357 download_item, |
296 base::Bind(&StoreDownloadTargetInfo, loop_runner.QuitClosure(), result)); | 358 base::Bind(&StoreDownloadTargetInfo, loop_runner.QuitClosure(), result)); |
297 loop_runner.Run(); | 359 loop_runner.Run(); |
298 } | 360 } |
299 | 361 |
300 void StoreBoolAndRunClosure(const base::Closure& closure, | 362 void StoreBoolAndRunClosure(const base::Closure& closure, |
301 bool* result_storage, | 363 bool* result_storage, |
302 bool result) { | 364 bool result) { |
(...skipping 26 matching lines...) Expand all Loading... |
329 ChromeDownloadManagerDelegateTest::download_manager() { | 391 ChromeDownloadManagerDelegateTest::download_manager() { |
330 return download_manager_.get(); | 392 return download_manager_.get(); |
331 } | 393 } |
332 | 394 |
333 DownloadPrefs* ChromeDownloadManagerDelegateTest::download_prefs() { | 395 DownloadPrefs* ChromeDownloadManagerDelegateTest::download_prefs() { |
334 return delegate_->download_prefs(); | 396 return delegate_->download_prefs(); |
335 } | 397 } |
336 | 398 |
337 } // namespace | 399 } // namespace |
338 | 400 |
339 // There is no "save as" context menu option on Android. | 401 TEST_F(ChromeDownloadManagerDelegateTest, LastSavePath) { |
340 #if !defined(OS_ANDROID) | |
341 TEST_F(ChromeDownloadManagerDelegateTest, StartDownload_LastSavePath) { | |
342 GURL download_url("http://example.com/foo.txt"); | 402 GURL download_url("http://example.com/foo.txt"); |
343 | 403 |
344 std::unique_ptr<content::MockDownloadItem> save_as_download = | 404 std::unique_ptr<content::MockDownloadItem> save_as_download = |
345 CreateActiveDownloadItem(0); | 405 CreateActiveDownloadItem(0); |
346 EXPECT_CALL(*save_as_download, GetURL()) | 406 EXPECT_CALL(*save_as_download, GetURL()) |
347 .Times(::testing::AnyNumber()) | 407 .Times(AnyNumber()) |
348 .WillRepeatedly(ReturnRef(download_url)); | 408 .WillRepeatedly(ReturnRef(download_url)); |
349 EXPECT_CALL(*save_as_download, GetTargetDisposition()) | 409 EXPECT_CALL(*save_as_download, GetTargetDisposition()) |
350 .Times(::testing::AnyNumber()) | 410 .Times(AnyNumber()) |
351 .WillRepeatedly(Return(DownloadItem::TARGET_DISPOSITION_PROMPT)); | 411 .WillRepeatedly(Return(DownloadItem::TARGET_DISPOSITION_PROMPT)); |
352 | 412 |
353 std::unique_ptr<content::MockDownloadItem> automatic_download = | 413 std::unique_ptr<content::MockDownloadItem> automatic_download = |
354 CreateActiveDownloadItem(1); | 414 CreateActiveDownloadItem(1); |
355 EXPECT_CALL(*automatic_download, GetURL()) | 415 EXPECT_CALL(*automatic_download, GetURL()) |
356 .Times(::testing::AnyNumber()) | 416 .Times(AnyNumber()) |
357 .WillRepeatedly(ReturnRef(download_url)); | 417 .WillRepeatedly(ReturnRef(download_url)); |
358 EXPECT_CALL(*automatic_download, GetTargetDisposition()) | 418 EXPECT_CALL(*automatic_download, GetTargetDisposition()) |
359 .Times(::testing::AnyNumber()) | 419 .Times(AnyNumber()) |
360 .WillRepeatedly(Return(DownloadItem::TARGET_DISPOSITION_OVERWRITE)); | 420 .WillRepeatedly(Return(DownloadItem::TARGET_DISPOSITION_OVERWRITE)); |
361 | 421 |
362 { | 422 { |
363 // When the prompt is displayed for the first download, the user selects a | 423 // When the prompt is displayed for the first download, the user selects a |
364 // path in a different directory. | 424 // path in a different directory. |
365 DownloadTargetInfo result; | 425 DetermineDownloadTargetResult result; |
366 base::FilePath expected_prompt_path(GetPathInDownloadDir("foo.txt")); | 426 base::FilePath expected_prompt_path(GetPathInDownloadDir("foo.txt")); |
367 base::FilePath user_selected_path(GetPathInDownloadDir("bar/baz.txt")); | 427 base::FilePath user_selected_path(GetPathInDownloadDir("bar/baz.txt")); |
368 EXPECT_CALL(*delegate(), | 428 EXPECT_CALL(*delegate(), RequestConfirmation(save_as_download.get(), |
369 MockPromptUserForDownloadPath(save_as_download.get(), | 429 expected_prompt_path, _, _)) |
370 expected_prompt_path, _)) | 430 .WillOnce(WithArg<3>(ScheduleCallback2( |
371 .WillOnce(Return(user_selected_path)); | 431 DownloadConfirmationResult::CONFIRMED, user_selected_path))); |
372 DetermineDownloadTarget(save_as_download.get(), &result); | 432 DetermineDownloadTarget(save_as_download.get(), &result); |
373 EXPECT_EQ(user_selected_path, result.target_path); | 433 EXPECT_EQ(user_selected_path, result.target_path); |
374 VerifyAndClearExpectations(); | 434 VerifyAndClearExpectations(); |
375 } | 435 } |
376 | 436 |
377 { | 437 { |
378 // The prompt path for the second download is the user selected directroy | 438 // The prompt path for the second download is the user selected directory |
379 // from the previous download. | 439 // from the previous download. |
380 DownloadTargetInfo result; | 440 DetermineDownloadTargetResult result; |
381 base::FilePath expected_prompt_path(GetPathInDownloadDir("bar/foo.txt")); | 441 base::FilePath expected_prompt_path(GetPathInDownloadDir("bar/foo.txt")); |
382 EXPECT_CALL(*delegate(), | 442 EXPECT_CALL(*delegate(), RequestConfirmation(save_as_download.get(), |
383 MockPromptUserForDownloadPath(save_as_download.get(), | 443 expected_prompt_path, _, _)) |
384 expected_prompt_path, _)) | 444 .WillOnce(WithArg<3>(ScheduleCallback2( |
385 .WillOnce(Return(base::FilePath())); | 445 DownloadConfirmationResult::CANCELED, base::FilePath()))); |
386 DetermineDownloadTarget(save_as_download.get(), &result); | 446 DetermineDownloadTarget(save_as_download.get(), &result); |
387 VerifyAndClearExpectations(); | 447 VerifyAndClearExpectations(); |
388 } | 448 } |
389 | 449 |
390 { | 450 { |
391 // Start an automatic download. This one should get the default download | 451 // Start an automatic download. This one should get the default download |
392 // path since the last download path only affects Save As downloads. | 452 // path since the last download path only affects Save As downloads. |
393 DownloadTargetInfo result; | 453 DetermineDownloadTargetResult result; |
394 base::FilePath expected_path(GetPathInDownloadDir("foo.txt")); | 454 base::FilePath expected_path(GetPathInDownloadDir("foo.txt")); |
395 DetermineDownloadTarget(automatic_download.get(), &result); | 455 DetermineDownloadTarget(automatic_download.get(), &result); |
396 EXPECT_EQ(expected_path, result.target_path); | 456 EXPECT_EQ(expected_path, result.target_path); |
397 VerifyAndClearExpectations(); | 457 VerifyAndClearExpectations(); |
398 } | 458 } |
399 | 459 |
400 { | 460 { |
401 // The prompt path for the next download should be the default. | 461 // The prompt path for the next download should be the default. |
402 download_prefs()->SetSaveFilePath(download_prefs()->DownloadPath()); | 462 download_prefs()->SetSaveFilePath(download_prefs()->DownloadPath()); |
403 DownloadTargetInfo result; | 463 DetermineDownloadTargetResult result; |
404 base::FilePath expected_prompt_path(GetPathInDownloadDir("foo.txt")); | 464 base::FilePath expected_prompt_path(GetPathInDownloadDir("foo.txt")); |
405 EXPECT_CALL(*delegate(), | 465 EXPECT_CALL(*delegate(), RequestConfirmation(save_as_download.get(), |
406 MockPromptUserForDownloadPath(save_as_download.get(), | 466 expected_prompt_path, _, _)) |
407 expected_prompt_path, _)) | 467 .WillOnce(WithArg<3>(ScheduleCallback2( |
408 .WillOnce(Return(base::FilePath())); | 468 DownloadConfirmationResult::CANCELED, base::FilePath()))); |
409 DetermineDownloadTarget(save_as_download.get(), &result); | 469 DetermineDownloadTarget(save_as_download.get(), &result); |
410 VerifyAndClearExpectations(); | 470 VerifyAndClearExpectations(); |
411 } | 471 } |
412 } | 472 } |
413 #endif // !defined(OS_ANDROID) | 473 |
| 474 TEST_F(ChromeDownloadManagerDelegateTest, ConflictAction) { |
| 475 const GURL kUrl("http://example.com/foo"); |
| 476 const std::string kTargetDisposition("attachment; filename=\"foo.txt\""); |
| 477 |
| 478 std::unique_ptr<content::MockDownloadItem> download_item = |
| 479 CreateActiveDownloadItem(0); |
| 480 EXPECT_CALL(*download_item, GetURL()).WillRepeatedly(ReturnRef(kUrl)); |
| 481 EXPECT_CALL(*download_item, GetContentDisposition()) |
| 482 .WillRepeatedly(Return(kTargetDisposition)); |
| 483 |
| 484 base::FilePath kExpectedPath = GetPathInDownloadDir("bar.txt"); |
| 485 |
| 486 DetermineDownloadTargetResult result; |
| 487 |
| 488 EXPECT_CALL(*delegate(), MockReserveVirtualPath(_, _, _, _, _)) |
| 489 .WillOnce(DoAll(SetArgPointee<4>(PathValidationResult::CONFLICT), |
| 490 ReturnArg<1>())); |
| 491 EXPECT_CALL( |
| 492 *delegate(), |
| 493 RequestConfirmation(_, _, DownloadConfirmationReason::TARGET_CONFLICT, _)) |
| 494 .WillOnce(WithArg<3>(ScheduleCallback2( |
| 495 DownloadConfirmationResult::CONFIRMED, kExpectedPath))); |
| 496 DetermineDownloadTarget(download_item.get(), &result); |
| 497 EXPECT_EQ(content::DownloadItem::TARGET_DISPOSITION_PROMPT, |
| 498 result.disposition); |
| 499 EXPECT_EQ(kExpectedPath, result.target_path); |
| 500 |
| 501 VerifyAndClearExpectations(); |
| 502 } |
414 | 503 |
415 TEST_F(ChromeDownloadManagerDelegateTest, MaybeDangerousContent) { | 504 TEST_F(ChromeDownloadManagerDelegateTest, MaybeDangerousContent) { |
416 #if !defined(OS_ANDROID) | 505 #if BUILDFLAG(ENABLE_PLUGINS) |
417 content::PluginService::GetInstance()->Init(); | 506 content::PluginService::GetInstance()->Init(); |
418 #endif | 507 #endif |
419 | 508 |
420 GURL url("http://example.com/foo"); | 509 GURL url("http://example.com/foo"); |
421 | 510 |
422 std::unique_ptr<content::MockDownloadItem> download_item = | 511 std::unique_ptr<content::MockDownloadItem> download_item = |
423 CreateActiveDownloadItem(0); | 512 CreateActiveDownloadItem(0); |
424 EXPECT_CALL(*download_item, GetURL()).WillRepeatedly(ReturnRef(url)); | 513 EXPECT_CALL(*download_item, GetURL()).WillRepeatedly(ReturnRef(url)); |
425 EXPECT_CALL(*download_item, GetTargetDisposition()) | 514 EXPECT_CALL(*download_item, GetTargetDisposition()) |
426 .WillRepeatedly(Return(DownloadItem::TARGET_DISPOSITION_OVERWRITE)); | 515 .WillRepeatedly(Return(DownloadItem::TARGET_DISPOSITION_OVERWRITE)); |
427 EXPECT_CALL(*delegate(), MockCheckDownloadUrl(_, _)) | 516 EXPECT_CALL(*delegate(), MockCheckDownloadUrl(_, _)) |
428 .WillRepeatedly( | 517 .WillRepeatedly( |
429 Return(content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT)); | 518 Return(content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT)); |
430 | 519 |
431 { | 520 { |
432 const std::string kDangerousContentDisposition( | 521 const std::string kDangerousContentDisposition( |
433 "attachment; filename=\"foo.swf\""); | 522 "attachment; filename=\"foo.swf\""); |
434 EXPECT_CALL(*download_item, GetContentDisposition()) | 523 EXPECT_CALL(*download_item, GetContentDisposition()) |
435 .WillRepeatedly(Return(kDangerousContentDisposition)); | 524 .WillRepeatedly(Return(kDangerousContentDisposition)); |
436 DownloadTargetInfo target_info; | 525 DetermineDownloadTargetResult result; |
437 DetermineDownloadTarget(download_item.get(), &target_info); | 526 DetermineDownloadTarget(download_item.get(), &result); |
438 | 527 |
439 EXPECT_EQ(DownloadFileType::DANGEROUS, | 528 EXPECT_EQ(DownloadFileType::DANGEROUS, |
440 DownloadItemModel(download_item.get()).GetDangerLevel()); | 529 DownloadItemModel(download_item.get()).GetDangerLevel()); |
441 EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, | 530 EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, |
442 target_info.danger_type); | 531 result.danger_type); |
443 } | 532 } |
444 | 533 |
445 { | 534 { |
446 const std::string kSafeContentDisposition( | 535 const std::string kSafeContentDisposition( |
447 "attachment; filename=\"foo.txt\""); | 536 "attachment; filename=\"foo.txt\""); |
448 EXPECT_CALL(*download_item, GetContentDisposition()) | 537 EXPECT_CALL(*download_item, GetContentDisposition()) |
449 .WillRepeatedly(Return(kSafeContentDisposition)); | 538 .WillRepeatedly(Return(kSafeContentDisposition)); |
450 DownloadTargetInfo target_info; | 539 DetermineDownloadTargetResult result; |
451 DetermineDownloadTarget(download_item.get(), &target_info); | 540 DetermineDownloadTarget(download_item.get(), &result); |
452 EXPECT_EQ(DownloadFileType::NOT_DANGEROUS, | 541 EXPECT_EQ(DownloadFileType::NOT_DANGEROUS, |
453 DownloadItemModel(download_item.get()).GetDangerLevel()); | 542 DownloadItemModel(download_item.get()).GetDangerLevel()); |
454 EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, | 543 EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, |
455 target_info.danger_type); | 544 result.danger_type); |
456 } | 545 } |
457 | 546 |
458 { | 547 { |
459 const std::string kModerateContentDisposition( | 548 const std::string kModerateContentDisposition( |
460 "attachment; filename=\"foo.crx\""); | 549 "attachment; filename=\"foo.crx\""); |
461 EXPECT_CALL(*download_item, GetContentDisposition()) | 550 EXPECT_CALL(*download_item, GetContentDisposition()) |
462 .WillRepeatedly(Return(kModerateContentDisposition)); | 551 .WillRepeatedly(Return(kModerateContentDisposition)); |
463 DownloadTargetInfo target_info; | 552 DetermineDownloadTargetResult result; |
464 DetermineDownloadTarget(download_item.get(), &target_info); | 553 DetermineDownloadTarget(download_item.get(), &result); |
465 EXPECT_EQ(DownloadFileType::ALLOW_ON_USER_GESTURE, | 554 EXPECT_EQ(DownloadFileType::ALLOW_ON_USER_GESTURE, |
466 DownloadItemModel(download_item.get()).GetDangerLevel()); | 555 DownloadItemModel(download_item.get()).GetDangerLevel()); |
467 EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, | 556 EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, |
468 target_info.danger_type); | 557 result.danger_type); |
469 } | 558 } |
470 } | 559 } |
471 | 560 |
472 TEST_F(ChromeDownloadManagerDelegateTest, CheckForFileExistence) { | 561 TEST_F(ChromeDownloadManagerDelegateTest, CheckForFileExistence) { |
473 const char kData[] = "helloworld"; | 562 const char kData[] = "helloworld"; |
474 const size_t kDataLength = sizeof(kData) - 1; | 563 const size_t kDataLength = sizeof(kData) - 1; |
475 base::FilePath existing_path = default_download_path().AppendASCII("foo"); | 564 base::FilePath existing_path = default_download_path().AppendASCII("foo"); |
476 base::FilePath non_existent_path = | 565 base::FilePath non_existent_path = |
477 default_download_path().AppendASCII("bar"); | 566 default_download_path().AppendASCII("bar"); |
478 base::WriteFile(existing_path, kData, kDataLength); | 567 base::WriteFile(existing_path, kData, kDataLength); |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
678 EXPECT_CALL(*download_item, OnContentCheckCompleted(_)).Times(0); | 767 EXPECT_CALL(*download_item, OnContentCheckCompleted(_)).Times(0); |
679 } | 768 } |
680 | 769 |
681 base::RunLoop run_loop; | 770 base::RunLoop run_loop; |
682 ASSERT_FALSE(delegate()->ShouldCompleteDownload(download_item.get(), | 771 ASSERT_FALSE(delegate()->ShouldCompleteDownload(download_item.get(), |
683 run_loop.QuitClosure())); | 772 run_loop.QuitClosure())); |
684 run_loop.Run(); | 773 run_loop.Run(); |
685 } | 774 } |
686 | 775 |
687 #endif // FULL_SAFE_BROWSING | 776 #endif // FULL_SAFE_BROWSING |
| 777 |
| 778 #if defined(OS_ANDROID) |
| 779 |
| 780 namespace { |
| 781 |
| 782 class AndroidDownloadInfobarCounter |
| 783 : public infobars::InfoBarManager::Observer { |
| 784 public: |
| 785 explicit AndroidDownloadInfobarCounter(content::WebContents* web_contents) { |
| 786 infobar_service_ = InfoBarService::FromWebContents(web_contents); |
| 787 infobar_service_->AddObserver(this); |
| 788 } |
| 789 |
| 790 ~AndroidDownloadInfobarCounter() override { |
| 791 infobar_service_->RemoveObserver(this); |
| 792 } |
| 793 |
| 794 int CheckAndResetInfobarCount() { |
| 795 int count = infobar_count_; |
| 796 infobar_count_ = 0; |
| 797 return count; |
| 798 } |
| 799 |
| 800 private: |
| 801 void OnInfoBarAdded(infobars::InfoBar* infobar) override { |
| 802 if (infobar->delegate()->GetIdentifier() == |
| 803 infobars::InfoBarDelegate::CHROME_DUPLICATE_DOWNLOAD_INFOBAR_DELEGATE) { |
| 804 ++infobar_count_; |
| 805 } |
| 806 infobar->delegate()->InfoBarDismissed(); |
| 807 infobar->RemoveSelf(); |
| 808 } |
| 809 |
| 810 InfoBarService* infobar_service_ = nullptr; |
| 811 int infobar_count_ = 0; |
| 812 }; |
| 813 |
| 814 } // namespace |
| 815 |
| 816 TEST_F(ChromeDownloadManagerDelegateTest, RequestConfirmation_Android) { |
| 817 enum class WebContents { AVAILABLE, NONE }; |
| 818 enum class ExpectPath { FULL, EMPTY }; |
| 819 enum class ExpectInfoBar { YES, NO }; |
| 820 struct { |
| 821 DownloadConfirmationReason confirmation_reason; |
| 822 DownloadConfirmationResult expected_result; |
| 823 WebContents web_contents; |
| 824 ExpectInfoBar info_bar; |
| 825 ExpectPath path; |
| 826 } kTestCases[] = { |
| 827 {DownloadConfirmationReason::TARGET_PATH_NOT_WRITEABLE, |
| 828 DownloadConfirmationResult::CANCELED, WebContents::AVAILABLE, |
| 829 ExpectInfoBar::NO, ExpectPath::EMPTY}, |
| 830 |
| 831 {DownloadConfirmationReason::NAME_TOO_LONG, |
| 832 DownloadConfirmationResult::CONTINUE_WITHOUT_CONFIRMATION, |
| 833 WebContents::AVAILABLE, ExpectInfoBar::NO, ExpectPath::FULL}, |
| 834 |
| 835 {DownloadConfirmationReason::TARGET_NO_SPACE, |
| 836 DownloadConfirmationResult::CONTINUE_WITHOUT_CONFIRMATION, |
| 837 WebContents::AVAILABLE, ExpectInfoBar::NO, ExpectPath::FULL}, |
| 838 |
| 839 {DownloadConfirmationReason::SAVE_AS, |
| 840 DownloadConfirmationResult::CONTINUE_WITHOUT_CONFIRMATION, |
| 841 WebContents::AVAILABLE, ExpectInfoBar::NO, ExpectPath::FULL}, |
| 842 |
| 843 {DownloadConfirmationReason::PREFERENCE, |
| 844 DownloadConfirmationResult::CONTINUE_WITHOUT_CONFIRMATION, |
| 845 WebContents::AVAILABLE, ExpectInfoBar::NO, ExpectPath::FULL}, |
| 846 |
| 847 // This case results in an infobar. The logic above dismisses the infobar |
| 848 // and counts it for testing. The functionality of the infobar is not |
| 849 // tested here other than that dimssing the infobar is treated as a user |
| 850 // initiated cancellation. |
| 851 {DownloadConfirmationReason::TARGET_CONFLICT, |
| 852 DownloadConfirmationResult::CANCELED, WebContents::AVAILABLE, |
| 853 ExpectInfoBar::YES, ExpectPath::EMPTY}, |
| 854 |
| 855 {DownloadConfirmationReason::TARGET_CONFLICT, |
| 856 DownloadConfirmationResult::CANCELED, WebContents::NONE, |
| 857 ExpectInfoBar::NO, ExpectPath::EMPTY}, |
| 858 |
| 859 {DownloadConfirmationReason::UNEXPECTED, |
| 860 DownloadConfirmationResult::CANCELED, WebContents::AVAILABLE, |
| 861 ExpectInfoBar::NO, ExpectPath::EMPTY}, |
| 862 }; |
| 863 |
| 864 EXPECT_CALL(*delegate(), RequestConfirmation(_, _, _, _)) |
| 865 .WillRepeatedly(Invoke( |
| 866 delegate(), |
| 867 &TestChromeDownloadManagerDelegate::RequestConfirmationConcrete)); |
| 868 InfoBarService::CreateForWebContents(web_contents()); |
| 869 base::FilePath fake_path = GetPathInDownloadDir(FILE_PATH_LITERAL("foo.txt")); |
| 870 GURL url("http://example.com"); |
| 871 AndroidDownloadInfobarCounter infobar_counter(web_contents()); |
| 872 |
| 873 for (const auto& test_case : kTestCases) { |
| 874 std::unique_ptr<content::MockDownloadItem> download_item = |
| 875 CreateActiveDownloadItem(1); |
| 876 EXPECT_CALL(*download_item, GetWebContents()) |
| 877 .WillRepeatedly(Return(test_case.web_contents == WebContents::AVAILABLE |
| 878 ? web_contents() |
| 879 : nullptr)); |
| 880 EXPECT_CALL(*download_item, GetURL()).WillRepeatedly(ReturnRef(url)); |
| 881 infobar_counter.CheckAndResetInfobarCount(); |
| 882 |
| 883 base::RunLoop loop; |
| 884 const auto callback = base::Bind( |
| 885 [](const base::Closure& closure, |
| 886 DownloadConfirmationResult expected_result, |
| 887 const base::FilePath& expected_path, |
| 888 DownloadConfirmationResult actual_result, |
| 889 const base::FilePath& actual_path) { |
| 890 EXPECT_EQ(expected_result, actual_result); |
| 891 EXPECT_EQ(expected_path, actual_path); |
| 892 closure.Run(); |
| 893 }, |
| 894 loop.QuitClosure(), test_case.expected_result, |
| 895 test_case.path == ExpectPath::FULL ? fake_path : base::FilePath()); |
| 896 delegate()->RequestConfirmation(download_item.get(), fake_path, |
| 897 test_case.confirmation_reason, callback); |
| 898 loop.Run(); |
| 899 |
| 900 EXPECT_EQ(test_case.info_bar == ExpectInfoBar::YES ? 1 : 0, |
| 901 infobar_counter.CheckAndResetInfobarCount()); |
| 902 } |
| 903 } |
| 904 #endif // OS_ANDROID |
OLD | NEW |