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 <set> 6 #include <string> 7 8 #include "base/bind.h" 9 #include "base/files/scoped_temp_dir.h" 10 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/weak_ptr.h" 12 #include "base/message_loop/message_loop.h" 13 #include "base/stl_util.h" 14 #include "base/strings/string16.h" 15 #include "base/strings/string_util.h" 16 #include "base/strings/utf_string_conversions.h" 17 #include "build/build_config.h" 18 #include "content/browser/byte_stream.h" 19 #include "content/browser/download/download_create_info.h" 20 #include "content/browser/download/download_file_factory.h" 21 #include "content/browser/download/download_item_factory.h" 22 #include "content/browser/download/download_item_impl.h" 23 #include "content/browser/download/download_item_impl_delegate.h" 24 #include "content/browser/download/download_manager_impl.h" 25 #include "content/browser/download/download_request_handle.h" 26 #include "content/browser/download/mock_download_file.h" 27 #include "content/public/browser/browser_context.h" 28 #include "content/public/browser/download_interrupt_reasons.h" 29 #include "content/public/browser/download_item.h" 30 #include "content/public/browser/download_manager_delegate.h" 31 #include "content/public/test/mock_download_item.h" 32 #include "content/public/test/test_browser_context.h" 33 #include "content/public/test/test_browser_thread.h" 34 #include "net/base/net_log.h" 35 #include "net/base/net_util.h" 36 #include "testing/gmock/include/gmock/gmock.h" 37 #include "testing/gmock_mutant.h" 38 #include "testing/gtest/include/gtest/gtest.h" 39 40 using ::testing::AllOf; 41 using ::testing::DoAll; 42 using ::testing::Eq; 43 using ::testing::Ref; 44 using ::testing::Return; 45 using ::testing::ReturnRef; 46 using ::testing::SetArgPointee; 47 using ::testing::StrictMock; 48 using ::testing::_; 49 50 ACTION_TEMPLATE(RunCallback, 51 HAS_1_TEMPLATE_PARAMS(int, k), 52 AND_1_VALUE_PARAMS(p0)) { 53 return ::std::tr1::get<k>(args).Run(p0); 54 } 55 56 namespace content { 57 class ByteStreamReader; 58 59 namespace { 60 61 // Matches a DownloadCreateInfo* that points to the same object as |info| and 62 // has a |default_download_directory| that matches |download_directory|. 63 MATCHER_P2(DownloadCreateInfoWithDefaultPath, info, download_directory, "") { 64 return arg == info && 65 arg->default_download_directory == download_directory; 66 } 67 68 class MockDownloadItemImpl : public DownloadItemImpl { 69 public: 70 // Use history constructor for minimal base object. 71 explicit MockDownloadItemImpl(DownloadItemImplDelegate* delegate) 72 : DownloadItemImpl( 73 delegate, 74 content::DownloadItem::kInvalidId, 75 base::FilePath(), 76 base::FilePath(), 77 std::vector<GURL>(), 78 GURL(), 79 "application/octet-stream", 80 "application/octet-stream", 81 base::Time(), 82 base::Time(), 83 std::string(), 84 std::string(), 85 0, 86 0, 87 DownloadItem::COMPLETE, 88 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, 89 DOWNLOAD_INTERRUPT_REASON_NONE, 90 false, 91 net::BoundNetLog()) {} 92 virtual ~MockDownloadItemImpl() {} 93 94 MOCK_METHOD4(OnDownloadTargetDetermined, 95 void(const base::FilePath&, TargetDisposition, 96 DownloadDangerType, const base::FilePath&)); 97 MOCK_METHOD1(AddObserver, void(DownloadItem::Observer*)); 98 MOCK_METHOD1(RemoveObserver, void(DownloadItem::Observer*)); 99 MOCK_METHOD0(UpdateObservers, void()); 100 MOCK_METHOD0(CanShowInFolder, bool()); 101 MOCK_METHOD0(CanOpenDownload, bool()); 102 MOCK_METHOD0(ShouldOpenFileBasedOnExtension, bool()); 103 MOCK_METHOD0(OpenDownload, void()); 104 MOCK_METHOD0(ShowDownloadInShell, void()); 105 MOCK_METHOD0(ValidateDangerousDownload, void()); 106 MOCK_METHOD1(StealDangerousDownload, void(const AcquireFileCallback&)); 107 MOCK_METHOD3(UpdateProgress, void(int64, int64, const std::string&)); 108 MOCK_METHOD1(Cancel, void(bool)); 109 MOCK_METHOD0(MarkAsComplete, void()); 110 MOCK_METHOD1(OnAllDataSaved, void(const std::string&)); 111 MOCK_METHOD0(OnDownloadedFileRemoved, void()); 112 virtual void Start( 113 scoped_ptr<DownloadFile> download_file, 114 scoped_ptr<DownloadRequestHandleInterface> req_handle) OVERRIDE { 115 MockStart(download_file.get(), req_handle.get()); 116 } 117 118 MOCK_METHOD2(MockStart, void(DownloadFile*, DownloadRequestHandleInterface*)); 119 120 MOCK_METHOD0(Remove, void()); 121 MOCK_CONST_METHOD1(TimeRemaining, bool(base::TimeDelta*)); 122 MOCK_CONST_METHOD0(CurrentSpeed, int64()); 123 MOCK_CONST_METHOD0(PercentComplete, int()); 124 MOCK_CONST_METHOD0(AllDataSaved, bool()); 125 MOCK_CONST_METHOD1(MatchesQuery, bool(const base::string16& query)); 126 MOCK_CONST_METHOD0(IsDone, bool()); 127 MOCK_CONST_METHOD0(GetFullPath, const base::FilePath&()); 128 MOCK_CONST_METHOD0(GetTargetFilePath, const base::FilePath&()); 129 MOCK_CONST_METHOD0(GetTargetDisposition, TargetDisposition()); 130 MOCK_METHOD1(OnContentCheckCompleted, void(DownloadDangerType)); 131 MOCK_CONST_METHOD0(GetState, DownloadState()); 132 MOCK_CONST_METHOD0(GetUrlChain, const std::vector<GURL>&()); 133 MOCK_METHOD1(SetTotalBytes, void(int64)); 134 MOCK_CONST_METHOD0(GetURL, const GURL&()); 135 MOCK_CONST_METHOD0(GetOriginalUrl, const GURL&()); 136 MOCK_CONST_METHOD0(GetReferrerUrl, const GURL&()); 137 MOCK_CONST_METHOD0(GetTabUrl, const GURL&()); 138 MOCK_CONST_METHOD0(GetTabReferrerUrl, const GURL&()); 139 MOCK_CONST_METHOD0(GetSuggestedFilename, std::string()); 140 MOCK_CONST_METHOD0(GetContentDisposition, std::string()); 141 MOCK_CONST_METHOD0(GetMimeType, std::string()); 142 MOCK_CONST_METHOD0(GetOriginalMimeType, std::string()); 143 MOCK_CONST_METHOD0(GetReferrerCharset, std::string()); 144 MOCK_CONST_METHOD0(GetRemoteAddress, std::string()); 145 MOCK_CONST_METHOD0(GetTotalBytes, int64()); 146 MOCK_CONST_METHOD0(GetReceivedBytes, int64()); 147 MOCK_CONST_METHOD0(GetHashState, const std::string&()); 148 MOCK_CONST_METHOD0(GetHash, const std::string&()); 149 MOCK_CONST_METHOD0(GetId, uint32()); 150 MOCK_CONST_METHOD0(GetStartTime, base::Time()); 151 MOCK_CONST_METHOD0(GetEndTime, base::Time()); 152 MOCK_METHOD0(GetDownloadManager, DownloadManager*()); 153 MOCK_CONST_METHOD0(IsPaused, bool()); 154 MOCK_CONST_METHOD0(GetOpenWhenComplete, bool()); 155 MOCK_METHOD1(SetOpenWhenComplete, void(bool)); 156 MOCK_CONST_METHOD0(GetFileExternallyRemoved, bool()); 157 MOCK_CONST_METHOD0(GetDangerType, DownloadDangerType()); 158 MOCK_CONST_METHOD0(IsDangerous, bool()); 159 MOCK_METHOD0(GetAutoOpened, bool()); 160 MOCK_CONST_METHOD0(GetForcedFilePath, const base::FilePath&()); 161 MOCK_CONST_METHOD0(HasUserGesture, bool()); 162 MOCK_CONST_METHOD0(GetTransitionType, ui::PageTransition()); 163 MOCK_CONST_METHOD0(IsTemporary, bool()); 164 MOCK_METHOD1(SetIsTemporary, void(bool)); 165 MOCK_METHOD1(SetOpened, void(bool)); 166 MOCK_CONST_METHOD0(GetOpened, bool()); 167 MOCK_CONST_METHOD0(GetLastModifiedTime, const std::string&()); 168 MOCK_CONST_METHOD0(GetETag, const std::string&()); 169 MOCK_CONST_METHOD0(GetLastReason, DownloadInterruptReason()); 170 MOCK_CONST_METHOD0(GetBrowserContext, BrowserContext*()); 171 MOCK_CONST_METHOD0(GetWebContents, WebContents*()); 172 MOCK_CONST_METHOD0(GetFileNameToReportUser, base::FilePath()); 173 MOCK_METHOD1(SetDisplayName, void(const base::FilePath&)); 174 MOCK_METHOD0(NotifyRemoved, void()); 175 // May be called when vlog is on. 176 virtual std::string DebugString(bool verbose) const OVERRIDE { 177 return std::string(); 178 } 179 }; 180 181 class MockDownloadManagerDelegate : public DownloadManagerDelegate { 182 public: 183 MockDownloadManagerDelegate(); 184 virtual ~MockDownloadManagerDelegate(); 185 186 MOCK_METHOD0(Shutdown, void()); 187 MOCK_METHOD1(GetNextId, void(const DownloadIdCallback&)); 188 MOCK_METHOD2(DetermineDownloadTarget, 189 bool(DownloadItem* item, 190 const DownloadTargetCallback&)); 191 MOCK_METHOD1(ShouldOpenFileBasedOnExtension, bool(const base::FilePath&)); 192 MOCK_METHOD2(ShouldCompleteDownload, 193 bool(DownloadItem*, const base::Closure&)); 194 MOCK_METHOD2(ShouldOpenDownload, 195 bool(DownloadItem*, const DownloadOpenDelayedCallback&)); 196 MOCK_METHOD0(GenerateFileHash, bool()); 197 MOCK_METHOD4(GetSaveDir, void(BrowserContext*, 198 base::FilePath*, base::FilePath*, bool*)); 199 MOCK_METHOD5(ChooseSavePath, void( 200 WebContents*, const base::FilePath&, const base::FilePath::StringType&, 201 bool, const SavePackagePathPickedCallback&)); 202 MOCK_CONST_METHOD0(ApplicationClientIdForFileScanning, std::string()); 203 }; 204 205 MockDownloadManagerDelegate::MockDownloadManagerDelegate() {} 206 207 MockDownloadManagerDelegate::~MockDownloadManagerDelegate() {} 208 209 class MockDownloadItemFactory 210 : public DownloadItemFactory, 211 public base::SupportsWeakPtr<MockDownloadItemFactory> { 212 public: 213 MockDownloadItemFactory(); 214 virtual ~MockDownloadItemFactory(); 215 216 // Access to map of created items. 217 // TODO(rdsmith): Could add type (save page, persisted, etc.) 218 // functionality if it's ever needed by consumers. 219 220 // Returns NULL if no item of that id is present. 221 MockDownloadItemImpl* GetItem(int id); 222 223 // Remove and return an item made by the factory. 224 // Generally used during teardown. 225 MockDownloadItemImpl* PopItem(); 226 227 // Should be called when the item of this id is removed so that 228 // we don't keep dangling pointers. 229 void RemoveItem(int id); 230 231 // Overridden methods from DownloadItemFactory. 232 virtual DownloadItemImpl* CreatePersistedItem( 233 DownloadItemImplDelegate* delegate, 234 uint32 download_id, 235 const base::FilePath& current_path, 236 const base::FilePath& target_path, 237 const std::vector<GURL>& url_chain, 238 const GURL& referrer_url, 239 const std::string& mime_type, 240 const std::string& original_mime_type, 241 const base::Time& start_time, 242 const base::Time& end_time, 243 const std::string& etag, 244 const std::string& last_modofied, 245 int64 received_bytes, 246 int64 total_bytes, 247 DownloadItem::DownloadState state, 248 DownloadDangerType danger_type, 249 DownloadInterruptReason interrupt_reason, 250 bool opened, 251 const net::BoundNetLog& bound_net_log) OVERRIDE; 252 virtual DownloadItemImpl* CreateActiveItem( 253 DownloadItemImplDelegate* delegate, 254 uint32 download_id, 255 const DownloadCreateInfo& info, 256 const net::BoundNetLog& bound_net_log) OVERRIDE; 257 virtual DownloadItemImpl* CreateSavePageItem( 258 DownloadItemImplDelegate* delegate, 259 uint32 download_id, 260 const base::FilePath& path, 261 const GURL& url, 262 const std::string& mime_type, 263 scoped_ptr<DownloadRequestHandleInterface> request_handle, 264 const net::BoundNetLog& bound_net_log) OVERRIDE; 265 266 private: 267 std::map<uint32, MockDownloadItemImpl*> items_; 268 DownloadItemImplDelegate item_delegate_; 269 270 DISALLOW_COPY_AND_ASSIGN(MockDownloadItemFactory); 271 }; 272 273 MockDownloadItemFactory::MockDownloadItemFactory() {} 274 275 MockDownloadItemFactory::~MockDownloadItemFactory() {} 276 277 MockDownloadItemImpl* MockDownloadItemFactory::GetItem(int id) { 278 if (items_.find(id) == items_.end()) 279 return NULL; 280 return items_[id]; 281 } 282 283 MockDownloadItemImpl* MockDownloadItemFactory::PopItem() { 284 if (items_.empty()) 285 return NULL; 286 287 std::map<uint32, MockDownloadItemImpl*>::iterator first_item 288 = items_.begin(); 289 MockDownloadItemImpl* result = first_item->second; 290 items_.erase(first_item); 291 return result; 292 } 293 294 void MockDownloadItemFactory::RemoveItem(int id) { 295 DCHECK(items_.find(id) != items_.end()); 296 items_.erase(id); 297 } 298 299 DownloadItemImpl* MockDownloadItemFactory::CreatePersistedItem( 300 DownloadItemImplDelegate* delegate, 301 uint32 download_id, 302 const base::FilePath& current_path, 303 const base::FilePath& target_path, 304 const std::vector<GURL>& url_chain, 305 const GURL& referrer_url, 306 const std::string& mime_type, 307 const std::string& original_mime_type, 308 const base::Time& start_time, 309 const base::Time& end_time, 310 const std::string& etag, 311 const std::string& last_modified, 312 int64 received_bytes, 313 int64 total_bytes, 314 DownloadItem::DownloadState state, 315 DownloadDangerType danger_type, 316 DownloadInterruptReason interrupt_reason, 317 bool opened, 318 const net::BoundNetLog& bound_net_log) { 319 DCHECK(items_.find(download_id) == items_.end()); 320 MockDownloadItemImpl* result = 321 new StrictMock<MockDownloadItemImpl>(&item_delegate_); 322 EXPECT_CALL(*result, GetId()) 323 .WillRepeatedly(Return(download_id)); 324 items_[download_id] = result; 325 return result; 326 } 327 328 DownloadItemImpl* MockDownloadItemFactory::CreateActiveItem( 329 DownloadItemImplDelegate* delegate, 330 uint32 download_id, 331 const DownloadCreateInfo& info, 332 const net::BoundNetLog& bound_net_log) { 333 DCHECK(items_.find(download_id) == items_.end()); 334 335 MockDownloadItemImpl* result = 336 new StrictMock<MockDownloadItemImpl>(&item_delegate_); 337 EXPECT_CALL(*result, GetId()) 338 .WillRepeatedly(Return(download_id)); 339 items_[download_id] = result; 340 341 // Active items are created and then immediately are called to start 342 // the download. 343 EXPECT_CALL(*result, MockStart(_, _)); 344 345 return result; 346 } 347 348 DownloadItemImpl* MockDownloadItemFactory::CreateSavePageItem( 349 DownloadItemImplDelegate* delegate, 350 uint32 download_id, 351 const base::FilePath& path, 352 const GURL& url, 353 const std::string& mime_type, 354 scoped_ptr<DownloadRequestHandleInterface> request_handle, 355 const net::BoundNetLog& bound_net_log) { 356 DCHECK(items_.find(download_id) == items_.end()); 357 358 MockDownloadItemImpl* result = 359 new StrictMock<MockDownloadItemImpl>(&item_delegate_); 360 EXPECT_CALL(*result, GetId()) 361 .WillRepeatedly(Return(download_id)); 362 items_[download_id] = result; 363 364 return result; 365 } 366 367 class MockDownloadFileFactory 368 : public DownloadFileFactory, 369 public base::SupportsWeakPtr<MockDownloadFileFactory> { 370 public: 371 MockDownloadFileFactory() {} 372 virtual ~MockDownloadFileFactory() {} 373 374 // Overridden method from DownloadFileFactory 375 MOCK_METHOD8(MockCreateFile, MockDownloadFile*( 376 const DownloadSaveInfo&, 377 const base::FilePath&, 378 const GURL&, const GURL&, bool, 379 ByteStreamReader*, 380 const net::BoundNetLog&, 381 base::WeakPtr<DownloadDestinationObserver>)); 382 383 virtual DownloadFile* CreateFile( 384 scoped_ptr<DownloadSaveInfo> save_info, 385 const base::FilePath& default_download_directory, 386 const GURL& url, 387 const GURL& referrer_url, 388 bool calculate_hash, 389 scoped_ptr<ByteStreamReader> stream, 390 const net::BoundNetLog& bound_net_log, 391 base::WeakPtr<DownloadDestinationObserver> observer) { 392 return MockCreateFile(*save_info.get(), default_download_directory, url, 393 referrer_url, calculate_hash, 394 stream.get(), bound_net_log, observer); 395 } 396 }; 397 398 class MockBrowserContext : public BrowserContext { 399 public: 400 MockBrowserContext() {} 401 ~MockBrowserContext() {} 402 403 MOCK_CONST_METHOD0(GetPath, base::FilePath()); 404 MOCK_CONST_METHOD0(IsOffTheRecord, bool()); 405 MOCK_METHOD0(GetRequestContext, net::URLRequestContextGetter*()); 406 MOCK_METHOD1(GetRequestContextForRenderProcess, 407 net::URLRequestContextGetter*(int renderer_child_id)); 408 MOCK_METHOD0(GetMediaRequestContext, 409 net::URLRequestContextGetter*()); 410 MOCK_METHOD1(GetMediaRequestContextForRenderProcess, 411 net::URLRequestContextGetter*(int renderer_child_id)); 412 MOCK_METHOD2(GetMediaRequestContextForStoragePartition, 413 net::URLRequestContextGetter*( 414 const base::FilePath& partition_path, bool in_memory)); 415 MOCK_METHOD0(GetResourceContext, ResourceContext*()); 416 MOCK_METHOD0(GetDownloadManagerDelegate, DownloadManagerDelegate*()); 417 MOCK_METHOD0(GetGuestManager, BrowserPluginGuestManager* ()); 418 MOCK_METHOD0(GetSpecialStoragePolicy, storage::SpecialStoragePolicy*()); 419 MOCK_METHOD0(GetPushMessagingService, PushMessagingService*()); 420 MOCK_METHOD0(GetSSLHostStateDelegate, SSLHostStateDelegate*()); 421 }; 422 423 class MockDownloadManagerObserver : public DownloadManager::Observer { 424 public: 425 MockDownloadManagerObserver() {} 426 ~MockDownloadManagerObserver() {} 427 MOCK_METHOD2(OnDownloadCreated, void( 428 DownloadManager*, DownloadItem*)); 429 MOCK_METHOD1(ManagerGoingDown, void(DownloadManager*)); 430 MOCK_METHOD2(SelectFileDialogDisplayed, void( 431 DownloadManager*, int32)); 432 }; 433 434 } // namespace 435 436 class DownloadManagerTest : public testing::Test { 437 public: 438 static const char* kTestData; 439 static const size_t kTestDataLen; 440 441 DownloadManagerTest() 442 : callback_called_(false), 443 ui_thread_(BrowserThread::UI, &message_loop_), 444 file_thread_(BrowserThread::FILE, &message_loop_), 445 next_download_id_(0) { 446 } 447 448 // We tear down everything in TearDown(). 449 virtual ~DownloadManagerTest() {} 450 451 // Create a MockDownloadItemFactory and MockDownloadManagerDelegate, 452 // then create a DownloadManager that points 453 // at all of those. 454 virtual void SetUp() { 455 DCHECK(!download_manager_); 456 457 mock_download_item_factory_ = (new MockDownloadItemFactory())->AsWeakPtr(); 458 mock_download_file_factory_ = (new MockDownloadFileFactory())->AsWeakPtr(); 459 mock_download_manager_delegate_.reset( 460 new StrictMock<MockDownloadManagerDelegate>); 461 EXPECT_CALL(*mock_download_manager_delegate_.get(), Shutdown()) 462 .WillOnce(Return()); 463 mock_browser_context_.reset(new StrictMock<MockBrowserContext>); 464 EXPECT_CALL(*mock_browser_context_.get(), IsOffTheRecord()) 465 .WillRepeatedly(Return(false)); 466 467 download_manager_.reset(new DownloadManagerImpl( 468 NULL, mock_browser_context_.get())); 469 download_manager_->SetDownloadItemFactoryForTesting( 470 scoped_ptr<DownloadItemFactory>( 471 mock_download_item_factory_.get()).Pass()); 472 download_manager_->SetDownloadFileFactoryForTesting( 473 scoped_ptr<DownloadFileFactory>( 474 mock_download_file_factory_.get()).Pass()); 475 observer_.reset(new MockDownloadManagerObserver()); 476 download_manager_->AddObserver(observer_.get()); 477 download_manager_->SetDelegate(mock_download_manager_delegate_.get()); 478 } 479 480 virtual void TearDown() { 481 while (MockDownloadItemImpl* 482 item = mock_download_item_factory_->PopItem()) { 483 EXPECT_CALL(*item, GetState()) 484 .WillOnce(Return(DownloadItem::CANCELLED)); 485 } 486 EXPECT_CALL(GetMockObserver(), ManagerGoingDown(download_manager_.get())) 487 .WillOnce(Return()); 488 489 download_manager_->Shutdown(); 490 download_manager_.reset(); 491 message_loop_.RunUntilIdle(); 492 ASSERT_EQ(NULL, mock_download_item_factory_.get()); 493 ASSERT_EQ(NULL, mock_download_file_factory_.get()); 494 message_loop_.RunUntilIdle(); 495 mock_download_manager_delegate_.reset(); 496 mock_browser_context_.reset(); 497 } 498 499 // Returns download id. 500 MockDownloadItemImpl& AddItemToManager() { 501 DownloadCreateInfo info; 502 503 // Args are ignored except for download id, so everything else can be 504 // null. 505 uint32 id = next_download_id_; 506 ++next_download_id_; 507 info.request_handle = DownloadRequestHandle(); 508 download_manager_->CreateActiveItem(id, info); 509 DCHECK(mock_download_item_factory_->GetItem(id)); 510 MockDownloadItemImpl& item(*mock_download_item_factory_->GetItem(id)); 511 // Satisfy expectation. If the item is created in StartDownload(), 512 // we call Start on it immediately, so we need to set that expectation 513 // in the factory. 514 scoped_ptr<DownloadRequestHandleInterface> req_handle; 515 item.Start(scoped_ptr<DownloadFile>(), req_handle.Pass()); 516 517 return item; 518 } 519 520 MockDownloadItemImpl& GetMockDownloadItem(int id) { 521 MockDownloadItemImpl* itemp = mock_download_item_factory_->GetItem(id); 522 523 DCHECK(itemp); 524 return *itemp; 525 } 526 527 void RemoveMockDownloadItem(int id) { 528 // Owned by DownloadManager; should be deleted there. 529 mock_download_item_factory_->RemoveItem(id); 530 } 531 532 MockDownloadManagerDelegate& GetMockDownloadManagerDelegate() { 533 return *mock_download_manager_delegate_; 534 } 535 536 MockDownloadManagerObserver& GetMockObserver() { 537 return *observer_; 538 } 539 540 void DownloadTargetDeterminedCallback( 541 const base::FilePath& target_path, 542 DownloadItem::TargetDisposition disposition, 543 DownloadDangerType danger_type, 544 const base::FilePath& intermediate_path) { 545 callback_called_ = true; 546 target_path_ = target_path; 547 target_disposition_ = disposition; 548 danger_type_ = danger_type; 549 intermediate_path_ = intermediate_path; 550 } 551 552 void DetermineDownloadTarget(DownloadItemImpl* item) { 553 download_manager_->DetermineDownloadTarget( 554 item, base::Bind( 555 &DownloadManagerTest::DownloadTargetDeterminedCallback, 556 base::Unretained(this))); 557 } 558 559 protected: 560 // Key test variable; we'll keep it available to sub-classes. 561 scoped_ptr<DownloadManagerImpl> download_manager_; 562 base::WeakPtr<MockDownloadFileFactory> mock_download_file_factory_; 563 564 // Target detetermined callback. 565 bool callback_called_; 566 base::FilePath target_path_; 567 DownloadItem::TargetDisposition target_disposition_; 568 DownloadDangerType danger_type_; 569 base::FilePath intermediate_path_; 570 571 private: 572 base::MessageLoopForUI message_loop_; 573 TestBrowserThread ui_thread_; 574 TestBrowserThread file_thread_; 575 base::WeakPtr<MockDownloadItemFactory> mock_download_item_factory_; 576 scoped_ptr<MockDownloadManagerDelegate> mock_download_manager_delegate_; 577 scoped_ptr<MockBrowserContext> mock_browser_context_; 578 scoped_ptr<MockDownloadManagerObserver> observer_; 579 uint32 next_download_id_; 580 581 DISALLOW_COPY_AND_ASSIGN(DownloadManagerTest); 582 }; 583 584 // Confirm the appropriate invocations occur when you start a download. 585 TEST_F(DownloadManagerTest, StartDownload) { 586 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); 587 scoped_ptr<ByteStreamReader> stream; 588 uint32 local_id(5); // Random value 589 base::FilePath download_path(FILE_PATH_LITERAL("download/path")); 590 591 EXPECT_FALSE(download_manager_->GetDownload(local_id)); 592 593 EXPECT_CALL(GetMockObserver(), OnDownloadCreated(download_manager_.get(), _)) 594 .WillOnce(Return()); 595 EXPECT_CALL(GetMockDownloadManagerDelegate(), GetNextId(_)) 596 .WillOnce(RunCallback<0>(local_id)); 597 598 // Doing nothing will set the default download directory to null. 599 EXPECT_CALL(GetMockDownloadManagerDelegate(), GetSaveDir(_, _, _, _)); 600 EXPECT_CALL(GetMockDownloadManagerDelegate(), GenerateFileHash()) 601 .WillOnce(Return(true)); 602 EXPECT_CALL(GetMockDownloadManagerDelegate(), 603 ApplicationClientIdForFileScanning()) 604 .WillRepeatedly(Return("client-id")); 605 MockDownloadFile* mock_file = new MockDownloadFile; 606 EXPECT_CALL(*mock_file, SetClientGuid("client-id")); 607 EXPECT_CALL(*mock_download_file_factory_.get(), 608 MockCreateFile(Ref(*info->save_info.get()), _, _, _, true, 609 stream.get(), _, _)) 610 .WillOnce(Return(mock_file)); 611 612 download_manager_->StartDownload( 613 info.Pass(), stream.Pass(), DownloadUrlParameters::OnStartedCallback()); 614 EXPECT_TRUE(download_manager_->GetDownload(local_id)); 615 } 616 617 // Confirm that calling DetermineDownloadTarget behaves properly if the delegate 618 // blocks starting. 619 TEST_F(DownloadManagerTest, DetermineDownloadTarget_True) { 620 // Put a mock we have a handle to on the download manager. 621 MockDownloadItemImpl& item(AddItemToManager()); 622 EXPECT_CALL(item, GetState()) 623 .WillRepeatedly(Return(DownloadItem::IN_PROGRESS)); 624 625 EXPECT_CALL(GetMockDownloadManagerDelegate(), 626 DetermineDownloadTarget(&item, _)) 627 .WillOnce(Return(true)); 628 DetermineDownloadTarget(&item); 629 } 630 631 // Confirm that calling DetermineDownloadTarget behaves properly if the delegate 632 // allows starting. This also tests OnDownloadTargetDetermined. 633 TEST_F(DownloadManagerTest, DetermineDownloadTarget_False) { 634 // Put a mock we have a handle to on the download manager. 635 MockDownloadItemImpl& item(AddItemToManager()); 636 637 base::FilePath path(FILE_PATH_LITERAL("random_filepath.txt")); 638 EXPECT_CALL(GetMockDownloadManagerDelegate(), 639 DetermineDownloadTarget(&item, _)) 640 .WillOnce(Return(false)); 641 EXPECT_CALL(item, GetForcedFilePath()) 642 .WillOnce(ReturnRef(path)); 643 644 // Confirm that the callback was called with the right values in this case. 645 callback_called_ = false; 646 DetermineDownloadTarget(&item); 647 EXPECT_TRUE(callback_called_); 648 EXPECT_EQ(path, target_path_); 649 EXPECT_EQ(DownloadItem::TARGET_DISPOSITION_OVERWRITE, target_disposition_); 650 EXPECT_EQ(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, danger_type_); 651 EXPECT_EQ(path, intermediate_path_); 652 } 653 654 // Confirm the DownloadManagerImpl::RemoveAllDownloads() functionality 655 TEST_F(DownloadManagerTest, RemoveAllDownloads) { 656 base::Time now(base::Time::Now()); 657 for (uint32 i = 0; i < 4; ++i) { 658 MockDownloadItemImpl& item(AddItemToManager()); 659 EXPECT_EQ(i, item.GetId()); 660 EXPECT_CALL(item, GetStartTime()) 661 .WillRepeatedly(Return(now)); 662 } 663 664 // Specify states for each. 665 EXPECT_CALL(GetMockDownloadItem(0), GetState()) 666 .WillRepeatedly(Return(DownloadItem::COMPLETE)); 667 EXPECT_CALL(GetMockDownloadItem(1), GetState()) 668 .WillRepeatedly(Return(DownloadItem::CANCELLED)); 669 EXPECT_CALL(GetMockDownloadItem(2), GetState()) 670 .WillRepeatedly(Return(DownloadItem::INTERRUPTED)); 671 EXPECT_CALL(GetMockDownloadItem(3), GetState()) 672 .WillRepeatedly(Return(DownloadItem::IN_PROGRESS)); 673 674 // Expectations for whether or not they'll actually be removed. 675 EXPECT_CALL(GetMockDownloadItem(0), Remove()) 676 .WillOnce(Return()); 677 EXPECT_CALL(GetMockDownloadItem(1), Remove()) 678 .WillOnce(Return()); 679 EXPECT_CALL(GetMockDownloadItem(2), Remove()) 680 .WillOnce(Return()); 681 EXPECT_CALL(GetMockDownloadItem(3), Remove()) 682 .Times(0); 683 684 download_manager_->RemoveAllDownloads(); 685 // Because we're mocking the download item, the Remove call doesn't 686 // result in them being removed from the DownloadManager list. 687 } 688 689 } // namespace content 690