download_ui_controller_unittest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright 2013 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 "base/files/file_path.h"
6#include "base/memory/ref_counted.h"
7#include "base/memory/scoped_ptr.h"
8#include "base/memory/weak_ptr.h"
9#include "chrome/browser/download/download_ui_controller.h"
10#include "content/public/test/mock_download_item.h"
11#include "content/public/test/mock_download_manager.h"
12#include "testing/gmock/include/gmock/gmock.h"
13#include "testing/gtest/include/gtest/gtest.h"
14
15using content::MockDownloadItem;
16using content::MockDownloadManager;
17using testing::AnyNumber;
18using testing::Assign;
19using testing::Return;
20using testing::ReturnRefOfCopy;
21using testing::SaveArg;
22using testing::_;
23
24namespace {
25
26// A DownloadUIController::Delegate that stores the DownloadItem* for the last
27// download that was sent to the UI.
28class TestDelegate : public DownloadUIController::Delegate {
29 public:
30  explicit TestDelegate(base::WeakPtr<content::DownloadItem*> receiver);
31  virtual ~TestDelegate() {}
32
33 private:
34  virtual void NotifyDownloadStarting(content::DownloadItem* item) OVERRIDE;
35
36  base::WeakPtr<content::DownloadItem*> receiver_;
37};
38
39TestDelegate::TestDelegate(base::WeakPtr<content::DownloadItem*> receiver)
40    : receiver_(receiver) {
41}
42
43void TestDelegate::NotifyDownloadStarting(content::DownloadItem* item) {
44  if (receiver_.get())
45    *receiver_ = item;
46}
47
48class DownloadUIControllerTest : public testing::Test {
49 public:
50  DownloadUIControllerTest();
51
52 protected:
53  // testing::Test
54  virtual void SetUp() OVERRIDE;
55
56  // Returns a MockDownloadItem that has AddObserver and RemoveObserver
57  // expectations set up to store the observer in |item_observer_|.
58  scoped_ptr<MockDownloadItem> GetMockDownload();
59
60  // Returns a TestDelegate. Invoking NotifyDownloadStarting on the returned
61  // delegate results in the DownloadItem* being stored in |received_item_|.
62  scoped_ptr<DownloadUIController::Delegate> GetTestDelegate();
63
64  MockDownloadManager* manager() { return manager_.get(); }
65  content::DownloadManager::Observer* manager_observer() {
66    return manager_observer_;
67  }
68  content::DownloadItem::Observer* item_observer() { return item_observer_; }
69  content::DownloadItem* received_item() { return received_item_; }
70
71 private:
72  scoped_refptr<MockDownloadManager> manager_;
73  content::DownloadManager::Observer* manager_observer_;
74  content::DownloadItem::Observer* item_observer_;
75  content::DownloadItem* received_item_;
76
77  base::WeakPtrFactory<content::DownloadItem*> receiver_factory_;
78};
79
80DownloadUIControllerTest::DownloadUIControllerTest()
81    : manager_observer_(NULL),
82      item_observer_(NULL),
83      received_item_(NULL),
84      receiver_factory_(&received_item_) {
85}
86
87void DownloadUIControllerTest::SetUp() {
88  manager_ = new testing::StrictMock<MockDownloadManager>();
89  EXPECT_CALL(*manager_, AddObserver(_))
90      .WillOnce(SaveArg<0>(&manager_observer_));
91  EXPECT_CALL(*manager_, RemoveObserver(_))
92      .WillOnce(Assign(&manager_observer_,
93                       static_cast<content::DownloadManager::Observer*>(NULL)));
94  EXPECT_CALL(*manager_, GetAllDownloads(_));
95}
96
97scoped_ptr<MockDownloadItem> DownloadUIControllerTest::GetMockDownload() {
98  scoped_ptr<MockDownloadItem> item(
99      new testing::StrictMock<MockDownloadItem>());
100  EXPECT_CALL(*item, AddObserver(_))
101      .WillOnce(SaveArg<0>(&item_observer_));
102  EXPECT_CALL(*item, RemoveObserver(_))
103      .WillOnce(Assign(&item_observer_,
104                       static_cast<content::DownloadItem::Observer*>(NULL)));
105  return item.Pass();
106}
107
108scoped_ptr<DownloadUIController::Delegate>
109DownloadUIControllerTest::GetTestDelegate() {
110  scoped_ptr<DownloadUIController::Delegate> delegate(
111      new TestDelegate(receiver_factory_.GetWeakPtr()));
112  return delegate.Pass();
113}
114
115// Normal downloads that are constructed in the IN_PROGRESS state should be
116// presented to the UI when GetTargetFilePath() returns a non-empty path.
117// I.e. once the download target has been determined.
118TEST_F(DownloadUIControllerTest, DownloadUIController_NotifyBasic) {
119  scoped_ptr<MockDownloadItem> item = GetMockDownload();
120  DownloadUIController controller(manager(), GetTestDelegate());
121  EXPECT_CALL(*item, IsInProgress())
122      .WillOnce(Return(true));
123  EXPECT_CALL(*item, GetTargetFilePath())
124      .WillOnce(ReturnRefOfCopy(base::FilePath()));
125  EXPECT_CALL(*item, IsComplete())
126      .Times(AnyNumber())
127      .WillRepeatedly(Return(false));
128
129  ASSERT_TRUE(manager_observer());
130  manager_observer()->OnDownloadCreated(manager(), item.get());
131
132  // The destination for the download hasn't been determined yet. It should not
133  // be displayed.
134  EXPECT_FALSE(received_item());
135  ASSERT_TRUE(item_observer());
136
137  // Once the destination has been determined, then it should be displayed.
138  EXPECT_CALL(*item, GetTargetFilePath())
139      .WillOnce(ReturnRefOfCopy(base::FilePath(FILE_PATH_LITERAL("foo"))));
140  item_observer()->OnDownloadUpdated(item.get());
141
142  EXPECT_EQ(static_cast<content::DownloadItem*>(item.get()), received_item());
143}
144
145// Downloads that have a target path on creation and are in the IN_PROGRESS
146// state should be displayed in the UI immediately without requiring an
147// additional OnDownloadUpdated() notification.
148TEST_F(DownloadUIControllerTest, DownloadUIController_NotifyReadyOnCreate) {
149  scoped_ptr<MockDownloadItem> item = GetMockDownload();
150  DownloadUIController controller(manager(), GetTestDelegate());
151  EXPECT_CALL(*item, IsInProgress())
152      .WillOnce(Return(true));
153  EXPECT_CALL(*item, GetTargetFilePath())
154      .WillOnce(ReturnRefOfCopy(base::FilePath(FILE_PATH_LITERAL("foo"))));
155  EXPECT_CALL(*item, IsComplete())
156      .Times(AnyNumber())
157      .WillRepeatedly(Return(false));
158
159  ASSERT_TRUE(manager_observer());
160  manager_observer()->OnDownloadCreated(manager(), item.get());
161  EXPECT_EQ(static_cast<content::DownloadItem*>(item.get()), received_item());
162}
163
164// History downloads (downloads that are not in IN_PROGRESS on create) should
165// not be displayed on the shelf.
166TEST_F(DownloadUIControllerTest, DownloadUIController_NoNotifyHistory) {
167  scoped_ptr<MockDownloadItem> item = GetMockDownload();
168  DownloadUIController controller(manager(), GetTestDelegate());
169  EXPECT_CALL(*item, IsInProgress())
170      .WillOnce(Return(false));
171  EXPECT_CALL(*item, IsComplete())
172      .Times(AnyNumber())
173      .WillRepeatedly(Return(true));
174
175  ASSERT_TRUE(manager_observer());
176  manager_observer()->OnDownloadCreated(manager(), item.get());
177  EXPECT_FALSE(received_item());
178
179  item_observer()->OnDownloadUpdated(item.get());
180  EXPECT_FALSE(received_item());
181}
182
183} // namespace
184