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