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