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

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

Issue 12850002: Move download filename determintion into a separate class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix tests on Android Created 7 years, 7 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/file_util.h"
6 #include "base/files/file_path.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/message_loop.h"
9 #include "base/observer_list.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/stl_util.h"
12 #include "base/string_util.h"
13 #include "base/value_conversions.h"
14 #include "chrome/browser/download/chrome_download_manager_delegate.h"
15 #include "chrome/browser/download/download_extensions.h"
16 #include "chrome/browser/download/download_prefs.h"
17 #include "chrome/browser/download/download_target_determiner.h"
18 #include "chrome/browser/download/download_util.h"
19 #include "chrome/browser/history/history_service.h"
20 #include "chrome/browser/history/history_service_factory.h"
21 #include "chrome/browser/history/history_types.h"
22 #include "chrome/common/extensions/extension.h"
23 #include "chrome/common/pref_names.h"
24 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
25 #include "chrome/test/base/testing_pref_service_syncable.h"
26 #include "chrome/test/base/testing_profile.h"
27 #include "content/public/browser/web_contents.h"
28 #include "content/public/browser/web_contents_delegate.h"
29 #include "content/public/test/mock_download_item.h"
30 #include "content/public/test/test_browser_thread.h"
31 #include "content/public/test/test_renderer_host.h"
32 #include "content/public/test/web_contents_tester.h"
33 #include "testing/gmock/include/gmock/gmock.h"
34 #include "testing/gtest/include/gtest/gtest.h"
35
36 using ::testing::AnyNumber;
37 using ::testing::Invoke;
38 using ::testing::Ref;
39 using ::testing::Return;
40 using ::testing::ReturnRef;
41 using ::testing::ReturnRefOfCopy;
42 using ::testing::Truly;
43 using ::testing::WithArg;
44 using ::testing::_;
45 using content::DownloadItem;
46
47 namespace {
48
49 // No-op delegate.
50 class NullWebContentsDelegate : public content::WebContentsDelegate {
51 public:
52 NullWebContentsDelegate() {}
53 ~NullWebContentsDelegate() {}
54 };
55
56 // Google Mock action that posts a task to the current message loop that invokes
57 // the first argument of the mocked method as a callback. Said argument must be
58 // a base::Callback<void(ParamType)>. |result| must be of |ParamType| and is
59 // bound as that parameter.
60 // Example:
61 // class FooClass {
62 // public:
63 // virtual void Foo(base::Callback<void(bool)> callback);
64 // };
65 // ...
66 // EXPECT_CALL(mock_fooclass_instance, Foo(callback))
67 // .WillOnce(ScheduleCallback(false));
68 ACTION_P(ScheduleCallback, result0) {
69 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(arg0, result0));
70 }
71
72 // Similar to ScheduleCallback, but binds 2 arguments.
73 ACTION_P2(ScheduleCallback2, result0, result1) {
74 MessageLoop::current()->PostTask(
75 FROM_HERE, base::Bind(arg0, result0, result1));
76 }
77
78 // Used with DownloadTestCase. Indicates the type of test case. The expectations
79 // for the test is set based on the type.
80 enum TestCaseType {
81 SAVE_AS,
82 AUTOMATIC,
83 FORCED // Requires that forced_file_path be non-empty.
84 };
85
86 // Used with DownloadTestCase. Type of intermediate filename to expect.
87 enum TestCaseExpectIntermediate {
88 EXPECT_CRDOWNLOAD, // Expect path/to/target.crdownload.
89 EXPECT_UNCONFIRMED, // Expect path/to/Unconfirmed xxx.crdownload.
90 EXPECT_LOCAL_PATH, // Expect target path.
91 };
92
93 // Typical download test case. Used with
94 // DownloadTargetDeterminerTest::RunTestCase().
95 struct DownloadTestCase {
96 // Type of test.
97 TestCaseType test_type;
98
99 // Expected danger type. Verified at the end of target determination.
100 content::DownloadDangerType expected_danger_type;
101
102 // Value of DownloadItem::GetURL()
103 const char* url;
104
105 // Value of DownloadItem::GetMimeType()
106 const char* mime_type;
107
108 // Should be non-empty if |test_type| == FORCED. Value of GetForcedFilePath().
109 const base::FilePath::CharType* forced_file_path;
110
111 // Expected virtual path. Specified relative to the virtual download path. If
112 // empty, assumed to be the same as |expected_local_path|.
113 const base::FilePath::CharType* expected_virtual_path;
114
115 // Expected local path. Specified relative to the test download path.
116 const base::FilePath::CharType* expected_local_path;
117
118 // Expected target disposition. If this is TARGET_DISPOSITION_PROMPT, then the
119 // test run will expect ChromeDownloadManagerDelegate to prompt the user for a
120 // download location.
121 DownloadItem::TargetDisposition expected_disposition;
122
123 // Type of intermediate path to expect.
124 TestCaseExpectIntermediate expected_intermediate;
125 };
126
127 class MockDownloadTargetDeterminerDelegate :
128 public DownloadTargetDeterminerDelegate {
129 public:
130 MOCK_METHOD3(CheckDownloadUrl,
131 void(content::DownloadItem*, const base::FilePath&,
132 const CheckDownloadUrlCallback&));
133 MOCK_METHOD3(NotifyExtensions,
134 void(content::DownloadItem*, const base::FilePath&,
135 const NotifyExtensionsCallback&));
136 MOCK_METHOD3(PromptUserForDownloadPath,
137 void(content::DownloadItem*, const base::FilePath&,
138 const FileSelectedCallback&));
139 MOCK_METHOD3(DetermineLocalPath,
140 void(DownloadItem*, const base::FilePath&,
141 const LocalPathCallback&));
142 MOCK_METHOD4(ReserveVirtualPath,
143 void(DownloadItem*, const base::FilePath&,
144 DownloadPathReservationTracker::FilenameConflictAction,
145 const ReservedPathCallback&));
146
147 void SetupDefaults() {
148 ON_CALL(*this, CheckDownloadUrl(_, _, _))
149 .WillByDefault(WithArg<2>(
150 ScheduleCallback(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS)));
151 ON_CALL(*this, NotifyExtensions(_, _, _))
152 .WillByDefault(WithArg<2>(
153 ScheduleCallback2(base::FilePath(),
154 DownloadPathReservationTracker::UNIQUIFY)));
155 ON_CALL(*this, ReserveVirtualPath(_, _, _, _))
156 .WillByDefault(Invoke(
157 &MockDownloadTargetDeterminerDelegate::NullReserveVirtualPath));
158 ON_CALL(*this, PromptUserForDownloadPath(_, _, _))
159 .WillByDefault(Invoke(
160 &MockDownloadTargetDeterminerDelegate::NullPromptUser));
161 ON_CALL(*this, DetermineLocalPath(_, _, _))
162 .WillByDefault(Invoke(
163 &MockDownloadTargetDeterminerDelegate::NullDetermineLocalPath));
164 }
165 private:
166 static void NullReserveVirtualPath(
167 DownloadItem* download,
168 const base::FilePath& virtual_path,
169 DownloadPathReservationTracker::FilenameConflictAction conflict_action,
170 const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback);
171 static void NullPromptUser(
172 DownloadItem* download, const base::FilePath& suggested_path,
173 const FileSelectedCallback& callback);
174 static void NullDetermineLocalPath(
175 DownloadItem* download, const base::FilePath& virtual_path,
176 const LocalPathCallback& callback);
177 };
178
179 class DownloadTargetDeterminerTest : public ChromeRenderViewHostTestHarness {
180 public:
181 DownloadTargetDeterminerTest();
182
183 // ::testing::Test
184 virtual void SetUp() OVERRIDE;
185 virtual void TearDown() OVERRIDE;
186
187 // Creates MockDownloadItem and sets up default expectations.
188 content::MockDownloadItem* CreateActiveDownloadItem(
189 int32 id,
190 const DownloadTestCase& test_case);
191
192 // Sets the AutoOpenBasedOnExtension user preference for |path|.
193 void EnableAutoOpenBasedOnExtension(const base::FilePath& path);
194
195 // Set the kDownloadDefaultDirectory user preference to |path|.
196 void SetDefaultDownloadPath(const base::FilePath& path);
197
198 // Set the kDownloadDefaultDirectory managed preference to |path|.
199 void SetManagedDownloadPath(const base::FilePath& path);
200
201 // Set the kPromptForDownload user preference to |prompt|.
202 void SetPromptForDownload(bool prompt);
203
204 // Given the relative path |path|, returns the full path under the temporary
205 // downloads directory.
206 base::FilePath GetPathInDownloadDir(const base::FilePath::StringType& path);
207
208 // Run |test_case| using |item|.
209 void RunTestCase(const DownloadTestCase& test_case,
210 content::MockDownloadItem* item);
211
212 // Run through |test_case_count| tests in |test_cases|. A new MockDownloadItem
213 // will be created for each test case and destroyed when the test case is
214 // complete.
215 void RunTestCasesWithActiveItem(const DownloadTestCase test_cases[],
216 size_t test_case_count);
217
218 const base::FilePath& test_download_dir() const {
219 return test_download_dir_.path();
220 }
221
222 const base::FilePath& test_virtual_dir() const {
223 return test_virtual_dir_;
224 }
225
226 MockDownloadTargetDeterminerDelegate* delegate() {
227 return &delegate_;
228 }
229
230 DownloadPrefs* download_prefs() {
231 return download_prefs_.get();
232 }
233
234 void set_last_selected_directory(const base::FilePath& path) {
235 last_selected_directory_ = path;
236 }
237
238 private:
239 // Verifies that |target_path|, |disposition|, |expected_danger_type| and
240 // |intermediate_path| matches the expectations of |test_case|.
241 void DownloadTargetVerifier(const DownloadTestCase& test_case,
242 const base::FilePath& local_path,
243 DownloadItem::TargetDisposition disposition,
244 content::DownloadDangerType danger_type,
245 const base::FilePath& intermediate_path);
246
247 scoped_ptr<DownloadPrefs> download_prefs_;
248 ::testing::NiceMock<MockDownloadTargetDeterminerDelegate> delegate_;
249 NullWebContentsDelegate web_contents_delegate_;
250 base::ScopedTempDir test_download_dir_;
251 base::FilePath test_virtual_dir_;
252 base::FilePath last_selected_directory_;
253 content::TestBrowserThread ui_thread_;
254 content::TestBrowserThread file_thread_;
255 };
256
257 DownloadTargetDeterminerTest::DownloadTargetDeterminerTest()
258 : ChromeRenderViewHostTestHarness(),
259 ui_thread_(content::BrowserThread::UI, &message_loop_),
260 file_thread_(content::BrowserThread::FILE, &message_loop_) {
261 }
262
263 void DownloadTargetDeterminerTest::SetUp() {
264 ChromeRenderViewHostTestHarness::SetUp();
265 CHECK(profile());
266 download_prefs_.reset(new DownloadPrefs(profile()));
267 web_contents()->SetDelegate(&web_contents_delegate_);
268 ASSERT_TRUE(test_download_dir_.CreateUniqueTempDir());
269 test_virtual_dir_ = test_download_dir().Append(FILE_PATH_LITERAL("virtual"));
270 SetDefaultDownloadPath(test_download_dir());
271 delegate_.SetupDefaults();
272 }
273
274 void DownloadTargetDeterminerTest::TearDown() {
275 download_prefs_.reset();
276 message_loop_.RunUntilIdle();
277 ChromeRenderViewHostTestHarness::TearDown();
278 }
279
280 content::MockDownloadItem*
281 DownloadTargetDeterminerTest::CreateActiveDownloadItem(
282 int32 id,
283 const DownloadTestCase& test_case) {
284 content::MockDownloadItem* item =
285 new ::testing::NiceMock<content::MockDownloadItem>();
286 GURL download_url(test_case.url);
287 std::vector<GURL> url_chain;
288 url_chain.push_back(download_url);
289 base::FilePath forced_file_path =
290 GetPathInDownloadDir(test_case.forced_file_path);
291 DownloadItem::TargetDisposition initial_disposition =
292 (test_case.test_type == SAVE_AS) ?
293 DownloadItem::TARGET_DISPOSITION_PROMPT :
294 DownloadItem::TARGET_DISPOSITION_OVERWRITE;
295 EXPECT_EQ(test_case.test_type == FORCED,
296 !forced_file_path.empty());
297
298 ON_CALL(*item, GetBrowserContext())
299 .WillByDefault(Return(profile()));
300 ON_CALL(*item, GetDangerType())
301 .WillByDefault(Return(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS));
302 ON_CALL(*item, GetForcedFilePath())
303 .WillByDefault(ReturnRefOfCopy(forced_file_path));
304 ON_CALL(*item, GetFullPath())
305 .WillByDefault(ReturnRefOfCopy(base::FilePath()));
306 ON_CALL(*item, GetHash())
307 .WillByDefault(ReturnRefOfCopy(std::string()));
308 ON_CALL(*item, GetId())
309 .WillByDefault(Return(id));
310 ON_CALL(*item, GetMimeType())
311 .WillByDefault(Return(test_case.mime_type));
312 ON_CALL(*item, GetReferrerUrl())
313 .WillByDefault(ReturnRefOfCopy(download_url));
314 ON_CALL(*item, GetState())
315 .WillByDefault(Return(DownloadItem::IN_PROGRESS));
316 ON_CALL(*item, GetTargetDisposition())
317 .WillByDefault(Return(initial_disposition));
318 ON_CALL(*item, GetTargetFilePath())
319 .WillByDefault(ReturnRefOfCopy(base::FilePath()));
320 ON_CALL(*item, GetTransitionType())
321 .WillByDefault(Return(content::PAGE_TRANSITION_LINK));
322 ON_CALL(*item, GetURL())
323 .WillByDefault(ReturnRefOfCopy(download_url));
324 ON_CALL(*item, GetUrlChain())
325 .WillByDefault(ReturnRefOfCopy(url_chain));
326 ON_CALL(*item, GetWebContents())
327 .WillByDefault(Return(web_contents()));
328 ON_CALL(*item, HasUserGesture())
329 .WillByDefault(Return(true));
330 ON_CALL(*item, IsDangerous())
331 .WillByDefault(Return(false));
332 ON_CALL(*item, IsInProgress())
333 .WillByDefault(Return(true));
334 ON_CALL(*item, IsTemporary())
335 .WillByDefault(Return(false));
336 return item;
337 }
338
339 void DownloadTargetDeterminerTest::EnableAutoOpenBasedOnExtension(
340 const base::FilePath& path) {
341 EXPECT_TRUE(download_prefs_->EnableAutoOpenBasedOnExtension(path));
342 }
343
344 void DownloadTargetDeterminerTest::SetDefaultDownloadPath(
345 const base::FilePath& path) {
346 profile()->GetTestingPrefService()->
347 SetFilePath(prefs::kDownloadDefaultDirectory, path);
348 }
349
350 void DownloadTargetDeterminerTest::SetManagedDownloadPath(
351 const base::FilePath& path) {
352 profile()->GetTestingPrefService()->
353 SetManagedPref(prefs::kDownloadDefaultDirectory,
354 base::CreateFilePathValue(path));
355 }
356
357 void DownloadTargetDeterminerTest::SetPromptForDownload(bool prompt) {
358 profile()->GetTestingPrefService()->
359 SetBoolean(prefs::kPromptForDownload, prompt);
360 }
361
362 base::FilePath DownloadTargetDeterminerTest::GetPathInDownloadDir(
363 const base::FilePath::StringType& relative_path) {
364 if (relative_path.empty())
365 return base::FilePath();
366 base::FilePath full_path(test_download_dir().Append(relative_path));
367 return full_path.NormalizePathSeparators();
368 }
369
370 void DownloadTargetDeterminerTest::RunTestCase(
371 const DownloadTestCase& test_case,
372 content::MockDownloadItem* item) {
373 // Kick off the test.
374 base::WeakPtrFactory<DownloadTargetDeterminerTest> factory(this);
375 DownloadTargetDeterminer::Start(
376 item, download_prefs_.get(), last_selected_directory_, delegate(),
377 base::Bind(&DownloadTargetDeterminerTest::DownloadTargetVerifier,
378 factory.GetWeakPtr(), test_case));
379 message_loop_.RunUntilIdle();
380 ::testing::Mock::VerifyAndClearExpectations(delegate());
381 }
382
383 void DownloadTargetDeterminerTest::RunTestCasesWithActiveItem(
384 const DownloadTestCase test_cases[],
385 size_t test_case_count) {
386 for (size_t i = 0; i < test_case_count; ++i) {
387 scoped_ptr<content::MockDownloadItem> item(
388 CreateActiveDownloadItem(i, test_cases[i]));
389 SCOPED_TRACE(testing::Message() << "Running test case " << i);
390 RunTestCase(test_cases[i], item.get());
391 }
392 }
393
394 void DownloadTargetDeterminerTest::DownloadTargetVerifier(
395 const DownloadTestCase& test_case,
396 const base::FilePath& local_path,
397 DownloadItem::TargetDisposition disposition,
398 content::DownloadDangerType danger_type,
399 const base::FilePath& intermediate_path) {
400 base::FilePath expected_local_path(
401 GetPathInDownloadDir(test_case.expected_local_path));
402 EXPECT_EQ(expected_local_path.value(), local_path.value());
403 EXPECT_EQ(test_case.expected_disposition, disposition);
404 EXPECT_EQ(test_case.expected_danger_type, danger_type);
405
406 switch (test_case.expected_intermediate) {
407 case EXPECT_CRDOWNLOAD:
408 EXPECT_EQ(download_util::GetCrDownloadPath(local_path).value(),
409 intermediate_path.value());
410 break;
411
412 case EXPECT_UNCONFIRMED:
413 // The paths (in English) look like: /path/Unconfirmed xxx.crdownload.
414 // Of this, we only check that the path is:
415 // 1. Not "/path/target.crdownload",
416 // 2. Points to the same directory as the target.
417 // 3. Has extension ".crdownload".
418 // 4. Basename starts with "Unconfirmed ".
419 EXPECT_NE(download_util::GetCrDownloadPath(expected_local_path).value(),
420 intermediate_path.value());
421 EXPECT_EQ(expected_local_path.DirName().value(),
422 intermediate_path.DirName().value());
423 EXPECT_TRUE(intermediate_path.MatchesExtension(
424 FILE_PATH_LITERAL(".crdownload")));
425 EXPECT_EQ(0u, intermediate_path.BaseName().value().find(
426 FILE_PATH_LITERAL("Unconfirmed ")));
427 break;
428
429 case EXPECT_LOCAL_PATH:
430 EXPECT_EQ(expected_local_path.value(), intermediate_path.value());
431 break;
432 }
433 }
434
435 // static
436 void MockDownloadTargetDeterminerDelegate::NullReserveVirtualPath(
437 DownloadItem* download,
438 const base::FilePath& virtual_path,
439 DownloadPathReservationTracker::FilenameConflictAction conflict_action,
440 const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback) {
441 callback.Run(virtual_path, true);
442 }
443
444 // static
445 void MockDownloadTargetDeterminerDelegate::NullPromptUser(
446 DownloadItem* download, const base::FilePath& suggested_path,
447 const FileSelectedCallback& callback) {
448 callback.Run(suggested_path);
449 }
450
451 // static
452 void MockDownloadTargetDeterminerDelegate::NullDetermineLocalPath(
453 DownloadItem* download, const base::FilePath& virtual_path,
454 const LocalPathCallback& callback) {
455 callback.Run(virtual_path);
456 }
457
458 // NotifyExtensions implementation that overrides the path so that the target
459 // file is in a subdirectory called 'overridden'. If the extension is '.remove',
460 // the extension is removed.
461 void NotifyExtensionsOverridePath(
462 content::DownloadItem* download,
463 const base::FilePath& path,
464 const DownloadTargetDeterminerDelegate::NotifyExtensionsCallback&
465 callback) {
466 base::FilePath new_path =
467 base::FilePath()
468 .AppendASCII("overridden")
469 .Append(path.BaseName());
470 if (new_path.MatchesExtension(FILE_PATH_LITERAL(".remove")))
471 new_path = new_path.RemoveExtension();
472 callback.Run(new_path, DownloadPathReservationTracker::UNIQUIFY);
473 }
474
475 void CheckDownloadUrlCheckExes(
476 content::DownloadItem* download,
477 const base::FilePath& path,
478 const DownloadTargetDeterminerDelegate::CheckDownloadUrlCallback&
479 callback) {
480 if (path.MatchesExtension(FILE_PATH_LITERAL(".exe")))
481 callback.Run(content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT);
482 else
483 callback.Run(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
484 }
485
486 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_Basic) {
487 const DownloadTestCase kBasicTestCases[] = {
488 {
489 // 0: Automatic Safe
490 AUTOMATIC,
491 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
492 "http://example.com/foo.txt", "text/plain",
493 FILE_PATH_LITERAL(""),
494
495 FILE_PATH_LITERAL(""),
496 FILE_PATH_LITERAL("foo.txt"),
497 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
498
499 EXPECT_CRDOWNLOAD
500 },
501
502 {
503 // 1: Save_As Safe
504 SAVE_AS,
505 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
506 "http://example.com/foo.txt", "text/plain",
507 FILE_PATH_LITERAL(""),
508
509 FILE_PATH_LITERAL(""),
510 FILE_PATH_LITERAL("foo.txt"),
511 DownloadItem::TARGET_DISPOSITION_PROMPT,
512
513 EXPECT_CRDOWNLOAD
514 },
515
516 {
517 // 2: Automatic Dangerous
518 AUTOMATIC,
519 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
520 "http://example.com/foo.html", "",
521 FILE_PATH_LITERAL(""),
522
523 FILE_PATH_LITERAL(""),
524 FILE_PATH_LITERAL("foo.html"),
525 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
526
527 EXPECT_UNCONFIRMED
528 },
529
530 {
531 // 3: Forced Safe
532 FORCED,
533 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
534 "http://example.com/foo.txt", "",
535 FILE_PATH_LITERAL("forced-foo.txt"),
536
537 FILE_PATH_LITERAL(""),
538 FILE_PATH_LITERAL("forced-foo.txt"),
539 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
540
541 EXPECT_LOCAL_PATH
542 },
543 };
544
545 // The test assumes that .html files have a danger level of
546 // AllowOnUserGesture.
547 ASSERT_EQ(download_util::AllowOnUserGesture,
548 download_util::GetFileDangerLevel(
549 base::FilePath(FILE_PATH_LITERAL("foo.html"))));
550 RunTestCasesWithActiveItem(kBasicTestCases, arraysize(kBasicTestCases));
551 }
552
553 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_CancelSaveAs) {
554 const DownloadTestCase kCancelSaveAsTestCases[] = {
555 {
556 // 0: Save_As Safe, Cancelled.
557 SAVE_AS,
558 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
559 "http://example.com/foo.txt", "text/plain",
560 FILE_PATH_LITERAL(""),
561
562 FILE_PATH_LITERAL(""),
563 FILE_PATH_LITERAL(""),
564 DownloadItem::TARGET_DISPOSITION_PROMPT,
565
566 EXPECT_LOCAL_PATH
567 }
568 };
569 ON_CALL(*delegate(), PromptUserForDownloadPath(_, _, _))
570 .WillByDefault(WithArg<2>(ScheduleCallback(base::FilePath())));
571 RunTestCasesWithActiveItem(kCancelSaveAsTestCases,
572 arraysize(kCancelSaveAsTestCases));
573 }
574
575 // The SafeBrowsing check is performed early. Make sure that a download item
576 // that has been marked as DANGEROUS_URL behaves correctly.
577 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_DangerousUrl) {
578 const DownloadTestCase kSafeBrowsingTestCases[] = {
579 {
580 // 0: Automatic Dangerous URL
581 AUTOMATIC,
582 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
583 "http://phishing.example.com/foo.txt", "",
584 FILE_PATH_LITERAL(""),
585
586 FILE_PATH_LITERAL(""),
587 FILE_PATH_LITERAL("foo.txt"),
588 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
589
590 EXPECT_UNCONFIRMED
591 },
592
593 {
594 // 1: Save As Dangerous URL
595 SAVE_AS,
596 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
597 "http://phishing.example.com/foo.txt", "",
598 FILE_PATH_LITERAL(""),
599
600 FILE_PATH_LITERAL(""),
601 FILE_PATH_LITERAL("foo.txt"),
602 DownloadItem::TARGET_DISPOSITION_PROMPT,
603
604 EXPECT_UNCONFIRMED
605 },
606
607 {
608 // 2: Forced Dangerous URL
609 FORCED,
610 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
611 "http://phishing.example.com/foo.txt", "",
612 FILE_PATH_LITERAL("forced-foo.txt"),
613
614 FILE_PATH_LITERAL(""),
615 FILE_PATH_LITERAL("forced-foo.txt"),
616 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
617
618 EXPECT_UNCONFIRMED
619 },
620
621 {
622 // 3: Automatic Dangerous URL + Dangerous file. Dangerous URL takes
623 // precendence.
624 AUTOMATIC,
625 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
626 "http://phishing.example.com/foo.html", "",
627 FILE_PATH_LITERAL(""),
628
629 FILE_PATH_LITERAL(""),
630 FILE_PATH_LITERAL("foo.html"),
631 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
632
633 EXPECT_UNCONFIRMED
634 },
635
636 {
637 // 4: Save As Dangerous URL + Dangerous file
638 SAVE_AS,
639 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
640 "http://phishing.example.com/foo.html", "",
641 FILE_PATH_LITERAL(""),
642
643 FILE_PATH_LITERAL(""),
644 FILE_PATH_LITERAL("foo.html"),
645 DownloadItem::TARGET_DISPOSITION_PROMPT,
646
647 EXPECT_UNCONFIRMED
648 },
649
650 {
651 // 5: Forced Dangerous URL + Dangerous file
652 FORCED,
653 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
654 "http://phishing.example.com/foo.html", "",
655 FILE_PATH_LITERAL("forced-foo.html"),
656
657 FILE_PATH_LITERAL(""),
658 FILE_PATH_LITERAL("forced-foo.html"),
659 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
660
661 EXPECT_UNCONFIRMED
662 },
663 };
664
665 ON_CALL(*delegate(), CheckDownloadUrl(_, _, _))
666 .WillByDefault(WithArg<2>(ScheduleCallback(
667 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL)));
668 RunTestCasesWithActiveItem(kSafeBrowsingTestCases,
669 arraysize(kSafeBrowsingTestCases));
670 }
671
672 // The SafeBrowsing check is performed early. Make sure that a download item
673 // that has been marked as MAYBE_DANGEROUS_CONTENT behaves correctly.
674 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_MaybeDangerousContent) {
675 const DownloadTestCase kSafeBrowsingTestCases[] = {
676 {
677 // 0: Automatic Maybe dangerous content
678 AUTOMATIC,
679 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
680 "http://phishing.example.com/foo.exe", "",
681 FILE_PATH_LITERAL(""),
682
683 FILE_PATH_LITERAL(""),
684 FILE_PATH_LITERAL("foo.exe"),
685 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
686
687 EXPECT_UNCONFIRMED
688 },
689
690 {
691 // 1: Save As Maybe dangerous content
692 SAVE_AS,
693 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
694 "http://phishing.example.com/foo.exe", "",
695 FILE_PATH_LITERAL(""),
696
697 FILE_PATH_LITERAL(""),
698 FILE_PATH_LITERAL("foo.exe"),
699 DownloadItem::TARGET_DISPOSITION_PROMPT,
700
701 EXPECT_UNCONFIRMED
702 },
703
704 {
705 // 2: Forced Maybe dangerous content
706 FORCED,
707 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
708 "http://phishing.example.com/foo.exe", "",
709 FILE_PATH_LITERAL("forced-foo.exe"),
710
711 FILE_PATH_LITERAL(""),
712 FILE_PATH_LITERAL("forced-foo.exe"),
713 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
714
715 EXPECT_UNCONFIRMED
716 },
717 };
718
719 ON_CALL(*delegate(), CheckDownloadUrl(_, _, _))
720 .WillByDefault(WithArg<2>(ScheduleCallback(
721 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT)));
722 RunTestCasesWithActiveItem(kSafeBrowsingTestCases,
723 arraysize(kSafeBrowsingTestCases));
724 }
725
726 // Test whether the last saved directory is used for 'Save As' downloads.
727 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_LastSavePath) {
728 const DownloadTestCase kLastSavePathTestCasesPre[] = {
729 {
730 // 0: If the last save path is empty, then the default download directory
731 // should be used.
732 SAVE_AS,
733 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
734 "http://example.com/foo.txt", "text/plain",
735 FILE_PATH_LITERAL(""),
736
737 FILE_PATH_LITERAL(""),
738 FILE_PATH_LITERAL("foo.txt"),
739 DownloadItem::TARGET_DISPOSITION_PROMPT,
740
741 EXPECT_CRDOWNLOAD
742 }
743 };
744
745 // These test cases are run with a last save path set to a non-emtpy local
746 // download directory.
747 const DownloadTestCase kLastSavePathTestCasesPost[] = {
748 {
749 // 0: This test case is run with the last download directory set to
750 // '<test_download_dir()>/foo'.
751 SAVE_AS,
752 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
753 "http://example.com/foo.txt", "text/plain",
754 FILE_PATH_LITERAL(""),
755
756 FILE_PATH_LITERAL(""),
757 FILE_PATH_LITERAL("foo/foo.txt"),
758 DownloadItem::TARGET_DISPOSITION_PROMPT,
759
760 EXPECT_CRDOWNLOAD
761 },
762
763 {
764 // 1: Start an automatic download. This should be saved to the user's
765 // default download directory and not the last used Save As directory.
766 AUTOMATIC,
767 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
768 "http://example.com/foo.txt", "text/plain",
769 FILE_PATH_LITERAL(""),
770
771 FILE_PATH_LITERAL(""),
772 FILE_PATH_LITERAL("foo.txt"),
773 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
774
775 EXPECT_CRDOWNLOAD
776 },
777 };
778
779 // This test case is run with the last save path set to a non-empty virtual
780 // directory.
781 const DownloadTestCase kLastSavePathTestCasesVirtual[] = {
782 {
783 SAVE_AS,
784 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
785 "http://example.com/foo.txt", "text/plain",
786 FILE_PATH_LITERAL(""),
787
788 FILE_PATH_LITERAL("virtual/foo/foo.txt"),
789 FILE_PATH_LITERAL("bar.txt"),
790 DownloadItem::TARGET_DISPOSITION_PROMPT,
791
792 EXPECT_LOCAL_PATH
793 },
794 };
795
796 {
797 SCOPED_TRACE(testing::Message()
798 << "Running with empty last_selected_directory");
799 base::FilePath prompt_path =
800 GetPathInDownloadDir(FILE_PATH_LITERAL("foo.txt"));
801 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, prompt_path, _));
802 RunTestCasesWithActiveItem(kLastSavePathTestCasesPre,
803 arraysize(kLastSavePathTestCasesPre));
804 }
805
806 // Try with a non-empty last save path.
807 {
808 SCOPED_TRACE(testing::Message()
809 << "Running with local last_selected_directory");
810 set_last_selected_directory(test_download_dir().AppendASCII("foo"));
811 base::FilePath prompt_path =
812 GetPathInDownloadDir(FILE_PATH_LITERAL("foo/foo.txt"));
813 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, prompt_path, _));
814 RunTestCasesWithActiveItem(kLastSavePathTestCasesPost,
815 arraysize(kLastSavePathTestCasesPost));
816 }
817
818 // And again, but this time use a virtual directory.
819 {
820 SCOPED_TRACE(testing::Message()
821 << "Running with virtual last_selected_directory");
822 base::FilePath last_selected_dir = test_virtual_dir().AppendASCII("foo");
823 base::FilePath virtual_path = last_selected_dir.AppendASCII("foo.txt");
824 set_last_selected_directory(last_selected_dir);
825 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(
826 _, last_selected_dir.AppendASCII("foo.txt"), _));
827 EXPECT_CALL(*delegate(), DetermineLocalPath(_, virtual_path, _))
828 .WillOnce(WithArg<2>(ScheduleCallback(
829 GetPathInDownloadDir(FILE_PATH_LITERAL("bar.txt")))));
830 RunTestCasesWithActiveItem(kLastSavePathTestCasesVirtual,
831 arraysize(kLastSavePathTestCasesVirtual));
832 }
833 }
834
835 // These tests are run with the default downloads folder set to a virtual
836 // directory.
837 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_DefaultVirtual) {
838 // The default download directory is the virutal path.
839 SetDefaultDownloadPath(test_virtual_dir());
840
841 {
842 SCOPED_TRACE(testing::Message() << "Automatic Safe Download");
843 const DownloadTestCase kAutomaticDownloadToVirtualDir = {
844 AUTOMATIC,
845 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
846 "http://example.com/foo.txt", "text/plain",
847 FILE_PATH_LITERAL(""),
848
849 // Downloaded to default virtual directory.
850 FILE_PATH_LITERAL("virtual/foo.txt"),
851 FILE_PATH_LITERAL("foo-local.txt"),
852 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
853
854 EXPECT_LOCAL_PATH
855 };
856 EXPECT_CALL(*delegate(), DetermineLocalPath(_, _, _))
857 .WillOnce(WithArg<2>(ScheduleCallback(
858 GetPathInDownloadDir(FILE_PATH_LITERAL("foo-local.txt")))));
859 RunTestCasesWithActiveItem(&kAutomaticDownloadToVirtualDir, 1);
860 }
861
862 {
863 SCOPED_TRACE(testing::Message() << "Save As to virtual directory");
864 const DownloadTestCase kSaveAsToVirtualDir = {
865 SAVE_AS,
866 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
867 "http://example.com/bar.txt", "text/plain",
868 FILE_PATH_LITERAL(""),
869
870 // The response to the download prompt is to choose the 'prompted.txt'
871 // virtual path.
872 FILE_PATH_LITERAL("virtual/prompted.txt"),
873 FILE_PATH_LITERAL("foo-local.txt"),
874 DownloadItem::TARGET_DISPOSITION_PROMPT,
875
876 EXPECT_LOCAL_PATH
877 };
878 EXPECT_CALL(*delegate(), DetermineLocalPath(_, _, _))
879 .WillOnce(WithArg<2>(ScheduleCallback(
880 GetPathInDownloadDir(FILE_PATH_LITERAL("foo-local.txt")))));
881 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(
882 _, test_virtual_dir().AppendASCII("bar.txt"), _))
883 .WillOnce(WithArg<2>(ScheduleCallback(
884 test_virtual_dir().AppendASCII("prompted.txt"))));
885 RunTestCasesWithActiveItem(&kSaveAsToVirtualDir, 1);
886 }
887
888 {
889 SCOPED_TRACE(testing::Message() << "Save As to local directory");
890 const DownloadTestCase kSaveAsToLocalDir = {
891 SAVE_AS,
892 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
893 "http://example.com/bar.txt", "text/plain",
894 FILE_PATH_LITERAL(""),
895
896 // Response to the 'Save As' is to choose the local path for 'foo-x.txt'.
897 FILE_PATH_LITERAL(""),
898 FILE_PATH_LITERAL("foo-x.txt"),
899 DownloadItem::TARGET_DISPOSITION_PROMPT,
900
901 EXPECT_CRDOWNLOAD
902 };
903 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(
904 _, test_virtual_dir().AppendASCII("bar.txt"), _))
905 .WillOnce(WithArg<2>(ScheduleCallback(
906 GetPathInDownloadDir(FILE_PATH_LITERAL("foo-x.txt")))));
907 RunTestCasesWithActiveItem(&kSaveAsToLocalDir, 1);
908 }
909
910 {
911 SCOPED_TRACE(testing::Message() << "Forced safe download");
912 const DownloadTestCase kForcedSafe = {
913 FORCED,
914 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
915 "http://example.com/foo.txt", "",
916 FILE_PATH_LITERAL("forced-foo.txt"),
917
918 // Forced paths should be left as-is.
919 FILE_PATH_LITERAL(""),
920 FILE_PATH_LITERAL("forced-foo.txt"),
921 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
922
923 EXPECT_LOCAL_PATH
924 };
925 RunTestCasesWithActiveItem(&kForcedSafe, 1);
926 }
927 }
928
929 // Test that an inactive download will still get a virtual or local download
930 // path.
931 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_InactiveDownload) {
932 const DownloadTestCase kInactiveTestCases[] = {
933 {
934 AUTOMATIC,
935 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
936 "http://example.com/foo.txt", "text/plain",
937 FILE_PATH_LITERAL(""),
938
939 FILE_PATH_LITERAL("foo.txt"),
940 FILE_PATH_LITERAL(""),
941 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
942
943 EXPECT_LOCAL_PATH
944 },
945
946 {
947 SAVE_AS,
948 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
949 "http://example.com/foo.txt", "text/plain",
950 FILE_PATH_LITERAL(""),
951
952 FILE_PATH_LITERAL("foo.txt"),
953 FILE_PATH_LITERAL(""),
954 DownloadItem::TARGET_DISPOSITION_PROMPT,
955
956 EXPECT_LOCAL_PATH
957 }
958 };
959
960 for (size_t i = 0; i < arraysize(kInactiveTestCases); ++i) {
961 SCOPED_TRACE(testing::Message() << "Running test case " << i);
962 const DownloadTestCase& test_case = kInactiveTestCases[i];
963 scoped_ptr<content::MockDownloadItem> item(
964 CreateActiveDownloadItem(i, test_case));
965 EXPECT_CALL(*item.get(), IsInProgress())
966 .WillRepeatedly(Return(false));
967 // Even though one is a SAVE_AS download, no prompt will be displayed to
968 // the user because the download is inactive.
969 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, _, _))
970 .Times(0);
971 RunTestCase(kInactiveTestCases[i], item.get());
972 }
973 }
974
975 // If the reserved path could not be verified, then the user should see a
976 // prompt.
977 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ReservationFailed) {
978 const DownloadTestCase kReservationFailedCases[] = {
979 {
980 // 0: Automatic download. Since the reservation fails, the disposition of
981 // the target is to prompt, but the returned path is used.
982 AUTOMATIC,
983 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
984 "http://example.com/foo.txt", "text/plain",
985 FILE_PATH_LITERAL(""),
986
987 FILE_PATH_LITERAL(""),
988 FILE_PATH_LITERAL("bar.txt"),
989 DownloadItem::TARGET_DISPOSITION_PROMPT,
990
991 EXPECT_CRDOWNLOAD
992 },
993 };
994
995 // Setup ReserveVirtualPath() to fail.
996 ON_CALL(*delegate(), ReserveVirtualPath(_, _, _, _))
997 .WillByDefault(WithArg<3>(ScheduleCallback2(
998 GetPathInDownloadDir(FILE_PATH_LITERAL("bar.txt")), false)));
999 RunTestCasesWithActiveItem(kReservationFailedCases,
1000 arraysize(kReservationFailedCases));
1001 }
1002
1003 // If the local path could not be determined, the download should be cancelled.
1004 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_LocalPathFailed) {
1005 const DownloadTestCase kLocalPathFailedCases[] = {
1006 {
1007 // 0: Automatic download.
1008 AUTOMATIC,
1009 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
1010 "http://example.com/foo.txt", "text/plain",
1011 FILE_PATH_LITERAL(""),
1012
1013 FILE_PATH_LITERAL(""),
1014 FILE_PATH_LITERAL(""),
1015 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
1016
1017 EXPECT_LOCAL_PATH
1018 },
1019 };
1020
1021 base::FilePath expected_virtual_path(
1022 GetPathInDownloadDir(FILE_PATH_LITERAL("virtual/foo.txt")));
1023 // The default download directory is the virtual path.
1024 SetDefaultDownloadPath(test_virtual_dir());
1025 // Simulate failed call to DetermineLocalPath.
1026 EXPECT_CALL(*delegate(), DetermineLocalPath(
1027 _, GetPathInDownloadDir(FILE_PATH_LITERAL("virtual/foo.txt")), _))
1028 .WillOnce(WithArg<2>(ScheduleCallback(base::FilePath())));
1029 RunTestCasesWithActiveItem(kLocalPathFailedCases,
1030 arraysize(kLocalPathFailedCases));
1031 }
1032
1033 // Downloads that have a danger level of AllowOnUserGesture should be marked as
1034 // safe depending on whether there was a user gesture associated with the
1035 // download and whether the referrer was visited prior to today.
1036 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_VisitedReferrer) {
1037 const DownloadTestCase kVisitedReferrerCases[] = {
1038 // http://visited.example.com/ is added to the history as a visit that
1039 // happened prior to today.
1040 {
1041 // 0: Safe download due to visiting referrer before.
1042 AUTOMATIC,
1043 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
1044 "http://visited.example.com/foo.html", "text/html",
1045 FILE_PATH_LITERAL(""),
1046
1047 FILE_PATH_LITERAL(""),
1048 FILE_PATH_LITERAL("foo.html"),
1049 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
1050
1051 EXPECT_CRDOWNLOAD
1052 },
1053
1054 {
1055 // 1: Dangerous due to not having visited referrer before.
1056 AUTOMATIC,
1057 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
1058 "http://not-visited.example.com/foo.html", "text/html",
1059 FILE_PATH_LITERAL(""),
1060
1061 FILE_PATH_LITERAL(""),
1062 FILE_PATH_LITERAL("foo.html"),
1063 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
1064
1065 EXPECT_UNCONFIRMED
1066 },
1067
1068 {
1069 // 2: Safe because the user is being prompted.
1070 SAVE_AS,
1071 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
1072 "http://not-visited.example.com/foo.html", "text/html",
1073 FILE_PATH_LITERAL(""),
1074
1075 FILE_PATH_LITERAL(""),
1076 FILE_PATH_LITERAL("foo.html"),
1077 DownloadItem::TARGET_DISPOSITION_PROMPT,
1078
1079 EXPECT_CRDOWNLOAD
1080 },
1081
1082 {
1083 // 3: Safe because of forced path.
1084 FORCED,
1085 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
1086 "http://not-visited.example.com/foo.html", "text/html",
1087 FILE_PATH_LITERAL("foo.html"),
1088
1089 FILE_PATH_LITERAL(""),
1090 FILE_PATH_LITERAL("foo.html"),
1091 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
1092
1093 EXPECT_LOCAL_PATH
1094 },
1095 };
1096
1097 // This test assumes that the danger level of .html files is
1098 // AllowOnUserGesture.
1099 ASSERT_EQ(download_util::AllowOnUserGesture,
1100 download_util::GetFileDangerLevel(
1101 base::FilePath(FILE_PATH_LITERAL("foo.html"))));
1102
1103 // First the history service must exist.
1104 profile()->CreateHistoryService(false, false);
1105
1106 GURL url("http://visited.example.com/visited-link.html");
1107 // The time of visit is picked to be several seconds prior to the most recent
1108 // midnight.
1109 base::Time time_of_visit(
1110 base::Time::Now().LocalMidnight() - base::TimeDelta::FromSeconds(10));
1111 HistoryService* history_service =
1112 HistoryServiceFactory::GetForProfile(profile(), Profile::EXPLICIT_ACCESS);
1113 ASSERT_TRUE(history_service);
1114 history_service->AddPage(url, time_of_visit, history::SOURCE_BROWSED);
1115
1116 RunTestCasesWithActiveItem(kVisitedReferrerCases,
1117 arraysize(kVisitedReferrerCases));
1118 }
1119
1120 // These test cases are run with "Prompt for download" user preference set to
1121 // true.
1122 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_PromptAlways) {
1123 const DownloadTestCase kPromptingTestCases[] = {
1124 {
1125 // 0: Safe Automatic - Should prompt because of "Prompt for download"
1126 // preference setting.
1127 AUTOMATIC,
1128 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
1129 "http://example.com/foo.txt", "text/plain",
1130 FILE_PATH_LITERAL(""),
1131
1132 FILE_PATH_LITERAL(""),
1133 FILE_PATH_LITERAL("foo.txt"),
1134 DownloadItem::TARGET_DISPOSITION_PROMPT,
1135
1136 EXPECT_CRDOWNLOAD
1137 },
1138
1139 {
1140 // 1: Safe Forced - Shouldn't prompt.
1141 FORCED,
1142 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
1143 "http://example.com/foo.txt", "text/plain",
1144 FILE_PATH_LITERAL("foo.txt"),
1145
1146 FILE_PATH_LITERAL(""),
1147 FILE_PATH_LITERAL("foo.txt"),
1148 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
1149
1150 EXPECT_LOCAL_PATH
1151 },
1152
1153 {
1154 // 2: Automatic - The filename extension is marked as one that we will
1155 // open automatically. Shouldn't prompt.
1156 AUTOMATIC,
1157 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
1158 "http://example.com/foo.dummy", "",
1159 FILE_PATH_LITERAL(""),
1160
1161 FILE_PATH_LITERAL(""),
1162 FILE_PATH_LITERAL("foo.dummy"),
1163 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
1164
1165 EXPECT_CRDOWNLOAD
1166 },
1167 };
1168
1169 SetPromptForDownload(true);
1170 EnableAutoOpenBasedOnExtension(
1171 base::FilePath(FILE_PATH_LITERAL("dummy.dummy")));
1172 RunTestCasesWithActiveItem(kPromptingTestCases,
1173 arraysize(kPromptingTestCases));
1174 }
1175
1176 #if !defined(OS_ANDROID)
1177 // These test cases are run with "Prompt for download" user preference set to
1178 // true. Automatic extension downloads shouldn't cause prompting.
1179 // Android doesn't support extensions.
1180 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_PromptAlways_Extension) {
1181 const DownloadTestCase kPromptingTestCases[] = {
1182 {
1183 // 0: Automatic Browser Extension download. - Shouldn't prompt for browser
1184 // extension downloads even if "Prompt for download" preference is set.
1185 AUTOMATIC,
1186 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
1187 "http://example.com/foo.crx",
1188 extensions::Extension::kMimeType,
1189 FILE_PATH_LITERAL(""),
1190
1191 FILE_PATH_LITERAL(""),
1192 FILE_PATH_LITERAL("foo.crx"),
1193 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
1194
1195 EXPECT_UNCONFIRMED
1196 },
1197
1198 #if defined(OS_WIN)
1199 {
1200 // 1: Automatic User Script - Shouldn't prompt for user script downloads
1201 // even if "Prompt for download" preference is set. ".js" files are
1202 // considered dangerous on Windows.
1203 AUTOMATIC,
1204 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
1205 "http://example.com/foo.user.js", "",
1206 FILE_PATH_LITERAL(""),
1207
1208 FILE_PATH_LITERAL(""),
1209 FILE_PATH_LITERAL("foo.user.js"),
1210 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
1211
1212 EXPECT_UNCONFIRMED
1213 },
1214 #else
1215 {
1216 // 1: Automatic User Script - Shouldn't prompt for user script downloads
1217 // even if "Prompt for download" preference is set.
1218 AUTOMATIC,
1219 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
1220 "http://example.com/foo.user.js", "",
1221 FILE_PATH_LITERAL(""),
1222
1223 FILE_PATH_LITERAL(""),
1224 FILE_PATH_LITERAL("foo.user.js"),
1225 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
1226
1227 EXPECT_CRDOWNLOAD
1228 },
1229 #endif
1230 };
1231
1232 SetPromptForDownload(true);
1233 RunTestCasesWithActiveItem(kPromptingTestCases,
1234 arraysize(kPromptingTestCases));
1235 }
1236 #endif
1237
1238 // If the download path is managed, then we don't show any prompts.
1239 // Note that if the download path is managed, then PromptForDownload() is false.
1240 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ManagedPath) {
1241 const DownloadTestCase kManagedPathTestCases[] = {
1242 {
1243 // 0: Automatic Safe
1244 AUTOMATIC,
1245 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
1246 "http://example.com/foo.txt", "text/plain",
1247 FILE_PATH_LITERAL(""),
1248
1249 FILE_PATH_LITERAL(""),
1250 FILE_PATH_LITERAL("foo.txt"),
1251 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
1252
1253 EXPECT_CRDOWNLOAD
1254 },
1255
1256 {
1257 // 1: Save_As Safe
1258 SAVE_AS,
1259 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
1260 "http://example.com/foo.txt", "text/plain",
1261 FILE_PATH_LITERAL(""),
1262
1263 FILE_PATH_LITERAL(""),
1264 FILE_PATH_LITERAL("foo.txt"),
1265 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
1266
1267 EXPECT_CRDOWNLOAD
1268 },
1269 };
1270
1271 SetManagedDownloadPath(test_download_dir());
1272 ASSERT_TRUE(download_prefs()->IsDownloadPathManaged());
1273 RunTestCasesWithActiveItem(kManagedPathTestCases,
1274 arraysize(kManagedPathTestCases));
1275 }
1276
1277 // Test basic functionality supporting extensions that want to override download
1278 // filenames.
1279 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_NotifyExtensionsSafe) {
1280 const DownloadTestCase kNotifyExtensionsTestCases[] = {
1281 {
1282 // 0: Automatic Safe
1283 AUTOMATIC,
1284 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
1285 "http://example.com/foo.txt", "text/plain",
1286 FILE_PATH_LITERAL(""),
1287
1288 FILE_PATH_LITERAL(""),
1289 FILE_PATH_LITERAL("overridden/foo.txt"),
1290 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
1291
1292 EXPECT_CRDOWNLOAD
1293 },
1294
1295 {
1296 // 1: Save_As Safe
1297 SAVE_AS,
1298 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
1299 "http://example.com/foo.txt", "text/plain",
1300 FILE_PATH_LITERAL(""),
1301
1302 FILE_PATH_LITERAL(""),
1303 FILE_PATH_LITERAL("overridden/foo.txt"),
1304 DownloadItem::TARGET_DISPOSITION_PROMPT,
1305
1306 EXPECT_CRDOWNLOAD
1307 },
1308
1309 {
1310 // 2: Automatic Dangerous
1311 AUTOMATIC,
1312 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
1313 "http://example.com/foo.html", "",
1314 FILE_PATH_LITERAL(""),
1315
1316 FILE_PATH_LITERAL(""),
1317 FILE_PATH_LITERAL("overridden/foo.html"),
1318 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
1319
1320 EXPECT_UNCONFIRMED
1321 },
1322
1323 {
1324 // 3: Forced Safe
1325 FORCED,
1326 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
1327 "http://example.com/foo.txt", "",
1328 FILE_PATH_LITERAL("forced-foo.txt"),
1329
1330 FILE_PATH_LITERAL(""),
1331 FILE_PATH_LITERAL("forced-foo.txt"),
1332 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
1333
1334 EXPECT_LOCAL_PATH
1335 },
1336 };
1337
1338 ON_CALL(*delegate(), NotifyExtensions(_, _, _))
1339 .WillByDefault(Invoke(&NotifyExtensionsOverridePath));
1340 RunTestCasesWithActiveItem(kNotifyExtensionsTestCases,
1341 arraysize(kNotifyExtensionsTestCases));
1342 }
1343
1344 // Test that filenames provided by extensions are passed into SafeBrowsing
1345 // checks and dangerous download checks.
1346 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_NotifyExtensionsUnsafe) {
1347 const DownloadTestCase kNotifyExtensionsTestCases[] = {
1348 {
1349 // 0: Automatic Safe : Later overridden by a dangerous filetype.
1350 AUTOMATIC,
1351 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
1352 "http://example.com/foo.html.remove", "text/plain",
1353 FILE_PATH_LITERAL(""),
1354
1355 FILE_PATH_LITERAL(""),
1356 FILE_PATH_LITERAL("overridden/foo.html"),
1357 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
1358
1359 EXPECT_UNCONFIRMED
1360 },
1361
1362 {
1363 // 1: Automatic Safe : Later overridden by a potentially dangerous
1364 // filetype.
1365 AUTOMATIC,
1366 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
1367 "http://example.com/foo.exe.remove", "text/plain",
1368 FILE_PATH_LITERAL(""),
1369
1370 FILE_PATH_LITERAL(""),
1371 FILE_PATH_LITERAL("overridden/foo.exe"),
1372 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
1373
1374 EXPECT_UNCONFIRMED
1375 },
1376 };
1377
1378 ON_CALL(*delegate(), NotifyExtensions(_, _, _))
1379 .WillByDefault(Invoke(&NotifyExtensionsOverridePath));
1380 ON_CALL(*delegate(), CheckDownloadUrl(_, _, _))
1381 .WillByDefault(Invoke(&CheckDownloadUrlCheckExes));
1382 RunTestCasesWithActiveItem(kNotifyExtensionsTestCases,
1383 arraysize(kNotifyExtensionsTestCases));
1384 }
1385
1386 // Test that conflict actions set by extensions are passed correctly into
1387 // ReserveVirtualPath.
1388 TEST_F(DownloadTargetDeterminerTest,
1389 TargetDeterminer_NotifyExtensionsConflict) {
1390 const DownloadTestCase kNotifyExtensionsTestCase = {
1391 AUTOMATIC,
1392 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
1393 "http://example.com/foo.txt", "text/plain",
1394 FILE_PATH_LITERAL(""),
1395
1396 FILE_PATH_LITERAL(""),
1397 FILE_PATH_LITERAL("overridden/foo.txt"),
1398 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
1399
1400 EXPECT_CRDOWNLOAD
1401 };
1402
1403 const DownloadTestCase& test_case = kNotifyExtensionsTestCase;
1404 scoped_ptr<content::MockDownloadItem> item(
1405 CreateActiveDownloadItem(0, test_case));
1406 base::FilePath overridden_path(FILE_PATH_LITERAL("overridden/foo.txt"));
1407 base::FilePath full_overridden_path =
1408 GetPathInDownloadDir(overridden_path.value());
1409
1410 // First case: An extension sets the conflict_action to OVERWRITE.
1411 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _))
1412 .WillOnce(WithArg<2>(
1413 ScheduleCallback2(overridden_path,
1414 DownloadPathReservationTracker::OVERWRITE)));
1415 EXPECT_CALL(*delegate(), ReserveVirtualPath(
1416 _, full_overridden_path, DownloadPathReservationTracker::OVERWRITE, _))
1417 .WillOnce(WithArg<3>(
1418 ScheduleCallback2(full_overridden_path, true)));
1419
1420 RunTestCase(test_case, item.get());
1421
1422 // Second case: An extension sets the conflict_action to PROMPT.
1423 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _))
1424 .WillOnce(WithArg<2>(
1425 ScheduleCallback2(overridden_path,
1426 DownloadPathReservationTracker::PROMPT)));
1427 EXPECT_CALL(*delegate(), ReserveVirtualPath(
1428 _, full_overridden_path, DownloadPathReservationTracker::PROMPT, _))
1429 .WillOnce(WithArg<3>(
1430 ScheduleCallback2(full_overridden_path, true)));
1431 RunTestCase(test_case, item.get());
1432 }
1433
1434 // Test that relative paths returned by extensions are always relative to the
1435 // default downloads path.
1436 TEST_F(DownloadTargetDeterminerTest,
1437 TargetDeterminer_NotifyExtensionsDefaultPath) {
1438 const DownloadTestCase kNotifyExtensionsTestCase = {
1439 SAVE_AS,
1440 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
1441 "http://example.com/foo.txt", "text/plain",
1442 FILE_PATH_LITERAL(""),
1443
1444 FILE_PATH_LITERAL(""),
1445 FILE_PATH_LITERAL("overridden/foo.txt"),
1446 DownloadItem::TARGET_DISPOSITION_PROMPT,
1447
1448 EXPECT_CRDOWNLOAD
1449 };
1450
1451 const DownloadTestCase& test_case = kNotifyExtensionsTestCase;
1452 scoped_ptr<content::MockDownloadItem> item(
1453 CreateActiveDownloadItem(0, test_case));
1454 base::FilePath overridden_path(FILE_PATH_LITERAL("overridden/foo.txt"));
1455 base::FilePath full_overridden_path =
1456 GetPathInDownloadDir(overridden_path.value());
1457
1458 // The last selected directory is this one. Since the test case is a SAVE_AS
1459 // download, it should use this directory for the generated path.
1460 set_last_selected_directory(GetPathInDownloadDir(
1461 FILE_PATH_LITERAL("last_selected")));
1462
1463 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _))
1464 .WillOnce(WithArg<2>(
1465 ScheduleCallback2(overridden_path,
1466 DownloadPathReservationTracker::UNIQUIFY)));
1467 EXPECT_CALL(*delegate(),
1468 PromptUserForDownloadPath(_, full_overridden_path, _))
1469 .WillOnce(WithArg<2>(
1470 ScheduleCallback(full_overridden_path)));
1471 RunTestCase(test_case, item.get());
1472 }
1473 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698