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

Side by Side Diff: chrome/browser/download/chrome_download_manager_delegate_unittest.cc

Issue 2453633006: [downloads] Move platform specific code out of DownloadTargetDeterminer. (Closed)
Patch Set: . Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « chrome/browser/download/chrome_download_manager_delegate.cc ('k') | chrome/browser/download/download_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698