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