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