download_manager_impl_unittest.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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          "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, 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
181class 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
205MockDownloadManagerDelegate::MockDownloadManagerDelegate() {}
206
207MockDownloadManagerDelegate::~MockDownloadManagerDelegate() {}
208
209class 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
273MockDownloadItemFactory::MockDownloadItemFactory() {}
274
275MockDownloadItemFactory::~MockDownloadItemFactory() {}
276
277MockDownloadItemImpl* MockDownloadItemFactory::GetItem(int id) {
278  if (items_.find(id) == items_.end())
279    return NULL;
280  return items_[id];
281}
282
283MockDownloadItemImpl* 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
294void MockDownloadItemFactory::RemoveItem(int id) {
295  DCHECK(items_.find(id) != items_.end());
296  items_.erase(id);
297}
298
299DownloadItemImpl* 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
328DownloadItemImpl* 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
348DownloadItemImpl* 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
367class 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
398class 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, quota::SpecialStoragePolicy*());
419  MOCK_METHOD0(GetPushMessagingService, PushMessagingService*());
420  MOCK_METHOD0(GetSSLHostStateDelegate, SSLHostStateDelegate*());
421};
422
423class 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
436class 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.
585TEST_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.
619TEST_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.
633TEST_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
655TEST_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