download_manager_impl_unittest.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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.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
50
51namespace content {
52class ByteStreamReader;
53
54namespace {
55
56// Matches a DownloadCreateInfo* that points to the same object as |info| and
57// has a |default_download_directory| that matches |download_directory|.
58MATCHER_P2(DownloadCreateInfoWithDefaultPath, info, download_directory, "") {
59  return arg == info &&
60      arg->default_download_directory == download_directory;
61}
62
63class MockDownloadItemImpl : public DownloadItemImpl {
64 public:
65  // Use history constructor for minimal base object.
66  explicit MockDownloadItemImpl(DownloadItemImplDelegate* delegate)
67      : DownloadItemImpl(
68          delegate,
69          content::DownloadId(),
70          base::FilePath(),
71          base::FilePath(),
72          std::vector<GURL>(),
73          GURL(),
74          base::Time(),
75          base::Time(),
76          0,
77          0,
78          DownloadItem::COMPLETE,
79          DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
80          DOWNLOAD_INTERRUPT_REASON_NONE,
81          false,
82          net::BoundNetLog()) {}
83  virtual ~MockDownloadItemImpl() {}
84
85  MOCK_METHOD4(OnDownloadTargetDetermined,
86               void(const base::FilePath&, TargetDisposition,
87                    DownloadDangerType, const base::FilePath&));
88  MOCK_METHOD1(AddObserver, void(DownloadItem::Observer*));
89  MOCK_METHOD1(RemoveObserver, void(DownloadItem::Observer*));
90  MOCK_METHOD0(UpdateObservers, void());
91  MOCK_METHOD0(CanShowInFolder, bool());
92  MOCK_METHOD0(CanOpenDownload, bool());
93  MOCK_METHOD0(ShouldOpenFileBasedOnExtension, bool());
94  MOCK_METHOD0(OpenDownload, void());
95  MOCK_METHOD0(ShowDownloadInShell, void());
96  MOCK_METHOD0(ValidateDangerousDownload, void());
97  MOCK_METHOD1(StealDangerousDownload, void(const AcquireFileCallback&));
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_METHOD0(Remove, void());
112  MOCK_CONST_METHOD1(TimeRemaining, bool(base::TimeDelta*));
113  MOCK_CONST_METHOD0(CurrentSpeed, int64());
114  MOCK_CONST_METHOD0(PercentComplete, int());
115  MOCK_CONST_METHOD0(AllDataSaved, bool());
116  MOCK_CONST_METHOD1(MatchesQuery, bool(const string16& query));
117  MOCK_CONST_METHOD0(IsDone, bool());
118  MOCK_CONST_METHOD0(IsInProgress, bool());
119  MOCK_CONST_METHOD0(IsCancelled, bool());
120  MOCK_CONST_METHOD0(IsInterrupted, bool());
121  MOCK_CONST_METHOD0(IsComplete, bool());
122  MOCK_CONST_METHOD0(GetFullPath, const base::FilePath&());
123  MOCK_CONST_METHOD0(GetTargetFilePath, const base::FilePath&());
124  MOCK_CONST_METHOD0(GetTargetDisposition, TargetDisposition());
125  MOCK_METHOD1(OnContentCheckCompleted, void(DownloadDangerType));
126  MOCK_CONST_METHOD0(GetState, DownloadState());
127  MOCK_CONST_METHOD0(GetUrlChain, const std::vector<GURL>&());
128  MOCK_METHOD1(SetTotalBytes, void(int64));
129  MOCK_CONST_METHOD0(GetURL, const GURL&());
130  MOCK_CONST_METHOD0(GetOriginalUrl, const GURL&());
131  MOCK_CONST_METHOD0(GetReferrerUrl, const GURL&());
132  MOCK_CONST_METHOD0(GetSuggestedFilename, std::string());
133  MOCK_CONST_METHOD0(GetContentDisposition, std::string());
134  MOCK_CONST_METHOD0(GetMimeType, std::string());
135  MOCK_CONST_METHOD0(GetOriginalMimeType, std::string());
136  MOCK_CONST_METHOD0(GetReferrerCharset, std::string());
137  MOCK_CONST_METHOD0(GetRemoteAddress, std::string());
138  MOCK_CONST_METHOD0(GetTotalBytes, int64());
139  MOCK_CONST_METHOD0(GetReceivedBytes, int64());
140  MOCK_CONST_METHOD0(GetHashState, const std::string&());
141  MOCK_CONST_METHOD0(GetHash, const std::string&());
142  MOCK_CONST_METHOD0(GetId, int32());
143  MOCK_CONST_METHOD0(GetGlobalId, DownloadId());
144  MOCK_CONST_METHOD0(GetStartTime, base::Time());
145  MOCK_CONST_METHOD0(GetEndTime, base::Time());
146  MOCK_METHOD0(GetDownloadManager, DownloadManager*());
147  MOCK_CONST_METHOD0(IsPaused, bool());
148  MOCK_CONST_METHOD0(GetOpenWhenComplete, bool());
149  MOCK_METHOD1(SetOpenWhenComplete, void(bool));
150  MOCK_CONST_METHOD0(GetFileExternallyRemoved, bool());
151  MOCK_CONST_METHOD0(GetDangerType, DownloadDangerType());
152  MOCK_CONST_METHOD0(IsDangerous, bool());
153  MOCK_METHOD0(GetAutoOpened, bool());
154  MOCK_CONST_METHOD0(GetForcedFilePath, const base::FilePath&());
155  MOCK_CONST_METHOD0(HasUserGesture, bool());
156  MOCK_CONST_METHOD0(GetTransitionType, PageTransition());
157  MOCK_CONST_METHOD0(IsTemporary, bool());
158  MOCK_METHOD1(SetIsTemporary, void(bool));
159  MOCK_METHOD1(SetOpened, void(bool));
160  MOCK_CONST_METHOD0(GetOpened, bool());
161  MOCK_CONST_METHOD0(GetLastModifiedTime, const std::string&());
162  MOCK_CONST_METHOD0(GetETag, const std::string&());
163  MOCK_CONST_METHOD0(GetLastReason, DownloadInterruptReason());
164  MOCK_CONST_METHOD0(GetBrowserContext, BrowserContext*());
165  MOCK_CONST_METHOD0(GetWebContents, WebContents*());
166  MOCK_CONST_METHOD0(GetFileNameToReportUser, base::FilePath());
167  MOCK_METHOD1(SetDisplayName, void(const base::FilePath&));
168  MOCK_METHOD0(NotifyRemoved, void());
169  // May be called when vlog is on.
170  virtual std::string DebugString(bool verbose) const OVERRIDE {
171    return std::string();
172  }
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      DownloadId download_id,
244      const DownloadCreateInfo& info,
245      const net::BoundNetLog& bound_net_log) OVERRIDE;
246  virtual DownloadItemImpl* CreateSavePageItem(
247      DownloadItemImplDelegate* delegate,
248      DownloadId download_id,
249      const base::FilePath& path,
250      const GURL& url,
251        const std::string& mime_type,
252      scoped_ptr<DownloadRequestHandleInterface> request_handle,
253      const net::BoundNetLog& bound_net_log) OVERRIDE;
254
255 private:
256  std::map<int32, MockDownloadItemImpl*> items_;
257  DownloadItemImplDelegate item_delegate_;
258
259  DISALLOW_COPY_AND_ASSIGN(MockDownloadItemFactory);
260};
261
262MockDownloadItemFactory::MockDownloadItemFactory() {}
263
264MockDownloadItemFactory::~MockDownloadItemFactory() {}
265
266MockDownloadItemImpl* MockDownloadItemFactory::GetItem(int id) {
267  if (items_.find(id) == items_.end())
268    return NULL;
269  return items_[id];
270}
271
272MockDownloadItemImpl* MockDownloadItemFactory::PopItem() {
273  if (items_.empty())
274    return NULL;
275
276  std::map<int32, MockDownloadItemImpl*>::iterator first_item
277      = items_.begin();
278  MockDownloadItemImpl* result = first_item->second;
279  items_.erase(first_item);
280  return result;
281}
282
283void MockDownloadItemFactory::RemoveItem(int id) {
284  DCHECK(items_.find(id) != items_.end());
285  items_.erase(id);
286}
287
288DownloadItemImpl* MockDownloadItemFactory::CreatePersistedItem(
289    DownloadItemImplDelegate* delegate,
290    DownloadId download_id,
291    const base::FilePath& current_path,
292    const base::FilePath& target_path,
293    const std::vector<GURL>& url_chain,
294    const GURL& referrer_url,
295    const base::Time& start_time,
296    const base::Time& end_time,
297    int64 received_bytes,
298    int64 total_bytes,
299    DownloadItem::DownloadState state,
300    DownloadDangerType danger_type,
301    DownloadInterruptReason interrupt_reason,
302    bool opened,
303    const net::BoundNetLog& bound_net_log) {
304  int local_id = download_id.local();
305  DCHECK(items_.find(local_id) == items_.end());
306
307  MockDownloadItemImpl* result =
308      new StrictMock<MockDownloadItemImpl>(&item_delegate_);
309  EXPECT_CALL(*result, GetId())
310      .WillRepeatedly(Return(local_id));
311  items_[local_id] = result;
312
313  return result;
314}
315
316DownloadItemImpl* MockDownloadItemFactory::CreateActiveItem(
317    DownloadItemImplDelegate* delegate,
318    DownloadId download_id,
319    const DownloadCreateInfo& info,
320    const net::BoundNetLog& bound_net_log) {
321  int local_id = download_id.local();
322  DCHECK(items_.find(local_id) == items_.end());
323
324  MockDownloadItemImpl* result =
325      new StrictMock<MockDownloadItemImpl>(&item_delegate_);
326  EXPECT_CALL(*result, GetId())
327      .WillRepeatedly(Return(local_id));
328  EXPECT_CALL(*result, GetGlobalId())
329      .WillRepeatedly(Return(download_id));
330  items_[local_id] = result;
331
332  // Active items are created and then immediately are called to start
333  // the download.
334  EXPECT_CALL(*result, MockStart(_, _));
335
336  return result;
337}
338
339DownloadItemImpl* MockDownloadItemFactory::CreateSavePageItem(
340    DownloadItemImplDelegate* delegate,
341    DownloadId download_id,
342    const base::FilePath& path,
343    const GURL& url,
344    const std::string& mime_type,
345    scoped_ptr<DownloadRequestHandleInterface> request_handle,
346    const net::BoundNetLog& bound_net_log) {
347  int local_id = download_id.local();
348  DCHECK(items_.find(local_id) == items_.end());
349
350  MockDownloadItemImpl* result =
351      new StrictMock<MockDownloadItemImpl>(&item_delegate_);
352  EXPECT_CALL(*result, GetId())
353      .WillRepeatedly(Return(local_id));
354  items_[local_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, DownloadFile*(
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_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_METHOD0(GetResourceContext, ResourceContext*());
408  MOCK_METHOD0(GetDownloadManagerDelegate, DownloadManagerDelegate*());
409  MOCK_METHOD0(GetGeolocationPermissionContext,
410               GeolocationPermissionContext* ());
411  MOCK_METHOD0(GetSpeechRecognitionPreferences,
412               SpeechRecognitionPreferences* ());
413  MOCK_METHOD0(GetSpecialStoragePolicy, quota::SpecialStoragePolicy*());
414};
415
416class MockDownloadManagerObserver : public DownloadManager::Observer {
417 public:
418  MockDownloadManagerObserver() {}
419  ~MockDownloadManagerObserver() {}
420  MOCK_METHOD2(OnDownloadCreated, void(
421        DownloadManager*, DownloadItem*));
422  MOCK_METHOD1(ManagerGoingDown, void(DownloadManager*));
423  MOCK_METHOD2(SelectFileDialogDisplayed, void(
424        DownloadManager*, int32));
425};
426
427}  // namespace
428
429class DownloadManagerTest : public testing::Test {
430 public:
431  static const char* kTestData;
432  static const size_t kTestDataLen;
433
434  DownloadManagerTest()
435      : ui_thread_(BrowserThread::UI, &message_loop_),
436        file_thread_(BrowserThread::FILE, &message_loop_),
437        next_download_id_(0) {
438  }
439
440  // We tear down everything in TearDown().
441  virtual ~DownloadManagerTest() {}
442
443  // Create a MockDownloadItemFactory and MockDownloadManagerDelegate,
444  // then create a DownloadManager that points
445  // at all of those.
446  virtual void SetUp() {
447    DCHECK(!download_manager_);
448
449    mock_download_item_factory_ = (new MockDownloadItemFactory())->AsWeakPtr();
450    mock_download_file_factory_ = (new MockDownloadFileFactory())->AsWeakPtr();
451    mock_download_manager_delegate_.reset(
452        new StrictMock<MockDownloadManagerDelegate>);
453    EXPECT_CALL(*mock_download_manager_delegate_.get(), Shutdown())
454        .WillOnce(Return());
455    mock_browser_context_.reset(new StrictMock<MockBrowserContext>);
456    EXPECT_CALL(*mock_browser_context_.get(), IsOffTheRecord())
457        .WillRepeatedly(Return(false));
458
459    download_manager_.reset(new DownloadManagerImpl(
460                                NULL, mock_browser_context_.get()));
461    download_manager_->SetDownloadItemFactoryForTesting(
462        scoped_ptr<DownloadItemFactory>(
463            mock_download_item_factory_.get()).Pass());
464    download_manager_->SetDownloadFileFactoryForTesting(
465        scoped_ptr<DownloadFileFactory>(
466            mock_download_file_factory_.get()).Pass());
467    observer_.reset(new MockDownloadManagerObserver());
468    download_manager_->AddObserver(observer_.get());
469    download_manager_->SetDelegate(mock_download_manager_delegate_.get());
470  }
471
472  virtual void TearDown() {
473    while (MockDownloadItemImpl*
474           item = mock_download_item_factory_->PopItem()) {
475      EXPECT_CALL(*item, GetState())
476          .WillOnce(Return(DownloadItem::CANCELLED));
477    }
478    EXPECT_CALL(GetMockObserver(), ManagerGoingDown(download_manager_.get()))
479        .WillOnce(Return());
480
481    download_manager_->Shutdown();
482    download_manager_.reset();
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.request_handle = DownloadRequestHandle();
502    download_manager_->CreateActiveItem(DownloadId(kDownloadIdDomain, id),
503                                        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  int next_download_id_;
575
576  DISALLOW_COPY_AND_ASSIGN(DownloadManagerTest);
577};
578
579// Confirm the appropriate invocations occur when you start a download.
580TEST_F(DownloadManagerTest, StartDownload) {
581  scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo);
582  scoped_ptr<ByteStreamReader> stream;
583  int32 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(Return(DownloadId(this, 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(*mock_download_file_factory_.get(),
598              MockCreateFile(Ref(*info->save_info.get()), _, _, _, true,
599                             stream.get(), _, _));
600
601  download_manager_->StartDownload(info.Pass(), stream.Pass());
602  EXPECT_TRUE(download_manager_->GetDownload(local_id));
603}
604
605// Confirm that calling DetermineDownloadTarget behaves properly if the delegate
606// blocks starting.
607TEST_F(DownloadManagerTest, DetermineDownloadTarget_True) {
608  // Put a mock we have a handle to on the download manager.
609  MockDownloadItemImpl& item(AddItemToManager());
610  EXPECT_CALL(item, IsInProgress())
611      .WillRepeatedly(Return(true));
612
613  EXPECT_CALL(GetMockDownloadManagerDelegate(),
614              DetermineDownloadTarget(&item, _))
615      .WillOnce(Return(true));
616  DetermineDownloadTarget(&item);
617}
618
619// Confirm that calling DetermineDownloadTarget behaves properly if the delegate
620// allows starting.  This also tests OnDownloadTargetDetermined.
621TEST_F(DownloadManagerTest, DetermineDownloadTarget_False) {
622  // Put a mock we have a handle to on the download manager.
623  MockDownloadItemImpl& item(AddItemToManager());
624
625  base::FilePath path(FILE_PATH_LITERAL("random_filepath.txt"));
626  EXPECT_CALL(GetMockDownloadManagerDelegate(),
627              DetermineDownloadTarget(&item, _))
628      .WillOnce(Return(false));
629  EXPECT_CALL(item, GetForcedFilePath())
630      .WillOnce(ReturnRef(path));
631
632  // Confirm that the callback was called with the right values in this case.
633  callback_called_ = false;
634  DetermineDownloadTarget(&item);
635  EXPECT_TRUE(callback_called_);
636  EXPECT_EQ(path, target_path_);
637  EXPECT_EQ(DownloadItem::TARGET_DISPOSITION_OVERWRITE, target_disposition_);
638  EXPECT_EQ(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, danger_type_);
639  EXPECT_EQ(path, intermediate_path_);
640}
641
642// Confirm the DownloadManagerImpl::RemoveAllDownloads() functionality
643TEST_F(DownloadManagerTest, RemoveAllDownloads) {
644  base::Time now(base::Time::Now());
645  for (int i = 0; i < 4; ++i) {
646    MockDownloadItemImpl& item(AddItemToManager());
647    EXPECT_EQ(i, item.GetId());
648    EXPECT_CALL(item, GetStartTime())
649        .WillRepeatedly(Return(now));
650
651    // Default returns; overridden for each item below.
652    EXPECT_CALL(GetMockDownloadItem(i), IsComplete())
653        .WillRepeatedly(Return(false));
654    EXPECT_CALL(GetMockDownloadItem(i), IsCancelled())
655        .WillRepeatedly(Return(false));
656    EXPECT_CALL(GetMockDownloadItem(i), IsInterrupted())
657        .WillRepeatedly(Return(false));
658    EXPECT_CALL(GetMockDownloadItem(i), IsInProgress())
659        .WillRepeatedly(Return(false));
660  }
661
662  // Specify states for each.
663  EXPECT_CALL(GetMockDownloadItem(0), IsComplete())
664      .WillRepeatedly(Return(true));
665  EXPECT_CALL(GetMockDownloadItem(1), IsCancelled())
666      .WillRepeatedly(Return(true));
667  EXPECT_CALL(GetMockDownloadItem(2), IsInterrupted())
668      .WillRepeatedly(Return(true));
669  EXPECT_CALL(GetMockDownloadItem(3), IsInProgress())
670      .WillRepeatedly(Return(true));
671
672  // Expectations for whether or not they'll actually be removed.
673  EXPECT_CALL(GetMockDownloadItem(0), Remove())
674      .WillOnce(Return());
675  EXPECT_CALL(GetMockDownloadItem(1), Remove())
676      .WillOnce(Return());
677  EXPECT_CALL(GetMockDownloadItem(2), Remove())
678      .WillOnce(Return());
679  EXPECT_CALL(GetMockDownloadItem(3), Remove())
680      .Times(0);
681
682  download_manager_->RemoveAllDownloads();
683  // Because we're mocking the download item, the Remove call doesn't
684  // result in them being removed from the DownloadManager list.
685}
686
687}  // namespace content
688