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/at_exit.h" 6 #include "base/files/file_path.h" 7 #include "base/files/scoped_temp_dir.h" 8 #include "base/message_loop/message_loop.h" 9 #include "base/observer_list.h" 10 #include "base/prefs/pref_service.h" 11 #include "base/run_loop.h" 12 #include "base/stl_util.h" 13 #include "base/strings/string_util.h" 14 #include "base/value_conversions.h" 15 #include "chrome/browser/download/chrome_download_manager_delegate.h" 16 #include "chrome/browser/download/download_extensions.h" 17 #include "chrome/browser/download/download_prefs.h" 18 #include "chrome/browser/download/download_target_determiner.h" 19 #include "chrome/browser/download/download_target_info.h" 20 #include "chrome/browser/history/history_service.h" 21 #include "chrome/browser/history/history_service_factory.h" 22 #include "chrome/browser/history/history_types.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/download_interrupt_reasons.h" 28 #include "content/public/browser/render_process_host.h" 29 #include "content/public/browser/web_contents.h" 30 #include "content/public/browser/web_contents_delegate.h" 31 #include "content/public/test/mock_download_item.h" 32 #include "content/public/test/test_browser_thread.h" 33 #include "content/public/test/test_renderer_host.h" 34 #include "content/public/test/web_contents_tester.h" 35 #include "extensions/common/extension.h" 36 #include "net/base/mime_util.h" 37 #include "testing/gmock/include/gmock/gmock.h" 38 #include "testing/gtest/include/gtest/gtest.h" 39 40 #if defined(ENABLE_PLUGINS) 41 #include "chrome/browser/plugins/plugin_prefs.h" 42 #include "content/public/browser/plugin_service.h" 43 #include "content/public/common/webplugininfo.h" 44 #endif 45 46 using ::testing::AnyNumber; 47 using ::testing::Invoke; 48 using ::testing::Ref; 49 using ::testing::Return; 50 using ::testing::ReturnRef; 51 using ::testing::ReturnRefOfCopy; 52 using ::testing::Truly; 53 using ::testing::WithArg; 54 using ::testing::_; 55 using content::DownloadItem; 56 57 namespace { 58 59 // No-op delegate. 60 class NullWebContentsDelegate : public content::WebContentsDelegate { 61 public: 62 NullWebContentsDelegate() {} 63 virtual ~NullWebContentsDelegate() {} 64 }; 65 66 // Google Mock action that posts a task to the current message loop that invokes 67 // the first argument of the mocked method as a callback. Said argument must be 68 // a base::Callback<void(ParamType)>. |result| must be of |ParamType| and is 69 // bound as that parameter. 70 // Example: 71 // class FooClass { 72 // public: 73 // virtual void Foo(base::Callback<void(bool)> callback); 74 // }; 75 // ... 76 // EXPECT_CALL(mock_fooclass_instance, Foo(callback)) 77 // .WillOnce(ScheduleCallback(false)); 78 ACTION_P(ScheduleCallback, result0) { 79 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(arg0, result0)); 80 } 81 82 // Similar to ScheduleCallback, but binds 2 arguments. 83 ACTION_P2(ScheduleCallback2, result0, result1) { 84 base::MessageLoop::current()->PostTask( 85 FROM_HERE, base::Bind(arg0, result0, result1)); 86 } 87 88 // Used with DownloadTestCase. Indicates the type of test case. The expectations 89 // for the test is set based on the type. 90 enum TestCaseType { 91 SAVE_AS, 92 AUTOMATIC, 93 FORCED // Requires that forced_file_path be non-empty. 94 }; 95 96 // Used with DownloadTestCase. Type of intermediate filename to expect. 97 enum TestCaseExpectIntermediate { 98 EXPECT_CRDOWNLOAD, // Expect path/to/target.crdownload. 99 EXPECT_UNCONFIRMED, // Expect path/to/Unconfirmed xxx.crdownload. 100 EXPECT_LOCAL_PATH, // Expect target path. 101 }; 102 103 // Typical download test case. Used with 104 // DownloadTargetDeterminerTest::RunTestCase(). 105 struct DownloadTestCase { 106 // Type of test. 107 TestCaseType test_type; 108 109 // Expected danger type. Verified at the end of target determination. 110 content::DownloadDangerType expected_danger_type; 111 112 // Value of DownloadItem::GetURL() 113 const char* url; 114 115 // Value of DownloadItem::GetMimeType() 116 const char* mime_type; 117 118 // Should be non-empty if |test_type| == FORCED. Value of GetForcedFilePath(). 119 const base::FilePath::CharType* forced_file_path; 120 121 // Expected virtual path. Specified relative to the virtual download path. If 122 // empty, assumed to be the same as |expected_local_path|. 123 const base::FilePath::CharType* expected_virtual_path; 124 125 // Expected local path. Specified relative to the test download path. 126 const base::FilePath::CharType* expected_local_path; 127 128 // Expected target disposition. If this is TARGET_DISPOSITION_PROMPT, then the 129 // test run will expect ChromeDownloadManagerDelegate to prompt the user for a 130 // download location. 131 DownloadItem::TargetDisposition expected_disposition; 132 133 // Type of intermediate path to expect. 134 TestCaseExpectIntermediate expected_intermediate; 135 }; 136 137 class MockDownloadTargetDeterminerDelegate 138 : public DownloadTargetDeterminerDelegate { 139 public: 140 MOCK_METHOD3(CheckDownloadUrl, 141 void(content::DownloadItem*, const base::FilePath&, 142 const CheckDownloadUrlCallback&)); 143 MOCK_METHOD3(NotifyExtensions, 144 void(content::DownloadItem*, const base::FilePath&, 145 const NotifyExtensionsCallback&)); 146 MOCK_METHOD3(PromptUserForDownloadPath, 147 void(content::DownloadItem*, const base::FilePath&, 148 const FileSelectedCallback&)); 149 MOCK_METHOD3(DetermineLocalPath, 150 void(DownloadItem*, const base::FilePath&, 151 const LocalPathCallback&)); 152 MOCK_METHOD5(ReserveVirtualPath, 153 void(DownloadItem*, const base::FilePath&, bool, 154 DownloadPathReservationTracker::FilenameConflictAction, 155 const ReservedPathCallback&)); 156 MOCK_METHOD2(GetFileMimeType, 157 void(const base::FilePath&, 158 const GetFileMimeTypeCallback&)); 159 160 void SetupDefaults() { 161 ON_CALL(*this, CheckDownloadUrl(_, _, _)) 162 .WillByDefault(WithArg<2>( 163 ScheduleCallback(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS))); 164 ON_CALL(*this, NotifyExtensions(_, _, _)) 165 .WillByDefault(WithArg<2>( 166 ScheduleCallback2(base::FilePath(), 167 DownloadPathReservationTracker::UNIQUIFY))); 168 ON_CALL(*this, ReserveVirtualPath(_, _, _, _, _)) 169 .WillByDefault(Invoke( 170 &MockDownloadTargetDeterminerDelegate::NullReserveVirtualPath)); 171 ON_CALL(*this, PromptUserForDownloadPath(_, _, _)) 172 .WillByDefault(Invoke( 173 &MockDownloadTargetDeterminerDelegate::NullPromptUser)); 174 ON_CALL(*this, DetermineLocalPath(_, _, _)) 175 .WillByDefault(Invoke( 176 &MockDownloadTargetDeterminerDelegate::NullDetermineLocalPath)); 177 ON_CALL(*this, GetFileMimeType(_, _)) 178 .WillByDefault(WithArg<1>( 179 ScheduleCallback(""))); 180 } 181 private: 182 static void NullReserveVirtualPath( 183 DownloadItem* download, 184 const base::FilePath& virtual_path, 185 bool create_directory, 186 DownloadPathReservationTracker::FilenameConflictAction conflict_action, 187 const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback); 188 static void NullPromptUser( 189 DownloadItem* download, const base::FilePath& suggested_path, 190 const FileSelectedCallback& callback); 191 static void NullDetermineLocalPath( 192 DownloadItem* download, const base::FilePath& virtual_path, 193 const LocalPathCallback& callback); 194 }; 195 196 class DownloadTargetDeterminerTest : public ChromeRenderViewHostTestHarness { 197 public: 198 // ::testing::Test 199 virtual void SetUp() OVERRIDE; 200 virtual void TearDown() OVERRIDE; 201 202 // Creates MockDownloadItem and sets up default expectations. 203 content::MockDownloadItem* CreateActiveDownloadItem( 204 int32 id, 205 const DownloadTestCase& test_case); 206 207 // Sets the AutoOpenBasedOnExtension user preference for |path|. 208 void EnableAutoOpenBasedOnExtension(const base::FilePath& path); 209 210 // Set the kDownloadDefaultDirectory managed preference to |path|. 211 void SetManagedDownloadPath(const base::FilePath& path); 212 213 // Set the kPromptForDownload user preference to |prompt|. 214 void SetPromptForDownload(bool prompt); 215 216 // Given the relative path |path|, returns the full path under the temporary 217 // downloads directory. 218 base::FilePath GetPathInDownloadDir(const base::FilePath::StringType& path); 219 220 // Run |test_case| using |item|. 221 void RunTestCase(const DownloadTestCase& test_case, 222 const base::FilePath& initial_virtual_path, 223 content::MockDownloadItem* item); 224 225 // Runs |test_case| with |item|. When the DownloadTargetDeterminer is done, 226 // returns the resulting DownloadTargetInfo. 227 scoped_ptr<DownloadTargetInfo> RunDownloadTargetDeterminer( 228 const base::FilePath& initial_virtual_path, 229 content::MockDownloadItem* item); 230 231 // Run through |test_case_count| tests in |test_cases|. A new MockDownloadItem 232 // will be created for each test case and destroyed when the test case is 233 // complete. 234 void RunTestCasesWithActiveItem(const DownloadTestCase test_cases[], 235 size_t test_case_count); 236 237 // Verifies that |target_path|, |disposition|, |expected_danger_type| and 238 // |intermediate_path| matches the expectations of |test_case|. Posts 239 // |closure| to the current message loop when done. 240 void VerifyDownloadTarget(const DownloadTestCase& test_case, 241 const DownloadTargetInfo* target_info); 242 243 const base::FilePath& test_download_dir() const { 244 return test_download_dir_.path(); 245 } 246 247 const base::FilePath& test_virtual_dir() const { 248 return test_virtual_dir_; 249 } 250 251 MockDownloadTargetDeterminerDelegate* delegate() { 252 return &delegate_; 253 } 254 255 DownloadPrefs* download_prefs() { 256 return download_prefs_.get(); 257 } 258 259 private: 260 scoped_ptr<DownloadPrefs> download_prefs_; 261 ::testing::NiceMock<MockDownloadTargetDeterminerDelegate> delegate_; 262 NullWebContentsDelegate web_contents_delegate_; 263 base::ScopedTempDir test_download_dir_; 264 base::FilePath test_virtual_dir_; 265 }; 266 267 void DownloadTargetDeterminerTest::SetUp() { 268 ChromeRenderViewHostTestHarness::SetUp(); 269 CHECK(profile()); 270 download_prefs_.reset(new DownloadPrefs(profile())); 271 web_contents()->SetDelegate(&web_contents_delegate_); 272 ASSERT_TRUE(test_download_dir_.CreateUniqueTempDir()); 273 test_virtual_dir_ = test_download_dir().Append(FILE_PATH_LITERAL("virtual")); 274 download_prefs_->SetDownloadPath(test_download_dir()); 275 delegate_.SetupDefaults(); 276 } 277 278 void DownloadTargetDeterminerTest::TearDown() { 279 download_prefs_.reset(); 280 ChromeRenderViewHostTestHarness::TearDown(); 281 } 282 283 content::MockDownloadItem* 284 DownloadTargetDeterminerTest::CreateActiveDownloadItem( 285 int32 id, 286 const DownloadTestCase& test_case) { 287 content::MockDownloadItem* item = 288 new ::testing::NiceMock<content::MockDownloadItem>(); 289 GURL download_url(test_case.url); 290 std::vector<GURL> url_chain; 291 url_chain.push_back(download_url); 292 base::FilePath forced_file_path = 293 GetPathInDownloadDir(test_case.forced_file_path); 294 DownloadItem::TargetDisposition initial_disposition = 295 (test_case.test_type == SAVE_AS) ? 296 DownloadItem::TARGET_DISPOSITION_PROMPT : 297 DownloadItem::TARGET_DISPOSITION_OVERWRITE; 298 EXPECT_EQ(test_case.test_type == FORCED, 299 !forced_file_path.empty()); 300 301 ON_CALL(*item, GetBrowserContext()) 302 .WillByDefault(Return(profile())); 303 ON_CALL(*item, GetDangerType()) 304 .WillByDefault(Return(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS)); 305 ON_CALL(*item, GetForcedFilePath()) 306 .WillByDefault(ReturnRefOfCopy(forced_file_path)); 307 ON_CALL(*item, GetFullPath()) 308 .WillByDefault(ReturnRefOfCopy(base::FilePath())); 309 ON_CALL(*item, GetHash()) 310 .WillByDefault(ReturnRefOfCopy(std::string())); 311 ON_CALL(*item, GetId()) 312 .WillByDefault(Return(id)); 313 ON_CALL(*item, GetLastReason()) 314 .WillByDefault(Return(content::DOWNLOAD_INTERRUPT_REASON_NONE)); 315 ON_CALL(*item, GetMimeType()) 316 .WillByDefault(Return(test_case.mime_type)); 317 ON_CALL(*item, GetReferrerUrl()) 318 .WillByDefault(ReturnRefOfCopy(download_url)); 319 ON_CALL(*item, GetState()) 320 .WillByDefault(Return(DownloadItem::IN_PROGRESS)); 321 ON_CALL(*item, GetTargetDisposition()) 322 .WillByDefault(Return(initial_disposition)); 323 ON_CALL(*item, GetTargetFilePath()) 324 .WillByDefault(ReturnRefOfCopy(base::FilePath())); 325 ON_CALL(*item, GetTransitionType()) 326 .WillByDefault(Return(content::PAGE_TRANSITION_LINK)); 327 ON_CALL(*item, GetURL()) 328 .WillByDefault(ReturnRefOfCopy(download_url)); 329 ON_CALL(*item, GetUrlChain()) 330 .WillByDefault(ReturnRefOfCopy(url_chain)); 331 ON_CALL(*item, GetWebContents()) 332 .WillByDefault(Return(web_contents())); 333 ON_CALL(*item, HasUserGesture()) 334 .WillByDefault(Return(true)); 335 ON_CALL(*item, IsDangerous()) 336 .WillByDefault(Return(false)); 337 ON_CALL(*item, IsTemporary()) 338 .WillByDefault(Return(false)); 339 return item; 340 } 341 342 void DownloadTargetDeterminerTest::EnableAutoOpenBasedOnExtension( 343 const base::FilePath& path) { 344 EXPECT_TRUE(download_prefs_->EnableAutoOpenBasedOnExtension(path)); 345 } 346 347 void DownloadTargetDeterminerTest::SetManagedDownloadPath( 348 const base::FilePath& path) { 349 profile()->GetTestingPrefService()-> 350 SetManagedPref(prefs::kDownloadDefaultDirectory, 351 base::CreateFilePathValue(path)); 352 } 353 354 void DownloadTargetDeterminerTest::SetPromptForDownload(bool prompt) { 355 profile()->GetTestingPrefService()-> 356 SetBoolean(prefs::kPromptForDownload, prompt); 357 } 358 359 base::FilePath DownloadTargetDeterminerTest::GetPathInDownloadDir( 360 const base::FilePath::StringType& relative_path) { 361 if (relative_path.empty()) 362 return base::FilePath(); 363 base::FilePath full_path(test_download_dir().Append(relative_path)); 364 return full_path.NormalizePathSeparators(); 365 } 366 367 void DownloadTargetDeterminerTest::RunTestCase( 368 const DownloadTestCase& test_case, 369 const base::FilePath& initial_virtual_path, 370 content::MockDownloadItem* item) { 371 scoped_ptr<DownloadTargetInfo> target_info = 372 RunDownloadTargetDeterminer(initial_virtual_path, item); 373 VerifyDownloadTarget(test_case, target_info.get()); 374 } 375 376 void CompletionCallbackWrapper( 377 const base::Closure& closure, 378 scoped_ptr<DownloadTargetInfo>* target_info_receiver, 379 scoped_ptr<DownloadTargetInfo> target_info) { 380 target_info_receiver->swap(target_info); 381 base::MessageLoop::current()->PostTask(FROM_HERE, closure); 382 } 383 384 scoped_ptr<DownloadTargetInfo> 385 DownloadTargetDeterminerTest::RunDownloadTargetDeterminer( 386 const base::FilePath& initial_virtual_path, 387 content::MockDownloadItem* item) { 388 scoped_ptr<DownloadTargetInfo> target_info; 389 base::RunLoop run_loop; 390 DownloadTargetDeterminer::Start( 391 item, initial_virtual_path, download_prefs_.get(), delegate(), 392 base::Bind(&CompletionCallbackWrapper, 393 run_loop.QuitClosure(), 394 &target_info)); 395 run_loop.Run(); 396 ::testing::Mock::VerifyAndClearExpectations(delegate()); 397 return target_info.Pass(); 398 } 399 400 void DownloadTargetDeterminerTest::RunTestCasesWithActiveItem( 401 const DownloadTestCase test_cases[], 402 size_t test_case_count) { 403 for (size_t i = 0; i < test_case_count; ++i) { 404 scoped_ptr<content::MockDownloadItem> item( 405 CreateActiveDownloadItem(i, test_cases[i])); 406 SCOPED_TRACE(testing::Message() << "Running test case " << i); 407 RunTestCase(test_cases[i], base::FilePath(), item.get()); 408 } 409 } 410 411 void DownloadTargetDeterminerTest::VerifyDownloadTarget( 412 const DownloadTestCase& test_case, 413 const DownloadTargetInfo* target_info) { 414 base::FilePath expected_local_path( 415 GetPathInDownloadDir(test_case.expected_local_path)); 416 EXPECT_EQ(expected_local_path.value(), target_info->target_path.value()); 417 EXPECT_EQ(test_case.expected_disposition, target_info->target_disposition); 418 EXPECT_EQ(test_case.expected_danger_type, target_info->danger_type); 419 420 switch (test_case.expected_intermediate) { 421 case EXPECT_CRDOWNLOAD: 422 EXPECT_EQ(DownloadTargetDeterminer::GetCrDownloadPath( 423 target_info->target_path).value(), 424 target_info->intermediate_path.value()); 425 break; 426 427 case EXPECT_UNCONFIRMED: 428 // The paths (in English) look like: /path/Unconfirmed xxx.crdownload. 429 // Of this, we only check that the path is: 430 // 1. Not "/path/target.crdownload", 431 // 2. Points to the same directory as the target. 432 // 3. Has extension ".crdownload". 433 // 4. Basename starts with "Unconfirmed ". 434 EXPECT_NE(DownloadTargetDeterminer::GetCrDownloadPath(expected_local_path) 435 .value(), 436 target_info->intermediate_path.value()); 437 EXPECT_EQ(expected_local_path.DirName().value(), 438 target_info->intermediate_path.DirName().value()); 439 EXPECT_TRUE(target_info->intermediate_path.MatchesExtension( 440 FILE_PATH_LITERAL(".crdownload"))); 441 EXPECT_EQ(0u, 442 target_info->intermediate_path.BaseName().value().find( 443 FILE_PATH_LITERAL("Unconfirmed "))); 444 break; 445 446 case EXPECT_LOCAL_PATH: 447 EXPECT_EQ(expected_local_path.value(), 448 target_info->intermediate_path.value()); 449 break; 450 } 451 } 452 453 // static 454 void MockDownloadTargetDeterminerDelegate::NullReserveVirtualPath( 455 DownloadItem* download, 456 const base::FilePath& virtual_path, 457 bool create_directory, 458 DownloadPathReservationTracker::FilenameConflictAction conflict_action, 459 const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback) { 460 callback.Run(virtual_path, true); 461 } 462 463 // static 464 void MockDownloadTargetDeterminerDelegate::NullPromptUser( 465 DownloadItem* download, const base::FilePath& suggested_path, 466 const FileSelectedCallback& callback) { 467 callback.Run(suggested_path); 468 } 469 470 // static 471 void MockDownloadTargetDeterminerDelegate::NullDetermineLocalPath( 472 DownloadItem* download, const base::FilePath& virtual_path, 473 const LocalPathCallback& callback) { 474 callback.Run(virtual_path); 475 } 476 477 // NotifyExtensions implementation that overrides the path so that the target 478 // file is in a subdirectory called 'overridden'. If the extension is '.remove', 479 // the extension is removed. 480 void NotifyExtensionsOverridePath( 481 content::DownloadItem* download, 482 const base::FilePath& path, 483 const DownloadTargetDeterminerDelegate::NotifyExtensionsCallback& 484 callback) { 485 base::FilePath new_path = 486 base::FilePath() 487 .AppendASCII("overridden") 488 .Append(path.BaseName()); 489 if (new_path.MatchesExtension(FILE_PATH_LITERAL(".remove"))) 490 new_path = new_path.RemoveExtension(); 491 callback.Run(new_path, DownloadPathReservationTracker::UNIQUIFY); 492 } 493 494 void CheckDownloadUrlCheckExes( 495 content::DownloadItem* download, 496 const base::FilePath& path, 497 const DownloadTargetDeterminerDelegate::CheckDownloadUrlCallback& 498 callback) { 499 if (path.MatchesExtension(FILE_PATH_LITERAL(".exe"))) 500 callback.Run(content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT); 501 else 502 callback.Run(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); 503 } 504 505 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_Basic) { 506 const DownloadTestCase kBasicTestCases[] = { 507 { 508 // 0: Automatic Safe 509 AUTOMATIC, 510 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 511 "http://example.com/foo.txt", "text/plain", 512 FILE_PATH_LITERAL(""), 513 514 FILE_PATH_LITERAL(""), 515 FILE_PATH_LITERAL("foo.txt"), 516 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 517 518 EXPECT_CRDOWNLOAD 519 }, 520 521 { 522 // 1: Save_As Safe 523 SAVE_AS, 524 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 525 "http://example.com/foo.txt", "text/plain", 526 FILE_PATH_LITERAL(""), 527 528 FILE_PATH_LITERAL(""), 529 FILE_PATH_LITERAL("foo.txt"), 530 DownloadItem::TARGET_DISPOSITION_PROMPT, 531 532 EXPECT_CRDOWNLOAD 533 }, 534 535 { 536 // 2: Automatic Dangerous 537 AUTOMATIC, 538 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, 539 "http://example.com/foo.crx", "", 540 FILE_PATH_LITERAL(""), 541 542 FILE_PATH_LITERAL(""), 543 FILE_PATH_LITERAL("foo.crx"), 544 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 545 546 EXPECT_UNCONFIRMED 547 }, 548 549 { 550 // 3: Forced Safe 551 FORCED, 552 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 553 "http://example.com/foo.txt", "", 554 FILE_PATH_LITERAL("forced-foo.txt"), 555 556 FILE_PATH_LITERAL(""), 557 FILE_PATH_LITERAL("forced-foo.txt"), 558 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 559 560 EXPECT_LOCAL_PATH 561 }, 562 }; 563 564 // The test assumes that .crx files have a danger level of 565 // ALLOW_ON_USER_GESTURE. 566 ASSERT_EQ(download_util::ALLOW_ON_USER_GESTURE, 567 download_util::GetFileDangerLevel( 568 base::FilePath(FILE_PATH_LITERAL("foo.crx")))); 569 RunTestCasesWithActiveItem(kBasicTestCases, arraysize(kBasicTestCases)); 570 } 571 572 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_CancelSaveAs) { 573 const DownloadTestCase kCancelSaveAsTestCases[] = { 574 { 575 // 0: Save_As Safe, Cancelled. 576 SAVE_AS, 577 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 578 "http://example.com/foo.txt", "text/plain", 579 FILE_PATH_LITERAL(""), 580 581 FILE_PATH_LITERAL(""), 582 FILE_PATH_LITERAL(""), 583 DownloadItem::TARGET_DISPOSITION_PROMPT, 584 585 EXPECT_LOCAL_PATH 586 } 587 }; 588 ON_CALL(*delegate(), PromptUserForDownloadPath(_, _, _)) 589 .WillByDefault(WithArg<2>(ScheduleCallback(base::FilePath()))); 590 RunTestCasesWithActiveItem(kCancelSaveAsTestCases, 591 arraysize(kCancelSaveAsTestCases)); 592 } 593 594 // The SafeBrowsing check is performed early. Make sure that a download item 595 // that has been marked as DANGEROUS_URL behaves correctly. 596 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_DangerousUrl) { 597 const DownloadTestCase kSafeBrowsingTestCases[] = { 598 { 599 // 0: Automatic Dangerous URL 600 AUTOMATIC, 601 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, 602 "http://phishing.example.com/foo.txt", "", 603 FILE_PATH_LITERAL(""), 604 605 FILE_PATH_LITERAL(""), 606 FILE_PATH_LITERAL("foo.txt"), 607 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 608 609 EXPECT_UNCONFIRMED 610 }, 611 612 { 613 // 1: Save As Dangerous URL 614 SAVE_AS, 615 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, 616 "http://phishing.example.com/foo.txt", "", 617 FILE_PATH_LITERAL(""), 618 619 FILE_PATH_LITERAL(""), 620 FILE_PATH_LITERAL("foo.txt"), 621 DownloadItem::TARGET_DISPOSITION_PROMPT, 622 623 EXPECT_UNCONFIRMED 624 }, 625 626 { 627 // 2: Forced Dangerous URL 628 FORCED, 629 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, 630 "http://phishing.example.com/foo.txt", "", 631 FILE_PATH_LITERAL("forced-foo.txt"), 632 633 FILE_PATH_LITERAL(""), 634 FILE_PATH_LITERAL("forced-foo.txt"), 635 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 636 637 EXPECT_UNCONFIRMED 638 }, 639 640 { 641 // 3: Automatic Dangerous URL + Dangerous file. Dangerous URL takes 642 // precendence. 643 AUTOMATIC, 644 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, 645 "http://phishing.example.com/foo.html", "", 646 FILE_PATH_LITERAL(""), 647 648 FILE_PATH_LITERAL(""), 649 FILE_PATH_LITERAL("foo.html"), 650 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 651 652 EXPECT_UNCONFIRMED 653 }, 654 655 { 656 // 4: Save As Dangerous URL + Dangerous file 657 SAVE_AS, 658 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, 659 "http://phishing.example.com/foo.html", "", 660 FILE_PATH_LITERAL(""), 661 662 FILE_PATH_LITERAL(""), 663 FILE_PATH_LITERAL("foo.html"), 664 DownloadItem::TARGET_DISPOSITION_PROMPT, 665 666 EXPECT_UNCONFIRMED 667 }, 668 669 { 670 // 5: Forced Dangerous URL + Dangerous file 671 FORCED, 672 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, 673 "http://phishing.example.com/foo.html", "", 674 FILE_PATH_LITERAL("forced-foo.html"), 675 676 FILE_PATH_LITERAL(""), 677 FILE_PATH_LITERAL("forced-foo.html"), 678 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 679 680 EXPECT_UNCONFIRMED 681 }, 682 }; 683 684 ON_CALL(*delegate(), CheckDownloadUrl(_, _, _)) 685 .WillByDefault(WithArg<2>(ScheduleCallback( 686 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL))); 687 RunTestCasesWithActiveItem(kSafeBrowsingTestCases, 688 arraysize(kSafeBrowsingTestCases)); 689 } 690 691 // The SafeBrowsing check is performed early. Make sure that a download item 692 // that has been marked as MAYBE_DANGEROUS_CONTENT behaves correctly. 693 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_MaybeDangerousContent) { 694 const DownloadTestCase kSafeBrowsingTestCases[] = { 695 { 696 // 0: Automatic Maybe dangerous content 697 AUTOMATIC, 698 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, 699 "http://phishing.example.com/foo.exe", "", 700 FILE_PATH_LITERAL(""), 701 702 FILE_PATH_LITERAL(""), 703 FILE_PATH_LITERAL("foo.exe"), 704 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 705 706 EXPECT_UNCONFIRMED 707 }, 708 709 { 710 // 1: Save As Maybe dangerous content 711 SAVE_AS, 712 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, 713 "http://phishing.example.com/foo.exe", "", 714 FILE_PATH_LITERAL(""), 715 716 FILE_PATH_LITERAL(""), 717 FILE_PATH_LITERAL("foo.exe"), 718 DownloadItem::TARGET_DISPOSITION_PROMPT, 719 720 EXPECT_UNCONFIRMED 721 }, 722 723 { 724 // 2: Forced Maybe dangerous content 725 FORCED, 726 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, 727 "http://phishing.example.com/foo.exe", "", 728 FILE_PATH_LITERAL("forced-foo.exe"), 729 730 FILE_PATH_LITERAL(""), 731 FILE_PATH_LITERAL("forced-foo.exe"), 732 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 733 734 EXPECT_UNCONFIRMED 735 }, 736 }; 737 738 ON_CALL(*delegate(), CheckDownloadUrl(_, _, _)) 739 .WillByDefault(WithArg<2>(ScheduleCallback( 740 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT))); 741 RunTestCasesWithActiveItem(kSafeBrowsingTestCases, 742 arraysize(kSafeBrowsingTestCases)); 743 } 744 745 // Test whether the last saved directory is used for 'Save As' downloads. 746 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_LastSavePath) { 747 const DownloadTestCase kLastSavePathTestCasesPre[] = { 748 { 749 // 0: If the last save path is empty, then the default download directory 750 // should be used. 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.txt"), 758 DownloadItem::TARGET_DISPOSITION_PROMPT, 759 760 EXPECT_CRDOWNLOAD 761 } 762 }; 763 764 // These test cases are run with a last save path set to a non-emtpy local 765 // download directory. 766 const DownloadTestCase kLastSavePathTestCasesPost[] = { 767 { 768 // 0: This test case is run with the last download directory set to 769 // '<test_download_dir()>/foo'. 770 SAVE_AS, 771 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 772 "http://example.com/foo.txt", "text/plain", 773 FILE_PATH_LITERAL(""), 774 775 FILE_PATH_LITERAL(""), 776 FILE_PATH_LITERAL("foo/foo.txt"), 777 DownloadItem::TARGET_DISPOSITION_PROMPT, 778 779 EXPECT_CRDOWNLOAD 780 }, 781 782 { 783 // 1: Start an automatic download. This should be saved to the user's 784 // default download directory and not the last used Save As directory. 785 AUTOMATIC, 786 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 787 "http://example.com/foo.txt", "text/plain", 788 FILE_PATH_LITERAL(""), 789 790 FILE_PATH_LITERAL(""), 791 FILE_PATH_LITERAL("foo.txt"), 792 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 793 794 EXPECT_CRDOWNLOAD 795 }, 796 }; 797 798 // This test case is run with the last save path set to a non-empty virtual 799 // directory. 800 const DownloadTestCase kLastSavePathTestCasesVirtual[] = { 801 { 802 SAVE_AS, 803 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 804 "http://example.com/foo.txt", "text/plain", 805 FILE_PATH_LITERAL(""), 806 807 FILE_PATH_LITERAL("virtual/foo/foo.txt"), 808 FILE_PATH_LITERAL("bar.txt"), 809 DownloadItem::TARGET_DISPOSITION_PROMPT, 810 811 EXPECT_LOCAL_PATH 812 }, 813 }; 814 815 { 816 SCOPED_TRACE(testing::Message() 817 << "Running with default download path"); 818 base::FilePath prompt_path = 819 GetPathInDownloadDir(FILE_PATH_LITERAL("foo.txt")); 820 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, prompt_path, _)); 821 RunTestCasesWithActiveItem(kLastSavePathTestCasesPre, 822 arraysize(kLastSavePathTestCasesPre)); 823 } 824 825 // Try with a non-empty last save path. 826 { 827 SCOPED_TRACE(testing::Message() 828 << "Running with local last_selected_directory"); 829 download_prefs()->SetSaveFilePath(test_download_dir().AppendASCII("foo")); 830 base::FilePath prompt_path = 831 GetPathInDownloadDir(FILE_PATH_LITERAL("foo/foo.txt")); 832 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, prompt_path, _)); 833 RunTestCasesWithActiveItem(kLastSavePathTestCasesPost, 834 arraysize(kLastSavePathTestCasesPost)); 835 } 836 837 // And again, but this time use a virtual directory. 838 { 839 SCOPED_TRACE(testing::Message() 840 << "Running with virtual last_selected_directory"); 841 base::FilePath last_selected_dir = test_virtual_dir().AppendASCII("foo"); 842 base::FilePath virtual_path = last_selected_dir.AppendASCII("foo.txt"); 843 download_prefs()->SetSaveFilePath(last_selected_dir); 844 EXPECT_CALL(*delegate(), PromptUserForDownloadPath( 845 _, last_selected_dir.AppendASCII("foo.txt"), _)); 846 EXPECT_CALL(*delegate(), DetermineLocalPath(_, virtual_path, _)) 847 .WillOnce(WithArg<2>(ScheduleCallback( 848 GetPathInDownloadDir(FILE_PATH_LITERAL("bar.txt"))))); 849 RunTestCasesWithActiveItem(kLastSavePathTestCasesVirtual, 850 arraysize(kLastSavePathTestCasesVirtual)); 851 } 852 } 853 854 // These tests are run with the default downloads folder set to a virtual 855 // directory. 856 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_DefaultVirtual) { 857 // The default download directory is the virutal path. 858 download_prefs()->SetDownloadPath(test_virtual_dir()); 859 860 { 861 SCOPED_TRACE(testing::Message() << "Automatic Safe Download"); 862 const DownloadTestCase kAutomaticDownloadToVirtualDir = { 863 AUTOMATIC, 864 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 865 "http://example.com/foo.txt", "text/plain", 866 FILE_PATH_LITERAL(""), 867 868 // Downloaded to default virtual directory. 869 FILE_PATH_LITERAL("virtual/foo.txt"), 870 FILE_PATH_LITERAL("foo-local.txt"), 871 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 872 873 EXPECT_LOCAL_PATH 874 }; 875 EXPECT_CALL(*delegate(), DetermineLocalPath(_, _, _)) 876 .WillOnce(WithArg<2>(ScheduleCallback( 877 GetPathInDownloadDir(FILE_PATH_LITERAL("foo-local.txt"))))); 878 RunTestCasesWithActiveItem(&kAutomaticDownloadToVirtualDir, 1); 879 } 880 881 { 882 SCOPED_TRACE(testing::Message() << "Save As to virtual directory"); 883 const DownloadTestCase kSaveAsToVirtualDir = { 884 SAVE_AS, 885 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 886 "http://example.com/bar.txt", "text/plain", 887 FILE_PATH_LITERAL(""), 888 889 // The response to the download prompt is to choose the 'prompted.txt' 890 // virtual path. 891 FILE_PATH_LITERAL("virtual/prompted.txt"), 892 FILE_PATH_LITERAL("foo-local.txt"), 893 DownloadItem::TARGET_DISPOSITION_PROMPT, 894 895 EXPECT_LOCAL_PATH 896 }; 897 EXPECT_CALL(*delegate(), DetermineLocalPath(_, _, _)) 898 .WillOnce(WithArg<2>(ScheduleCallback( 899 GetPathInDownloadDir(FILE_PATH_LITERAL("foo-local.txt"))))); 900 EXPECT_CALL(*delegate(), PromptUserForDownloadPath( 901 _, test_virtual_dir().AppendASCII("bar.txt"), _)) 902 .WillOnce(WithArg<2>(ScheduleCallback( 903 test_virtual_dir().AppendASCII("prompted.txt")))); 904 RunTestCasesWithActiveItem(&kSaveAsToVirtualDir, 1); 905 } 906 907 { 908 SCOPED_TRACE(testing::Message() << "Save As to local directory"); 909 const DownloadTestCase kSaveAsToLocalDir = { 910 SAVE_AS, 911 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 912 "http://example.com/bar.txt", "text/plain", 913 FILE_PATH_LITERAL(""), 914 915 // Response to the 'Save As' is to choose the local path for 'foo-x.txt'. 916 FILE_PATH_LITERAL(""), 917 FILE_PATH_LITERAL("foo-x.txt"), 918 DownloadItem::TARGET_DISPOSITION_PROMPT, 919 920 EXPECT_CRDOWNLOAD 921 }; 922 EXPECT_CALL(*delegate(), PromptUserForDownloadPath( 923 _, test_virtual_dir().AppendASCII("bar.txt"), _)) 924 .WillOnce(WithArg<2>(ScheduleCallback( 925 GetPathInDownloadDir(FILE_PATH_LITERAL("foo-x.txt"))))); 926 RunTestCasesWithActiveItem(&kSaveAsToLocalDir, 1); 927 } 928 929 { 930 SCOPED_TRACE(testing::Message() << "Forced safe download"); 931 const DownloadTestCase kForcedSafe = { 932 FORCED, 933 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 934 "http://example.com/foo.txt", "", 935 FILE_PATH_LITERAL("forced-foo.txt"), 936 937 // Forced paths should be left as-is. 938 FILE_PATH_LITERAL(""), 939 FILE_PATH_LITERAL("forced-foo.txt"), 940 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 941 942 EXPECT_LOCAL_PATH 943 }; 944 RunTestCasesWithActiveItem(&kForcedSafe, 1); 945 } 946 } 947 948 // Test that an inactive download will still get a virtual or local download 949 // path. 950 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_InactiveDownload) { 951 const DownloadTestCase kInactiveTestCases[] = { 952 { 953 AUTOMATIC, 954 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 955 "http://example.com/foo.txt", "text/plain", 956 FILE_PATH_LITERAL(""), 957 958 FILE_PATH_LITERAL("foo.txt"), 959 FILE_PATH_LITERAL(""), 960 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 961 962 EXPECT_LOCAL_PATH 963 }, 964 965 { 966 SAVE_AS, 967 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 968 "http://example.com/foo.txt", "text/plain", 969 FILE_PATH_LITERAL(""), 970 971 FILE_PATH_LITERAL("foo.txt"), 972 FILE_PATH_LITERAL(""), 973 DownloadItem::TARGET_DISPOSITION_PROMPT, 974 975 EXPECT_LOCAL_PATH 976 } 977 }; 978 979 for (size_t i = 0; i < arraysize(kInactiveTestCases); ++i) { 980 SCOPED_TRACE(testing::Message() << "Running test case " << i); 981 const DownloadTestCase& test_case = kInactiveTestCases[i]; 982 scoped_ptr<content::MockDownloadItem> item( 983 CreateActiveDownloadItem(i, test_case)); 984 EXPECT_CALL(*item.get(), GetState()) 985 .WillRepeatedly(Return(content::DownloadItem::CANCELLED)); 986 // Even though one is a SAVE_AS download, no prompt will be displayed to 987 // the user because the download is inactive. 988 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, _, _)) 989 .Times(0); 990 RunTestCase(test_case, base::FilePath(), item.get()); 991 } 992 } 993 994 // If the reserved path could not be verified, then the user should see a 995 // prompt. 996 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ReservationFailed) { 997 const DownloadTestCase kReservationFailedCases[] = { 998 { 999 // 0: Automatic download. Since the reservation fails, the disposition of 1000 // the target is to prompt, but the returned path is used. 1001 AUTOMATIC, 1002 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1003 "http://example.com/foo.txt", "text/plain", 1004 FILE_PATH_LITERAL(""), 1005 1006 FILE_PATH_LITERAL(""), 1007 FILE_PATH_LITERAL("bar.txt"), 1008 DownloadItem::TARGET_DISPOSITION_PROMPT, 1009 1010 EXPECT_CRDOWNLOAD 1011 }, 1012 }; 1013 1014 // Setup ReserveVirtualPath() to fail. 1015 ON_CALL(*delegate(), ReserveVirtualPath(_, _, _, _, _)) 1016 .WillByDefault(WithArg<4>(ScheduleCallback2( 1017 GetPathInDownloadDir(FILE_PATH_LITERAL("bar.txt")), false))); 1018 RunTestCasesWithActiveItem(kReservationFailedCases, 1019 arraysize(kReservationFailedCases)); 1020 } 1021 1022 // If the local path could not be determined, the download should be cancelled. 1023 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_LocalPathFailed) { 1024 const DownloadTestCase kLocalPathFailedCases[] = { 1025 { 1026 // 0: Automatic download. 1027 AUTOMATIC, 1028 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1029 "http://example.com/foo.txt", "text/plain", 1030 FILE_PATH_LITERAL(""), 1031 1032 FILE_PATH_LITERAL(""), 1033 FILE_PATH_LITERAL(""), 1034 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1035 1036 EXPECT_LOCAL_PATH 1037 }, 1038 }; 1039 1040 base::FilePath expected_virtual_path( 1041 GetPathInDownloadDir(FILE_PATH_LITERAL("virtual/foo.txt"))); 1042 // The default download directory is the virtual path. 1043 download_prefs()->SetDownloadPath(test_virtual_dir()); 1044 // Simulate failed call to DetermineLocalPath. 1045 EXPECT_CALL(*delegate(), DetermineLocalPath( 1046 _, GetPathInDownloadDir(FILE_PATH_LITERAL("virtual/foo.txt")), _)) 1047 .WillOnce(WithArg<2>(ScheduleCallback(base::FilePath()))); 1048 RunTestCasesWithActiveItem(kLocalPathFailedCases, 1049 arraysize(kLocalPathFailedCases)); 1050 } 1051 1052 // Downloads that have a danger level of ALLOW_ON_USER_GESTURE should be marked 1053 // as safe depending on whether there was a user gesture associated with the 1054 // download and whether the referrer was visited prior to today. 1055 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_VisitedReferrer) { 1056 const DownloadTestCase kVisitedReferrerCases[] = { 1057 // http://visited.example.com/ is added to the history as a visit that 1058 // happened prior to today. 1059 { 1060 // 0: Safe download due to visiting referrer before. 1061 AUTOMATIC, 1062 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1063 "http://visited.example.com/foo.crx", "application/xml", 1064 FILE_PATH_LITERAL(""), 1065 1066 FILE_PATH_LITERAL(""), 1067 FILE_PATH_LITERAL("foo.crx"), 1068 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1069 1070 EXPECT_CRDOWNLOAD 1071 }, 1072 1073 { 1074 // 1: Dangerous due to not having visited referrer before. 1075 AUTOMATIC, 1076 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, 1077 "http://not-visited.example.com/foo.crx", "application/xml", 1078 FILE_PATH_LITERAL(""), 1079 1080 FILE_PATH_LITERAL(""), 1081 FILE_PATH_LITERAL("foo.crx"), 1082 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1083 1084 EXPECT_UNCONFIRMED 1085 }, 1086 1087 { 1088 // 2: Safe because the user is being prompted. 1089 SAVE_AS, 1090 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1091 "http://not-visited.example.com/foo.crx", "application/xml", 1092 FILE_PATH_LITERAL(""), 1093 1094 FILE_PATH_LITERAL(""), 1095 FILE_PATH_LITERAL("foo.crx"), 1096 DownloadItem::TARGET_DISPOSITION_PROMPT, 1097 1098 EXPECT_CRDOWNLOAD 1099 }, 1100 1101 { 1102 // 3: Safe because of forced path. 1103 FORCED, 1104 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1105 "http://not-visited.example.com/foo.crx", "application/xml", 1106 FILE_PATH_LITERAL("foo.crx"), 1107 1108 FILE_PATH_LITERAL(""), 1109 FILE_PATH_LITERAL("foo.crx"), 1110 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1111 1112 EXPECT_LOCAL_PATH 1113 }, 1114 }; 1115 1116 // This test assumes that the danger level of .crx files is 1117 // ALLOW_ON_USER_GESTURE. 1118 ASSERT_EQ(download_util::ALLOW_ON_USER_GESTURE, 1119 download_util::GetFileDangerLevel( 1120 base::FilePath(FILE_PATH_LITERAL("foo.crx")))); 1121 1122 // First the history service must exist. 1123 ASSERT_TRUE(profile()->CreateHistoryService(false, false)); 1124 1125 GURL url("http://visited.example.com/visited-link.html"); 1126 // The time of visit is picked to be several seconds prior to the most recent 1127 // midnight. 1128 base::Time time_of_visit( 1129 base::Time::Now().LocalMidnight() - base::TimeDelta::FromSeconds(10)); 1130 HistoryService* history_service = 1131 HistoryServiceFactory::GetForProfile(profile(), Profile::EXPLICIT_ACCESS); 1132 ASSERT_TRUE(history_service); 1133 history_service->AddPage(url, time_of_visit, history::SOURCE_BROWSED); 1134 1135 RunTestCasesWithActiveItem(kVisitedReferrerCases, 1136 arraysize(kVisitedReferrerCases)); 1137 } 1138 1139 // These test cases are run with "Prompt for download" user preference set to 1140 // true. 1141 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_PromptAlways) { 1142 const DownloadTestCase kPromptingTestCases[] = { 1143 { 1144 // 0: Safe Automatic - Should prompt because of "Prompt for download" 1145 // preference setting. 1146 AUTOMATIC, 1147 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1148 "http://example.com/foo.txt", "text/plain", 1149 FILE_PATH_LITERAL(""), 1150 1151 FILE_PATH_LITERAL(""), 1152 FILE_PATH_LITERAL("foo.txt"), 1153 DownloadItem::TARGET_DISPOSITION_PROMPT, 1154 1155 EXPECT_CRDOWNLOAD 1156 }, 1157 1158 { 1159 // 1: Safe Forced - Shouldn't prompt. 1160 FORCED, 1161 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1162 "http://example.com/foo.txt", "text/plain", 1163 FILE_PATH_LITERAL("foo.txt"), 1164 1165 FILE_PATH_LITERAL(""), 1166 FILE_PATH_LITERAL("foo.txt"), 1167 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1168 1169 EXPECT_LOCAL_PATH 1170 }, 1171 1172 { 1173 // 2: Automatic - The filename extension is marked as one that we will 1174 // open automatically. Shouldn't prompt. 1175 AUTOMATIC, 1176 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1177 "http://example.com/foo.dummy", "", 1178 FILE_PATH_LITERAL(""), 1179 1180 FILE_PATH_LITERAL(""), 1181 FILE_PATH_LITERAL("foo.dummy"), 1182 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1183 1184 EXPECT_CRDOWNLOAD 1185 }, 1186 }; 1187 1188 SetPromptForDownload(true); 1189 EnableAutoOpenBasedOnExtension( 1190 base::FilePath(FILE_PATH_LITERAL("dummy.dummy"))); 1191 RunTestCasesWithActiveItem(kPromptingTestCases, 1192 arraysize(kPromptingTestCases)); 1193 } 1194 1195 #if !defined(OS_ANDROID) 1196 // These test cases are run with "Prompt for download" user preference set to 1197 // true. Automatic extension downloads shouldn't cause prompting. 1198 // Android doesn't support extensions. 1199 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_PromptAlways_Extension) { 1200 const DownloadTestCase kPromptingTestCases[] = { 1201 { 1202 // 0: Automatic Browser Extension download. - Shouldn't prompt for browser 1203 // extension downloads even if "Prompt for download" preference is set. 1204 AUTOMATIC, 1205 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, 1206 "http://example.com/foo.crx", 1207 extensions::Extension::kMimeType, 1208 FILE_PATH_LITERAL(""), 1209 1210 FILE_PATH_LITERAL(""), 1211 FILE_PATH_LITERAL("foo.crx"), 1212 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1213 1214 EXPECT_UNCONFIRMED 1215 }, 1216 1217 #if defined(OS_WIN) 1218 { 1219 // 1: Automatic User Script - Shouldn't prompt for user script downloads 1220 // even if "Prompt for download" preference is set. ".js" files are 1221 // considered dangerous on Windows. 1222 AUTOMATIC, 1223 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, 1224 "http://example.com/foo.user.js", "", 1225 FILE_PATH_LITERAL(""), 1226 1227 FILE_PATH_LITERAL(""), 1228 FILE_PATH_LITERAL("foo.user.js"), 1229 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1230 1231 EXPECT_UNCONFIRMED 1232 }, 1233 #else 1234 { 1235 // 1: Automatic User Script - Shouldn't prompt for user script downloads 1236 // even if "Prompt for download" preference is set. 1237 AUTOMATIC, 1238 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1239 "http://example.com/foo.user.js", "", 1240 FILE_PATH_LITERAL(""), 1241 1242 FILE_PATH_LITERAL(""), 1243 FILE_PATH_LITERAL("foo.user.js"), 1244 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1245 1246 EXPECT_CRDOWNLOAD 1247 }, 1248 #endif 1249 }; 1250 1251 SetPromptForDownload(true); 1252 RunTestCasesWithActiveItem(kPromptingTestCases, 1253 arraysize(kPromptingTestCases)); 1254 } 1255 #endif 1256 1257 // If the download path is managed, then we don't show any prompts. 1258 // Note that if the download path is managed, then PromptForDownload() is false. 1259 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ManagedPath) { 1260 const DownloadTestCase kManagedPathTestCases[] = { 1261 { 1262 // 0: Automatic Safe 1263 AUTOMATIC, 1264 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1265 "http://example.com/foo.txt", "text/plain", 1266 FILE_PATH_LITERAL(""), 1267 1268 FILE_PATH_LITERAL(""), 1269 FILE_PATH_LITERAL("foo.txt"), 1270 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1271 1272 EXPECT_CRDOWNLOAD 1273 }, 1274 1275 { 1276 // 1: Save_As Safe 1277 SAVE_AS, 1278 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1279 "http://example.com/foo.txt", "text/plain", 1280 FILE_PATH_LITERAL(""), 1281 1282 FILE_PATH_LITERAL(""), 1283 FILE_PATH_LITERAL("foo.txt"), 1284 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1285 1286 EXPECT_CRDOWNLOAD 1287 }, 1288 }; 1289 1290 SetManagedDownloadPath(test_download_dir()); 1291 ASSERT_TRUE(download_prefs()->IsDownloadPathManaged()); 1292 RunTestCasesWithActiveItem(kManagedPathTestCases, 1293 arraysize(kManagedPathTestCases)); 1294 } 1295 1296 // Test basic functionality supporting extensions that want to override download 1297 // filenames. 1298 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_NotifyExtensionsSafe) { 1299 const DownloadTestCase kNotifyExtensionsTestCases[] = { 1300 { 1301 // 0: Automatic Safe 1302 AUTOMATIC, 1303 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1304 "http://example.com/foo.txt", "text/plain", 1305 FILE_PATH_LITERAL(""), 1306 1307 FILE_PATH_LITERAL(""), 1308 FILE_PATH_LITERAL("overridden/foo.txt"), 1309 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1310 1311 EXPECT_CRDOWNLOAD 1312 }, 1313 1314 { 1315 // 1: Save_As Safe 1316 SAVE_AS, 1317 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1318 "http://example.com/foo.txt", "text/plain", 1319 FILE_PATH_LITERAL(""), 1320 1321 FILE_PATH_LITERAL(""), 1322 FILE_PATH_LITERAL("overridden/foo.txt"), 1323 DownloadItem::TARGET_DISPOSITION_PROMPT, 1324 1325 EXPECT_CRDOWNLOAD 1326 }, 1327 1328 { 1329 // 2: Automatic Dangerous 1330 AUTOMATIC, 1331 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, 1332 "http://example.com/foo.crx", "", 1333 FILE_PATH_LITERAL(""), 1334 1335 FILE_PATH_LITERAL(""), 1336 FILE_PATH_LITERAL("overridden/foo.crx"), 1337 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1338 1339 EXPECT_UNCONFIRMED 1340 }, 1341 1342 { 1343 // 3: Forced Safe 1344 FORCED, 1345 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1346 "http://example.com/foo.txt", "", 1347 FILE_PATH_LITERAL("forced-foo.txt"), 1348 1349 FILE_PATH_LITERAL(""), 1350 FILE_PATH_LITERAL("forced-foo.txt"), 1351 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1352 1353 EXPECT_LOCAL_PATH 1354 }, 1355 }; 1356 1357 ON_CALL(*delegate(), NotifyExtensions(_, _, _)) 1358 .WillByDefault(Invoke(&NotifyExtensionsOverridePath)); 1359 RunTestCasesWithActiveItem(kNotifyExtensionsTestCases, 1360 arraysize(kNotifyExtensionsTestCases)); 1361 } 1362 1363 // Test that filenames provided by extensions are passed into SafeBrowsing 1364 // checks and dangerous download checks. 1365 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_NotifyExtensionsUnsafe) { 1366 const DownloadTestCase kNotifyExtensionsTestCases[] = { 1367 { 1368 // 0: Automatic Safe : Later overridden by a dangerous filetype. 1369 AUTOMATIC, 1370 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, 1371 "http://example.com/foo.crx.remove", "text/plain", 1372 FILE_PATH_LITERAL(""), 1373 1374 FILE_PATH_LITERAL(""), 1375 FILE_PATH_LITERAL("overridden/foo.crx"), 1376 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1377 1378 EXPECT_UNCONFIRMED 1379 }, 1380 1381 { 1382 // 1: Automatic Safe : Later overridden by a potentially dangerous 1383 // filetype. 1384 AUTOMATIC, 1385 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, 1386 "http://example.com/foo.exe.remove", "text/plain", 1387 FILE_PATH_LITERAL(""), 1388 1389 FILE_PATH_LITERAL(""), 1390 FILE_PATH_LITERAL("overridden/foo.exe"), 1391 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1392 1393 EXPECT_UNCONFIRMED 1394 }, 1395 }; 1396 1397 ON_CALL(*delegate(), NotifyExtensions(_, _, _)) 1398 .WillByDefault(Invoke(&NotifyExtensionsOverridePath)); 1399 ON_CALL(*delegate(), CheckDownloadUrl(_, _, _)) 1400 .WillByDefault(Invoke(&CheckDownloadUrlCheckExes)); 1401 RunTestCasesWithActiveItem(kNotifyExtensionsTestCases, 1402 arraysize(kNotifyExtensionsTestCases)); 1403 } 1404 1405 // Test that conflict actions set by extensions are passed correctly into 1406 // ReserveVirtualPath. 1407 TEST_F(DownloadTargetDeterminerTest, 1408 TargetDeterminer_NotifyExtensionsConflict) { 1409 const DownloadTestCase kNotifyExtensionsTestCase = { 1410 AUTOMATIC, 1411 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1412 "http://example.com/foo.txt", "text/plain", 1413 FILE_PATH_LITERAL(""), 1414 1415 FILE_PATH_LITERAL(""), 1416 FILE_PATH_LITERAL("overridden/foo.txt"), 1417 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1418 1419 EXPECT_CRDOWNLOAD 1420 }; 1421 1422 const DownloadTestCase& test_case = kNotifyExtensionsTestCase; 1423 scoped_ptr<content::MockDownloadItem> item( 1424 CreateActiveDownloadItem(0, test_case)); 1425 base::FilePath overridden_path(FILE_PATH_LITERAL("overridden/foo.txt")); 1426 base::FilePath full_overridden_path = 1427 GetPathInDownloadDir(overridden_path.value()); 1428 1429 // First case: An extension sets the conflict_action to OVERWRITE. 1430 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _)) 1431 .WillOnce(WithArg<2>( 1432 ScheduleCallback2(overridden_path, 1433 DownloadPathReservationTracker::OVERWRITE))); 1434 EXPECT_CALL(*delegate(), ReserveVirtualPath( 1435 _, full_overridden_path, true, DownloadPathReservationTracker::OVERWRITE, 1436 _)).WillOnce(WithArg<4>( 1437 ScheduleCallback2(full_overridden_path, true))); 1438 1439 RunTestCase(test_case, base::FilePath(), item.get()); 1440 1441 // Second case: An extension sets the conflict_action to PROMPT. 1442 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _)) 1443 .WillOnce(WithArg<2>( 1444 ScheduleCallback2(overridden_path, 1445 DownloadPathReservationTracker::PROMPT))); 1446 EXPECT_CALL(*delegate(), ReserveVirtualPath( 1447 _, full_overridden_path, true, DownloadPathReservationTracker::PROMPT, _)) 1448 .WillOnce(WithArg<4>( 1449 ScheduleCallback2(full_overridden_path, true))); 1450 RunTestCase(test_case, base::FilePath(), item.get()); 1451 } 1452 1453 // Test that relative paths returned by extensions are always relative to the 1454 // default downloads path. 1455 TEST_F(DownloadTargetDeterminerTest, 1456 TargetDeterminer_NotifyExtensionsDefaultPath) { 1457 const DownloadTestCase kNotifyExtensionsTestCase = { 1458 SAVE_AS, 1459 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1460 "http://example.com/foo.txt", "text/plain", 1461 FILE_PATH_LITERAL(""), 1462 1463 FILE_PATH_LITERAL(""), 1464 FILE_PATH_LITERAL("overridden/foo.txt"), 1465 DownloadItem::TARGET_DISPOSITION_PROMPT, 1466 1467 EXPECT_CRDOWNLOAD 1468 }; 1469 1470 const DownloadTestCase& test_case = kNotifyExtensionsTestCase; 1471 scoped_ptr<content::MockDownloadItem> item( 1472 CreateActiveDownloadItem(0, test_case)); 1473 base::FilePath overridden_path(FILE_PATH_LITERAL("overridden/foo.txt")); 1474 base::FilePath full_overridden_path = 1475 GetPathInDownloadDir(overridden_path.value()); 1476 1477 download_prefs()->SetSaveFilePath(GetPathInDownloadDir( 1478 FILE_PATH_LITERAL("last_selected"))); 1479 1480 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _)) 1481 .WillOnce(WithArg<2>( 1482 ScheduleCallback2(overridden_path, 1483 DownloadPathReservationTracker::UNIQUIFY))); 1484 EXPECT_CALL(*delegate(), 1485 PromptUserForDownloadPath(_, full_overridden_path, _)) 1486 .WillOnce(WithArg<2>( 1487 ScheduleCallback(full_overridden_path))); 1488 RunTestCase(test_case, base::FilePath(), item.get()); 1489 } 1490 1491 TEST_F(DownloadTargetDeterminerTest, 1492 TargetDeterminer_InitialVirtualPathUnsafe) { 1493 const base::FilePath::CharType* kInitialPath = 1494 FILE_PATH_LITERAL("some_path/bar.html"); 1495 1496 const DownloadTestCase kInitialPathTestCase = { 1497 // 0: Save As Save. The path generated based on the DownloadItem is safe, 1498 // but the initial path is unsafe. However, the download is not considered 1499 // dangerous since the user has been prompted. 1500 SAVE_AS, 1501 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1502 "http://example.com/foo.txt", "text/plain", 1503 FILE_PATH_LITERAL(""), 1504 1505 FILE_PATH_LITERAL(""), 1506 kInitialPath, 1507 DownloadItem::TARGET_DISPOSITION_PROMPT, 1508 1509 EXPECT_CRDOWNLOAD 1510 }; 1511 1512 const DownloadTestCase& test_case = kInitialPathTestCase; 1513 scoped_ptr<content::MockDownloadItem> item( 1514 CreateActiveDownloadItem(1, test_case)); 1515 EXPECT_CALL(*item, GetLastReason()) 1516 .WillRepeatedly(Return( 1517 content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED)); 1518 EXPECT_CALL(*item, GetTargetDisposition()) 1519 .WillRepeatedly(Return(DownloadItem::TARGET_DISPOSITION_PROMPT)); 1520 RunTestCase(test_case, GetPathInDownloadDir(kInitialPath), item.get()); 1521 } 1522 1523 // Prompting behavior for resumed downloads is based on the last interrupt 1524 // reason. If the reason indicates that the target path may not be suitable for 1525 // the download (ACCESS_DENIED, NO_SPACE, etc..), then the user should be 1526 // prompted, and not otherwise. These test cases shouldn't result in prompting 1527 // since the error is set to NETWORK_FAILED. 1528 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ResumedNoPrompt) { 1529 // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital 1530 // path. 1531 const base::FilePath::CharType* kInitialPath = 1532 FILE_PATH_LITERAL("some_path/bar.txt"); 1533 1534 const DownloadTestCase kResumedTestCases[] = { 1535 { 1536 // 0: Automatic Safe: Initial path is ignored since the user has not been 1537 // prompted before. 1538 AUTOMATIC, 1539 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1540 "http://example.com/foo.txt", "text/plain", 1541 FILE_PATH_LITERAL(""), 1542 1543 FILE_PATH_LITERAL(""), 1544 FILE_PATH_LITERAL("foo.txt"), 1545 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1546 1547 EXPECT_CRDOWNLOAD 1548 }, 1549 1550 { 1551 // 1: Save_As Safe: Initial path used. 1552 SAVE_AS, 1553 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1554 "http://example.com/foo.txt", "text/plain", 1555 FILE_PATH_LITERAL(""), 1556 1557 FILE_PATH_LITERAL(""), 1558 kInitialPath, 1559 DownloadItem::TARGET_DISPOSITION_PROMPT, 1560 1561 EXPECT_CRDOWNLOAD 1562 }, 1563 1564 { 1565 // 2: Automatic Dangerous: Initial path is ignored since the user hasn't 1566 // been prompted before. 1567 AUTOMATIC, 1568 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, 1569 "http://example.com/foo.crx", "", 1570 FILE_PATH_LITERAL(""), 1571 1572 FILE_PATH_LITERAL(""), 1573 FILE_PATH_LITERAL("foo.crx"), 1574 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1575 1576 EXPECT_UNCONFIRMED 1577 }, 1578 1579 { 1580 // 3: Forced Safe: Initial path is ignored due to the forced path. 1581 FORCED, 1582 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1583 "http://example.com/foo.txt", "", 1584 FILE_PATH_LITERAL("forced-foo.txt"), 1585 1586 FILE_PATH_LITERAL(""), 1587 FILE_PATH_LITERAL("forced-foo.txt"), 1588 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1589 1590 EXPECT_LOCAL_PATH 1591 }, 1592 }; 1593 1594 // The test assumes that .crx files have a danger level of 1595 // ALLOW_ON_USER_GESTURE. 1596 ASSERT_EQ(download_util::ALLOW_ON_USER_GESTURE, 1597 download_util::GetFileDangerLevel( 1598 base::FilePath(FILE_PATH_LITERAL("foo.crx")))); 1599 for (size_t i = 0; i < arraysize(kResumedTestCases); ++i) { 1600 SCOPED_TRACE(testing::Message() << "Running test case " << i); 1601 const DownloadTestCase& test_case = kResumedTestCases[i]; 1602 scoped_ptr<content::MockDownloadItem> item( 1603 CreateActiveDownloadItem(i, test_case)); 1604 base::FilePath expected_path = 1605 GetPathInDownloadDir(test_case.expected_local_path); 1606 ON_CALL(*item.get(), GetLastReason()) 1607 .WillByDefault(Return( 1608 content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED)); 1609 // Extensions should be notified if a new path is being generated and there 1610 // is no forced path. In the test cases above, this is true for tests with 1611 // type == AUTOMATIC. 1612 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _)) 1613 .Times(test_case.test_type == AUTOMATIC ? 1 : 0); 1614 EXPECT_CALL(*delegate(), ReserveVirtualPath(_, expected_path, false, _, _)); 1615 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, expected_path, _)) 1616 .Times(0); 1617 EXPECT_CALL(*delegate(), DetermineLocalPath(_, expected_path, _)); 1618 EXPECT_CALL(*delegate(), CheckDownloadUrl(_, expected_path, _)); 1619 RunTestCase(test_case, GetPathInDownloadDir(kInitialPath), item.get()); 1620 } 1621 1622 } 1623 1624 // Test that a forced download doesn't prompt, even if the interrupt reason 1625 // suggests that the target path may not be suitable for downloads. 1626 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ResumedForcedDownload) { 1627 const base::FilePath::CharType* kInitialPath = 1628 FILE_PATH_LITERAL("some_path/bar.txt"); 1629 const DownloadTestCase kResumedForcedDownload = { 1630 // 3: Forced Safe 1631 FORCED, 1632 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1633 "http://example.com/foo.txt", "", 1634 FILE_PATH_LITERAL("forced-foo.txt"), 1635 1636 FILE_PATH_LITERAL(""), 1637 FILE_PATH_LITERAL("forced-foo.txt"), 1638 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1639 1640 EXPECT_LOCAL_PATH 1641 }; 1642 1643 const DownloadTestCase& test_case = kResumedForcedDownload; 1644 base::FilePath expected_path = 1645 GetPathInDownloadDir(test_case.expected_local_path); 1646 scoped_ptr<content::MockDownloadItem> item( 1647 CreateActiveDownloadItem(0, test_case)); 1648 ON_CALL(*item.get(), GetLastReason()) 1649 .WillByDefault(Return(content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE)); 1650 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _)) 1651 .Times(test_case.test_type == AUTOMATIC ? 1 : 0); 1652 EXPECT_CALL(*delegate(), ReserveVirtualPath(_, expected_path, false, _, _)); 1653 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, _, _)) 1654 .Times(0); 1655 EXPECT_CALL(*delegate(), DetermineLocalPath(_, expected_path, _)); 1656 EXPECT_CALL(*delegate(), CheckDownloadUrl(_, expected_path, _)); 1657 RunTestCase(test_case, GetPathInDownloadDir(kInitialPath), item.get()); 1658 } 1659 1660 // Prompting behavior for resumed downloads is based on the last interrupt 1661 // reason. If the reason indicates that the target path may not be suitable for 1662 // the download (ACCESS_DENIED, NO_SPACE, etc..), then the user should be 1663 // prompted, and not otherwise. These test cases result in prompting since the 1664 // error is set to NO_SPACE. 1665 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ResumedWithPrompt) { 1666 // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital 1667 // path. 1668 const base::FilePath::CharType* kInitialPath = 1669 FILE_PATH_LITERAL("some_path/bar.txt"); 1670 1671 const DownloadTestCase kResumedTestCases[] = { 1672 { 1673 // 0: Automatic Safe 1674 AUTOMATIC, 1675 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1676 "http://example.com/foo.txt", "text/plain", 1677 FILE_PATH_LITERAL(""), 1678 1679 FILE_PATH_LITERAL(""), 1680 FILE_PATH_LITERAL("foo.txt"), 1681 DownloadItem::TARGET_DISPOSITION_PROMPT, 1682 1683 EXPECT_CRDOWNLOAD 1684 }, 1685 1686 { 1687 // 1: Save_As Safe 1688 SAVE_AS, 1689 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1690 "http://example.com/foo.txt", "text/plain", 1691 FILE_PATH_LITERAL(""), 1692 1693 FILE_PATH_LITERAL(""), 1694 kInitialPath, 1695 DownloadItem::TARGET_DISPOSITION_PROMPT, 1696 1697 EXPECT_CRDOWNLOAD 1698 }, 1699 1700 { 1701 // 2: Automatic Dangerous 1702 AUTOMATIC, 1703 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1704 "http://example.com/foo.crx", "", 1705 FILE_PATH_LITERAL(""), 1706 1707 FILE_PATH_LITERAL(""), 1708 FILE_PATH_LITERAL("foo.crx"), 1709 DownloadItem::TARGET_DISPOSITION_PROMPT, 1710 1711 EXPECT_CRDOWNLOAD 1712 }, 1713 }; 1714 1715 // The test assumes that .xml files have a danger level of 1716 // ALLOW_ON_USER_GESTURE. 1717 ASSERT_EQ(download_util::ALLOW_ON_USER_GESTURE, 1718 download_util::GetFileDangerLevel( 1719 base::FilePath(FILE_PATH_LITERAL("foo.crx")))); 1720 for (size_t i = 0; i < arraysize(kResumedTestCases); ++i) { 1721 SCOPED_TRACE(testing::Message() << "Running test case " << i); 1722 download_prefs()->SetSaveFilePath(test_download_dir()); 1723 const DownloadTestCase& test_case = kResumedTestCases[i]; 1724 base::FilePath expected_path = 1725 GetPathInDownloadDir(test_case.expected_local_path); 1726 scoped_ptr<content::MockDownloadItem> item( 1727 CreateActiveDownloadItem(i, test_case)); 1728 ON_CALL(*item.get(), GetLastReason()) 1729 .WillByDefault(Return( 1730 content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE)); 1731 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _)) 1732 .Times(test_case.test_type == AUTOMATIC ? 1 : 0); 1733 EXPECT_CALL(*delegate(), ReserveVirtualPath(_, expected_path, false, _, _)); 1734 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, expected_path, _)); 1735 EXPECT_CALL(*delegate(), DetermineLocalPath(_, expected_path, _)); 1736 EXPECT_CALL(*delegate(), CheckDownloadUrl(_, expected_path, _)); 1737 RunTestCase(test_case, GetPathInDownloadDir(kInitialPath), item.get()); 1738 } 1739 } 1740 1741 // Test intermediate filename generation for resumed downloads. 1742 TEST_F(DownloadTargetDeterminerTest, 1743 TargetDeterminer_IntermediateNameForResumed) { 1744 // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital 1745 // path. 1746 const base::FilePath::CharType kInitialPath[] = 1747 FILE_PATH_LITERAL("some_path/bar.txt"); 1748 1749 struct IntermediateNameTestCase { 1750 // General test case settings. 1751 DownloadTestCase general; 1752 1753 // Value of DownloadItem::GetFullPath() during test run, relative 1754 // to test download path. 1755 const base::FilePath::CharType* initial_intermediate_path; 1756 1757 // Expected intermediate path relatvie to the test download path. An exact 1758 // match is performed if this string is non-empty. Ignored otherwise. 1759 const base::FilePath::CharType* expected_intermediate_path; 1760 } kIntermediateNameTestCases[] = { 1761 { 1762 { 1763 // 0: Automatic Safe 1764 AUTOMATIC, 1765 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1766 "http://example.com/foo.txt", "text/plain", 1767 FILE_PATH_LITERAL(""), 1768 1769 FILE_PATH_LITERAL(""), 1770 FILE_PATH_LITERAL("foo.txt"), 1771 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1772 1773 EXPECT_CRDOWNLOAD 1774 }, 1775 FILE_PATH_LITERAL("bar.txt.crdownload"), 1776 FILE_PATH_LITERAL("foo.txt.crdownload") 1777 }, 1778 1779 { 1780 { 1781 // 1: Save_As Safe 1782 SAVE_AS, 1783 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1784 "http://example.com/foo.txt", "text/plain", 1785 FILE_PATH_LITERAL(""), 1786 1787 FILE_PATH_LITERAL(""), 1788 kInitialPath, 1789 DownloadItem::TARGET_DISPOSITION_PROMPT, 1790 1791 EXPECT_CRDOWNLOAD 1792 }, 1793 FILE_PATH_LITERAL("foo.txt.crdownload"), 1794 FILE_PATH_LITERAL("some_path/bar.txt.crdownload") 1795 }, 1796 1797 { 1798 { 1799 // 2: Automatic Dangerous 1800 AUTOMATIC, 1801 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, 1802 "http://example.com/foo.crx", "", 1803 FILE_PATH_LITERAL(""), 1804 1805 FILE_PATH_LITERAL(""), 1806 FILE_PATH_LITERAL("foo.crx"), 1807 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1808 1809 EXPECT_UNCONFIRMED 1810 }, 1811 FILE_PATH_LITERAL("Unconfirmed abcd.crdownload"), 1812 FILE_PATH_LITERAL("Unconfirmed abcd.crdownload") 1813 }, 1814 1815 { 1816 { 1817 // 3: Automatic Dangerous 1818 AUTOMATIC, 1819 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, 1820 "http://example.com/foo.crx", "", 1821 FILE_PATH_LITERAL(""), 1822 1823 FILE_PATH_LITERAL(""), 1824 FILE_PATH_LITERAL("foo.crx"), 1825 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1826 1827 EXPECT_UNCONFIRMED 1828 }, 1829 FILE_PATH_LITERAL("other_path/Unconfirmed abcd.crdownload"), 1830 // Rely on the EXPECT_UNCONFIRMED check in the general test settings. A 1831 // new intermediate path of the form "Unconfirmed <number>.crdownload" 1832 // should be generated for this case since the initial intermediate path 1833 // is in the wrong directory. 1834 FILE_PATH_LITERAL("") 1835 }, 1836 1837 { 1838 { 1839 // 3: Forced Safe: Initial path is ignored due to the forced path. 1840 FORCED, 1841 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1842 "http://example.com/foo.txt", "", 1843 FILE_PATH_LITERAL("forced-foo.txt"), 1844 1845 FILE_PATH_LITERAL(""), 1846 FILE_PATH_LITERAL("forced-foo.txt"), 1847 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1848 1849 EXPECT_LOCAL_PATH 1850 }, 1851 FILE_PATH_LITERAL("forced-foo.txt"), 1852 FILE_PATH_LITERAL("forced-foo.txt") 1853 }, 1854 }; 1855 1856 // The test assumes that .crx files have a danger level of 1857 // ALLOW_ON_USER_GESTURE. 1858 ASSERT_EQ(download_util::ALLOW_ON_USER_GESTURE, 1859 download_util::GetFileDangerLevel( 1860 base::FilePath(FILE_PATH_LITERAL("foo.crx")))); 1861 1862 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kIntermediateNameTestCases); ++i) { 1863 SCOPED_TRACE(testing::Message() << "Running test case " << i); 1864 const IntermediateNameTestCase& test_case = kIntermediateNameTestCases[i]; 1865 scoped_ptr<content::MockDownloadItem> item( 1866 CreateActiveDownloadItem(i, test_case.general)); 1867 1868 ON_CALL(*item.get(), GetLastReason()) 1869 .WillByDefault(Return( 1870 content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED)); 1871 ON_CALL(*item.get(), GetFullPath()) 1872 .WillByDefault(ReturnRefOfCopy( 1873 GetPathInDownloadDir(test_case.initial_intermediate_path))); 1874 ON_CALL(*item.get(), GetDangerType()) 1875 .WillByDefault(Return(test_case.general.expected_danger_type)); 1876 1877 scoped_ptr<DownloadTargetInfo> target_info = 1878 RunDownloadTargetDeterminer(GetPathInDownloadDir(kInitialPath), 1879 item.get()); 1880 VerifyDownloadTarget(test_case.general, target_info.get()); 1881 base::FilePath expected_intermediate_path = 1882 GetPathInDownloadDir(test_case.expected_intermediate_path); 1883 if (!expected_intermediate_path.empty()) 1884 EXPECT_EQ(expected_intermediate_path, target_info->intermediate_path); 1885 } 1886 } 1887 1888 // Test MIME type determination based on the target filename. 1889 TEST_F(DownloadTargetDeterminerTest, 1890 TargetDeterminer_MIMETypeDetermination) { 1891 // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital 1892 // path. 1893 const base::FilePath::CharType kInitialPath[] = 1894 FILE_PATH_LITERAL("some_path/bar.txt"); 1895 1896 struct MIMETypeTestCase { 1897 // General test case settings. 1898 DownloadTestCase general; 1899 1900 // Expected MIME type for test case. 1901 const char* expected_mime_type; 1902 } kMIMETypeTestCases[] = { 1903 { 1904 { 1905 // 0: 1906 AUTOMATIC, 1907 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1908 "http://example.com/foo.png", "image/png", 1909 FILE_PATH_LITERAL(""), 1910 1911 FILE_PATH_LITERAL(""), 1912 FILE_PATH_LITERAL("foo.png"), 1913 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1914 1915 EXPECT_CRDOWNLOAD 1916 }, 1917 "image/png" 1918 }, 1919 { 1920 { 1921 // 1: Empty MIME type in response. 1922 AUTOMATIC, 1923 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1924 "http://example.com/foo.png", "", 1925 FILE_PATH_LITERAL(""), 1926 1927 FILE_PATH_LITERAL(""), 1928 FILE_PATH_LITERAL("foo.png"), 1929 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1930 1931 EXPECT_CRDOWNLOAD 1932 }, 1933 "image/png" 1934 }, 1935 { 1936 { 1937 // 2: Forced path. 1938 FORCED, 1939 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1940 "http://example.com/foo.abc", "", 1941 FILE_PATH_LITERAL("foo.png"), 1942 1943 FILE_PATH_LITERAL(""), 1944 FILE_PATH_LITERAL("foo.png"), 1945 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1946 1947 EXPECT_CRDOWNLOAD 1948 }, 1949 "image/png" 1950 }, 1951 { 1952 { 1953 // 3: Unknown file type. 1954 AUTOMATIC, 1955 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1956 "http://example.com/foo.notarealext", "", 1957 FILE_PATH_LITERAL(""), 1958 1959 FILE_PATH_LITERAL(""), 1960 FILE_PATH_LITERAL("foo.notarealext"), 1961 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1962 1963 EXPECT_CRDOWNLOAD 1964 }, 1965 "" 1966 }, 1967 { 1968 { 1969 // 4: Unknown file type. 1970 AUTOMATIC, 1971 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 1972 "http://example.com/foo.notarealext", "image/png", 1973 FILE_PATH_LITERAL(""), 1974 1975 FILE_PATH_LITERAL(""), 1976 FILE_PATH_LITERAL("foo.notarealext"), 1977 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 1978 1979 EXPECT_CRDOWNLOAD 1980 }, 1981 "" 1982 }, 1983 }; 1984 1985 ON_CALL(*delegate(), GetFileMimeType( 1986 GetPathInDownloadDir(FILE_PATH_LITERAL("foo.png")), _)) 1987 .WillByDefault(WithArg<1>( 1988 ScheduleCallback("image/png"))); 1989 1990 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kMIMETypeTestCases); ++i) { 1991 SCOPED_TRACE(testing::Message() << "Running test case " << i); 1992 const MIMETypeTestCase& test_case = kMIMETypeTestCases[i]; 1993 scoped_ptr<content::MockDownloadItem> item( 1994 CreateActiveDownloadItem(i, test_case.general)); 1995 scoped_ptr<DownloadTargetInfo> target_info = 1996 RunDownloadTargetDeterminer(GetPathInDownloadDir(kInitialPath), 1997 item.get()); 1998 EXPECT_EQ(test_case.expected_mime_type, target_info->mime_type); 1999 } 2000 } 2001 2002 #if defined(ENABLE_PLUGINS) 2003 2004 void DummyGetPluginsCallback( 2005 const base::Closure& closure, 2006 const std::vector<content::WebPluginInfo>& plugins) { 2007 closure.Run(); 2008 } 2009 2010 void ForceRefreshOfPlugins() { 2011 #if !defined(OS_WIN) 2012 // Prevent creation of a utility process for loading plugins. Doing so breaks 2013 // unit_tests since /proc/self/exe can't be run as a utility process. 2014 content::RenderProcessHost::SetRunRendererInProcess(true); 2015 #endif 2016 base::RunLoop run_loop; 2017 content::PluginService::GetInstance()->GetPlugins( 2018 base::Bind(&DummyGetPluginsCallback, run_loop.QuitClosure())); 2019 run_loop.Run(); 2020 #if !defined(OS_WIN) 2021 content::RenderProcessHost::SetRunRendererInProcess(false); 2022 #endif 2023 } 2024 2025 void PluginEnabledCallback(const base::Closure& closure, 2026 bool result) { 2027 EXPECT_TRUE(result); 2028 closure.Run(); 2029 } 2030 2031 void EnablePlugin(bool enable, PluginPrefs* prefs, const base::FilePath& path) { 2032 base::RunLoop run_loop; 2033 prefs->EnablePlugin(enable, path, 2034 base::Bind(&PluginEnabledCallback, 2035 run_loop.QuitClosure())); 2036 run_loop.Run(); 2037 } 2038 2039 class ScopedRegisterInternalPlugin { 2040 public: 2041 ScopedRegisterInternalPlugin(content::PluginService* plugin_service, 2042 content::WebPluginInfo::PluginType type, 2043 const base::FilePath& path, 2044 const char* mime_type, 2045 const char* extension) 2046 : plugin_service_(plugin_service), 2047 plugin_path_(path) { 2048 content::WebPluginMimeType plugin_mime_type(mime_type, 2049 extension, 2050 "Test file"); 2051 content::WebPluginInfo plugin_info(base::string16(), 2052 path, 2053 base::string16(), 2054 base::string16()); 2055 plugin_info.mime_types.push_back(plugin_mime_type); 2056 plugin_info.type = type; 2057 2058 plugin_service->RegisterInternalPlugin(plugin_info, true); 2059 plugin_service->RefreshPlugins(); 2060 ForceRefreshOfPlugins(); 2061 } 2062 2063 ~ScopedRegisterInternalPlugin() { 2064 plugin_service_->UnregisterInternalPlugin(plugin_path_); 2065 plugin_service_->RefreshPlugins(); 2066 ForceRefreshOfPlugins(); 2067 } 2068 2069 const base::FilePath& path() { return plugin_path_; } 2070 2071 private: 2072 content::PluginService* plugin_service_; 2073 base::FilePath plugin_path_; 2074 }; 2075 2076 // We use a slightly different test fixture for tests that touch plugins. SetUp 2077 // needs to disable plugin discovery and we need to use a 2078 // ShadowingAtExitManager to discard the tainted PluginService. Unfortunately, 2079 // PluginService carries global state. 2080 class DownloadTargetDeterminerTestWithPlugin : 2081 public DownloadTargetDeterminerTest { 2082 public: 2083 virtual void SetUp() OVERRIDE { 2084 content::PluginService::GetInstance()->Init(); 2085 content::PluginService::GetInstance()->DisablePluginsDiscoveryForTesting(); 2086 DownloadTargetDeterminerTest::SetUp(); 2087 } 2088 2089 protected: 2090 // The ShadowingAtExitManager destroys the tainted PluginService instance. 2091 base::ShadowingAtExitManager at_exit_manager_; 2092 }; 2093 2094 // Check if secure handling of filetypes is determined correctly for PPAPI 2095 // plugins. 2096 TEST_F(DownloadTargetDeterminerTestWithPlugin, 2097 TargetDeterminer_CheckForSecureHandling_PPAPI) { 2098 // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital 2099 // path. 2100 const base::FilePath::CharType kInitialPath[] = 2101 FILE_PATH_LITERAL("some_path/bar.txt"); 2102 const char kTestMIMEType[] = "application/x-example-should-not-exist"; 2103 2104 DownloadTestCase kSecureHandlingTestCase = { 2105 AUTOMATIC, 2106 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 2107 "http://example.com/foo.fakeext", "", 2108 FILE_PATH_LITERAL(""), 2109 2110 FILE_PATH_LITERAL(""), 2111 FILE_PATH_LITERAL("foo.fakeext"), 2112 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 2113 2114 EXPECT_CRDOWNLOAD 2115 }; 2116 2117 content::PluginService* plugin_service = 2118 content::PluginService::GetInstance(); 2119 // This creates a PluginPrefs for our TestingProfile. 2120 scoped_refptr<PluginPrefs> plugin_prefs = 2121 PluginPrefs::GetForTestingProfile(profile()); 2122 2123 // Verify our test assumptions. 2124 { 2125 ForceRefreshOfPlugins(); 2126 std::vector<content::WebPluginInfo> info; 2127 ASSERT_FALSE(plugin_service->GetPluginInfoArray( 2128 GURL(), kTestMIMEType, false, &info, NULL)); 2129 ASSERT_EQ(0u, info.size()) 2130 << "Name: " << info[0].name << ", Path: " << info[0].path.value(); 2131 } 2132 2133 ON_CALL(*delegate(), GetFileMimeType( 2134 GetPathInDownloadDir(FILE_PATH_LITERAL("foo.fakeext")), _)) 2135 .WillByDefault(WithArg<1>( 2136 ScheduleCallback(kTestMIMEType))); 2137 scoped_ptr<content::MockDownloadItem> item( 2138 CreateActiveDownloadItem(1, kSecureHandlingTestCase)); 2139 scoped_ptr<DownloadTargetInfo> target_info = 2140 RunDownloadTargetDeterminer(GetPathInDownloadDir(kInitialPath), 2141 item.get()); 2142 EXPECT_FALSE(target_info->is_filetype_handled_securely); 2143 2144 // Register a PPAPI plugin. This should count as handling the filetype 2145 // securely. 2146 ScopedRegisterInternalPlugin ppapi_plugin( 2147 plugin_service, 2148 content::WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS, 2149 test_download_dir().AppendASCII("ppapi"), 2150 kTestMIMEType, 2151 "fakeext"); 2152 2153 target_info = RunDownloadTargetDeterminer( 2154 GetPathInDownloadDir(kInitialPath), item.get()); 2155 EXPECT_TRUE(target_info->is_filetype_handled_securely); 2156 2157 // Try disabling the plugin. Handling should no longer be considered secure. 2158 EnablePlugin(false, plugin_prefs, ppapi_plugin.path()); 2159 target_info = RunDownloadTargetDeterminer( 2160 GetPathInDownloadDir(kInitialPath), item.get()); 2161 EXPECT_FALSE(target_info->is_filetype_handled_securely); 2162 2163 // Now register an unsandboxed PPAPI plug-in. This plugin should not be 2164 // considered secure. 2165 ScopedRegisterInternalPlugin ppapi_unsandboxed_plugin( 2166 plugin_service, 2167 content::WebPluginInfo::PLUGIN_TYPE_PEPPER_UNSANDBOXED, 2168 test_download_dir().AppendASCII("ppapi-nosandbox"), 2169 kTestMIMEType, 2170 "fakeext"); 2171 2172 target_info = RunDownloadTargetDeterminer( 2173 GetPathInDownloadDir(kInitialPath), item.get()); 2174 EXPECT_FALSE(target_info->is_filetype_handled_securely); 2175 } 2176 2177 // Check if secure handling of filetypes is determined correctly for NPAPI 2178 // plugins. 2179 TEST_F(DownloadTargetDeterminerTestWithPlugin, 2180 TargetDeterminer_CheckForSecureHandling_NPAPI) { 2181 // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital 2182 // path. 2183 const base::FilePath::CharType kInitialPath[] = 2184 FILE_PATH_LITERAL("some_path/bar.txt"); 2185 const char kTestMIMEType[] = "application/x-example-should-not-exist"; 2186 2187 DownloadTestCase kSecureHandlingTestCase = { 2188 AUTOMATIC, 2189 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 2190 "http://example.com/foo.fakeext", "", 2191 FILE_PATH_LITERAL(""), 2192 2193 FILE_PATH_LITERAL(""), 2194 FILE_PATH_LITERAL("foo.fakeext"), 2195 DownloadItem::TARGET_DISPOSITION_OVERWRITE, 2196 2197 EXPECT_CRDOWNLOAD 2198 }; 2199 2200 content::PluginService* plugin_service = 2201 content::PluginService::GetInstance(); 2202 2203 // Can't run this test if NPAPI isn't supported. 2204 if (!plugin_service->NPAPIPluginsSupported()) 2205 return; 2206 2207 // This creates a PluginPrefs for our TestingProfile. 2208 scoped_refptr<PluginPrefs> plugin_prefs = 2209 PluginPrefs::GetForTestingProfile(profile()); 2210 2211 // Verify our test assumptions. 2212 { 2213 ForceRefreshOfPlugins(); 2214 std::vector<content::WebPluginInfo> info; 2215 ASSERT_FALSE(plugin_service->GetPluginInfoArray( 2216 GURL(), kTestMIMEType, false, &info, NULL)); 2217 ASSERT_EQ(0u, info.size()) 2218 << "Name: " << info[0].name << ", Path: " << info[0].path.value(); 2219 } 2220 2221 ON_CALL(*delegate(), GetFileMimeType( 2222 GetPathInDownloadDir(FILE_PATH_LITERAL("foo.fakeext")), _)) 2223 .WillByDefault(WithArg<1>( 2224 ScheduleCallback(kTestMIMEType))); 2225 scoped_ptr<content::MockDownloadItem> item( 2226 CreateActiveDownloadItem(1, kSecureHandlingTestCase)); 2227 scoped_ptr<DownloadTargetInfo> target_info = 2228 RunDownloadTargetDeterminer(GetPathInDownloadDir(kInitialPath), 2229 item.get()); 2230 EXPECT_FALSE(target_info->is_filetype_handled_securely); 2231 2232 // Register a NPAPI plugin. This should not count as handling the filetype 2233 // securely. 2234 ScopedRegisterInternalPlugin npapi_plugin( 2235 plugin_service, 2236 content::WebPluginInfo::PLUGIN_TYPE_NPAPI, 2237 test_download_dir().AppendASCII("npapi"), 2238 kTestMIMEType, 2239 "fakeext"); 2240 2241 target_info = RunDownloadTargetDeterminer( 2242 GetPathInDownloadDir(kInitialPath), item.get()); 2243 EXPECT_FALSE(target_info->is_filetype_handled_securely); 2244 } 2245 #endif // ENABLE_PLUGINS 2246 2247 } // namespace 2248