Home | History | Annotate | Download | only in download
      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