download_manager_impl_unittest.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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 40using ::testing::AllOf; 41using ::testing::DoAll; 42using ::testing::Eq; 43using ::testing::Ref; 44using ::testing::Return; 45using ::testing::ReturnRef; 46using ::testing::SetArgPointee; 47using ::testing::StrictMock; 48using ::testing::_; 49 50ACTION_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 56namespace content { 57class ByteStreamReader; 58 59namespace { 60 61// Matches a DownloadCreateInfo* that points to the same object as |info| and 62// has a |default_download_directory| that matches |download_directory|. 63MATCHER_P2(DownloadCreateInfoWithDefaultPath, info, download_directory, "") { 64 return arg == info && 65 arg->default_download_directory == download_directory; 66} 67 68class 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 177class 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 201MockDownloadManagerDelegate::MockDownloadManagerDelegate() {} 202 203MockDownloadManagerDelegate::~MockDownloadManagerDelegate() {} 204 205class 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 267MockDownloadItemFactory::MockDownloadItemFactory() {} 268 269MockDownloadItemFactory::~MockDownloadItemFactory() {} 270 271MockDownloadItemImpl* MockDownloadItemFactory::GetItem(int id) { 272 if (items_.find(id) == items_.end()) 273 return NULL; 274 return items_[id]; 275} 276 277MockDownloadItemImpl* 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 288void MockDownloadItemFactory::RemoveItem(int id) { 289 DCHECK(items_.find(id) != items_.end()); 290 items_.erase(id); 291} 292 293DownloadItemImpl* 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 320DownloadItemImpl* 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 340DownloadItemImpl* 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 359class 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 390class 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_METHOD6(RequestProtectedMediaIdentifierPermission, 419 void(int render_process_id, 420 int render_view_id, 421 int bridge_id, 422 int group_id, 423 const GURL& requesting_frame, 424 const ProtectedMediaIdentifierPermissionCallback& 425 callback)); 426 MOCK_METHOD1(CancelProtectedMediaIdentifierPermissionRequests, 427 void(int group_id)); 428 MOCK_METHOD0(GetResourceContext, ResourceContext*()); 429 MOCK_METHOD0(GetDownloadManagerDelegate, DownloadManagerDelegate*()); 430 MOCK_METHOD0(GetGeolocationPermissionContext, 431 GeolocationPermissionContext* ()); 432 MOCK_METHOD0(GetSpecialStoragePolicy, quota::SpecialStoragePolicy*()); 433}; 434 435class MockDownloadManagerObserver : public DownloadManager::Observer { 436 public: 437 MockDownloadManagerObserver() {} 438 ~MockDownloadManagerObserver() {} 439 MOCK_METHOD2(OnDownloadCreated, void( 440 DownloadManager*, DownloadItem*)); 441 MOCK_METHOD1(ManagerGoingDown, void(DownloadManager*)); 442 MOCK_METHOD2(SelectFileDialogDisplayed, void( 443 DownloadManager*, int32)); 444}; 445 446} // namespace 447 448class DownloadManagerTest : public testing::Test { 449 public: 450 static const char* kTestData; 451 static const size_t kTestDataLen; 452 453 DownloadManagerTest() 454 : callback_called_(false), 455 ui_thread_(BrowserThread::UI, &message_loop_), 456 file_thread_(BrowserThread::FILE, &message_loop_), 457 next_download_id_(0) { 458 } 459 460 // We tear down everything in TearDown(). 461 virtual ~DownloadManagerTest() {} 462 463 // Create a MockDownloadItemFactory and MockDownloadManagerDelegate, 464 // then create a DownloadManager that points 465 // at all of those. 466 virtual void SetUp() { 467 DCHECK(!download_manager_); 468 469 mock_download_item_factory_ = (new MockDownloadItemFactory())->AsWeakPtr(); 470 mock_download_file_factory_ = (new MockDownloadFileFactory())->AsWeakPtr(); 471 mock_download_manager_delegate_.reset( 472 new StrictMock<MockDownloadManagerDelegate>); 473 EXPECT_CALL(*mock_download_manager_delegate_.get(), Shutdown()) 474 .WillOnce(Return()); 475 mock_browser_context_.reset(new StrictMock<MockBrowserContext>); 476 EXPECT_CALL(*mock_browser_context_.get(), IsOffTheRecord()) 477 .WillRepeatedly(Return(false)); 478 479 download_manager_.reset(new DownloadManagerImpl( 480 NULL, mock_browser_context_.get())); 481 download_manager_->SetDownloadItemFactoryForTesting( 482 scoped_ptr<DownloadItemFactory>( 483 mock_download_item_factory_.get()).Pass()); 484 download_manager_->SetDownloadFileFactoryForTesting( 485 scoped_ptr<DownloadFileFactory>( 486 mock_download_file_factory_.get()).Pass()); 487 observer_.reset(new MockDownloadManagerObserver()); 488 download_manager_->AddObserver(observer_.get()); 489 download_manager_->SetDelegate(mock_download_manager_delegate_.get()); 490 } 491 492 virtual void TearDown() { 493 while (MockDownloadItemImpl* 494 item = mock_download_item_factory_->PopItem()) { 495 EXPECT_CALL(*item, GetState()) 496 .WillOnce(Return(DownloadItem::CANCELLED)); 497 } 498 EXPECT_CALL(GetMockObserver(), ManagerGoingDown(download_manager_.get())) 499 .WillOnce(Return()); 500 501 download_manager_->Shutdown(); 502 download_manager_.reset(); 503 message_loop_.RunUntilIdle(); 504 ASSERT_EQ(NULL, mock_download_item_factory_.get()); 505 ASSERT_EQ(NULL, mock_download_file_factory_.get()); 506 message_loop_.RunUntilIdle(); 507 mock_download_manager_delegate_.reset(); 508 mock_browser_context_.reset(); 509 } 510 511 // Returns download id. 512 MockDownloadItemImpl& AddItemToManager() { 513 DownloadCreateInfo info; 514 515 // Args are ignored except for download id, so everything else can be 516 // null. 517 uint32 id = next_download_id_; 518 ++next_download_id_; 519 info.request_handle = DownloadRequestHandle(); 520 download_manager_->CreateActiveItem(id, info); 521 DCHECK(mock_download_item_factory_->GetItem(id)); 522 MockDownloadItemImpl& item(*mock_download_item_factory_->GetItem(id)); 523 // Satisfy expectation. If the item is created in StartDownload(), 524 // we call Start on it immediately, so we need to set that expectation 525 // in the factory. 526 scoped_ptr<DownloadRequestHandleInterface> req_handle; 527 item.Start(scoped_ptr<DownloadFile>(), req_handle.Pass()); 528 529 return item; 530 } 531 532 MockDownloadItemImpl& GetMockDownloadItem(int id) { 533 MockDownloadItemImpl* itemp = mock_download_item_factory_->GetItem(id); 534 535 DCHECK(itemp); 536 return *itemp; 537 } 538 539 void RemoveMockDownloadItem(int id) { 540 // Owned by DownloadManager; should be deleted there. 541 mock_download_item_factory_->RemoveItem(id); 542 } 543 544 MockDownloadManagerDelegate& GetMockDownloadManagerDelegate() { 545 return *mock_download_manager_delegate_; 546 } 547 548 MockDownloadManagerObserver& GetMockObserver() { 549 return *observer_; 550 } 551 552 void DownloadTargetDeterminedCallback( 553 const base::FilePath& target_path, 554 DownloadItem::TargetDisposition disposition, 555 DownloadDangerType danger_type, 556 const base::FilePath& intermediate_path) { 557 callback_called_ = true; 558 target_path_ = target_path; 559 target_disposition_ = disposition; 560 danger_type_ = danger_type; 561 intermediate_path_ = intermediate_path; 562 } 563 564 void DetermineDownloadTarget(DownloadItemImpl* item) { 565 download_manager_->DetermineDownloadTarget( 566 item, base::Bind( 567 &DownloadManagerTest::DownloadTargetDeterminedCallback, 568 base::Unretained(this))); 569 } 570 571 protected: 572 // Key test variable; we'll keep it available to sub-classes. 573 scoped_ptr<DownloadManagerImpl> download_manager_; 574 base::WeakPtr<MockDownloadFileFactory> mock_download_file_factory_; 575 576 // Target detetermined callback. 577 bool callback_called_; 578 base::FilePath target_path_; 579 DownloadItem::TargetDisposition target_disposition_; 580 DownloadDangerType danger_type_; 581 base::FilePath intermediate_path_; 582 583 private: 584 base::MessageLoopForUI message_loop_; 585 TestBrowserThread ui_thread_; 586 TestBrowserThread file_thread_; 587 base::WeakPtr<MockDownloadItemFactory> mock_download_item_factory_; 588 scoped_ptr<MockDownloadManagerDelegate> mock_download_manager_delegate_; 589 scoped_ptr<MockBrowserContext> mock_browser_context_; 590 scoped_ptr<MockDownloadManagerObserver> observer_; 591 uint32 next_download_id_; 592 593 DISALLOW_COPY_AND_ASSIGN(DownloadManagerTest); 594}; 595 596// Confirm the appropriate invocations occur when you start a download. 597TEST_F(DownloadManagerTest, StartDownload) { 598 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); 599 scoped_ptr<ByteStreamReader> stream; 600 uint32 local_id(5); // Random value 601 base::FilePath download_path(FILE_PATH_LITERAL("download/path")); 602 603 EXPECT_FALSE(download_manager_->GetDownload(local_id)); 604 605 EXPECT_CALL(GetMockObserver(), OnDownloadCreated(download_manager_.get(), _)) 606 .WillOnce(Return()); 607 EXPECT_CALL(GetMockDownloadManagerDelegate(), GetNextId(_)) 608 .WillOnce(RunCallback<0>(local_id)); 609 610 // Doing nothing will set the default download directory to null. 611 EXPECT_CALL(GetMockDownloadManagerDelegate(), GetSaveDir(_, _, _, _)); 612 EXPECT_CALL(GetMockDownloadManagerDelegate(), GenerateFileHash()) 613 .WillOnce(Return(true)); 614 EXPECT_CALL(GetMockDownloadManagerDelegate(), 615 ApplicationClientIdForFileScanning()) 616 .WillRepeatedly(Return("client-id")); 617 MockDownloadFile* mock_file = new MockDownloadFile; 618 EXPECT_CALL(*mock_file, SetClientGuid("client-id")); 619 EXPECT_CALL(*mock_download_file_factory_.get(), 620 MockCreateFile(Ref(*info->save_info.get()), _, _, _, true, 621 stream.get(), _, _)) 622 .WillOnce(Return(mock_file)); 623 624 download_manager_->StartDownload( 625 info.Pass(), stream.Pass(), DownloadUrlParameters::OnStartedCallback()); 626 EXPECT_TRUE(download_manager_->GetDownload(local_id)); 627} 628 629// Confirm that calling DetermineDownloadTarget behaves properly if the delegate 630// blocks starting. 631TEST_F(DownloadManagerTest, DetermineDownloadTarget_True) { 632 // Put a mock we have a handle to on the download manager. 633 MockDownloadItemImpl& item(AddItemToManager()); 634 EXPECT_CALL(item, GetState()) 635 .WillRepeatedly(Return(DownloadItem::IN_PROGRESS)); 636 637 EXPECT_CALL(GetMockDownloadManagerDelegate(), 638 DetermineDownloadTarget(&item, _)) 639 .WillOnce(Return(true)); 640 DetermineDownloadTarget(&item); 641} 642 643// Confirm that calling DetermineDownloadTarget behaves properly if the delegate 644// allows starting. This also tests OnDownloadTargetDetermined. 645TEST_F(DownloadManagerTest, DetermineDownloadTarget_False) { 646 // Put a mock we have a handle to on the download manager. 647 MockDownloadItemImpl& item(AddItemToManager()); 648 649 base::FilePath path(FILE_PATH_LITERAL("random_filepath.txt")); 650 EXPECT_CALL(GetMockDownloadManagerDelegate(), 651 DetermineDownloadTarget(&item, _)) 652 .WillOnce(Return(false)); 653 EXPECT_CALL(item, GetForcedFilePath()) 654 .WillOnce(ReturnRef(path)); 655 656 // Confirm that the callback was called with the right values in this case. 657 callback_called_ = false; 658 DetermineDownloadTarget(&item); 659 EXPECT_TRUE(callback_called_); 660 EXPECT_EQ(path, target_path_); 661 EXPECT_EQ(DownloadItem::TARGET_DISPOSITION_OVERWRITE, target_disposition_); 662 EXPECT_EQ(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, danger_type_); 663 EXPECT_EQ(path, intermediate_path_); 664} 665 666// Confirm the DownloadManagerImpl::RemoveAllDownloads() functionality 667TEST_F(DownloadManagerTest, RemoveAllDownloads) { 668 base::Time now(base::Time::Now()); 669 for (uint32 i = 0; i < 4; ++i) { 670 MockDownloadItemImpl& item(AddItemToManager()); 671 EXPECT_EQ(i, item.GetId()); 672 EXPECT_CALL(item, GetStartTime()) 673 .WillRepeatedly(Return(now)); 674 } 675 676 // Specify states for each. 677 EXPECT_CALL(GetMockDownloadItem(0), GetState()) 678 .WillRepeatedly(Return(DownloadItem::COMPLETE)); 679 EXPECT_CALL(GetMockDownloadItem(1), GetState()) 680 .WillRepeatedly(Return(DownloadItem::CANCELLED)); 681 EXPECT_CALL(GetMockDownloadItem(2), GetState()) 682 .WillRepeatedly(Return(DownloadItem::INTERRUPTED)); 683 EXPECT_CALL(GetMockDownloadItem(3), GetState()) 684 .WillRepeatedly(Return(DownloadItem::IN_PROGRESS)); 685 686 // Expectations for whether or not they'll actually be removed. 687 EXPECT_CALL(GetMockDownloadItem(0), Remove()) 688 .WillOnce(Return()); 689 EXPECT_CALL(GetMockDownloadItem(1), Remove()) 690 .WillOnce(Return()); 691 EXPECT_CALL(GetMockDownloadItem(2), Remove()) 692 .WillOnce(Return()); 693 EXPECT_CALL(GetMockDownloadItem(3), Remove()) 694 .Times(0); 695 696 download_manager_->RemoveAllDownloads(); 697 // Because we're mocking the download item, the Remove call doesn't 698 // result in them being removed from the DownloadManager list. 699} 700 701} // namespace content 702