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 15 using content::MockDownloadItem; 16 using content::MockDownloadManager; 17 using testing::AnyNumber; 18 using testing::Assign; 19 using testing::Return; 20 using testing::ReturnRefOfCopy; 21 using testing::SaveArg; 22 using testing::_; 23 24 namespace { 25 26 // A DownloadUIController::Delegate that stores the DownloadItem* for the last 27 // download that was sent to the UI. 28 class 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 39 TestDelegate::TestDelegate(base::WeakPtr<content::DownloadItem*> receiver) 40 : receiver_(receiver) { 41 } 42 43 void TestDelegate::NotifyDownloadStarting(content::DownloadItem* item) { 44 if (receiver_.get()) 45 *receiver_ = item; 46 } 47 48 class 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_ptr<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 80 DownloadUIControllerTest::DownloadUIControllerTest() 81 : manager_observer_(NULL), 82 item_observer_(NULL), 83 received_item_(NULL), 84 receiver_factory_(&received_item_) { 85 } 86 87 void DownloadUIControllerTest::SetUp() { 88 manager_.reset(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 97 scoped_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 108 scoped_ptr<DownloadUIController::Delegate> 109 DownloadUIControllerTest::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. 118 TEST_F(DownloadUIControllerTest, DownloadUIController_NotifyBasic) { 119 scoped_ptr<MockDownloadItem> item = GetMockDownload(); 120 DownloadUIController controller(manager(), GetTestDelegate()); 121 EXPECT_CALL(*item, GetTargetFilePath()) 122 .WillOnce(ReturnRefOfCopy(base::FilePath())); 123 EXPECT_CALL(*item, GetState()) 124 .WillRepeatedly(Return(content::DownloadItem::IN_PROGRESS)); 125 126 ASSERT_TRUE(manager_observer()); 127 manager_observer()->OnDownloadCreated(manager(), item.get()); 128 129 // The destination for the download hasn't been determined yet. It should not 130 // be displayed. 131 EXPECT_FALSE(received_item()); 132 ASSERT_TRUE(item_observer()); 133 134 // Once the destination has been determined, then it should be displayed. 135 EXPECT_CALL(*item, GetTargetFilePath()) 136 .WillOnce(ReturnRefOfCopy(base::FilePath(FILE_PATH_LITERAL("foo")))); 137 item_observer()->OnDownloadUpdated(item.get()); 138 139 EXPECT_EQ(static_cast<content::DownloadItem*>(item.get()), received_item()); 140 } 141 142 // Downloads that have a target path on creation and are in the IN_PROGRESS 143 // state should be displayed in the UI immediately without requiring an 144 // additional OnDownloadUpdated() notification. 145 TEST_F(DownloadUIControllerTest, DownloadUIController_NotifyReadyOnCreate) { 146 scoped_ptr<MockDownloadItem> item = GetMockDownload(); 147 DownloadUIController controller(manager(), GetTestDelegate()); 148 EXPECT_CALL(*item, GetTargetFilePath()) 149 .WillOnce(ReturnRefOfCopy(base::FilePath(FILE_PATH_LITERAL("foo")))); 150 EXPECT_CALL(*item, GetState()) 151 .WillRepeatedly(Return(content::DownloadItem::IN_PROGRESS)); 152 153 ASSERT_TRUE(manager_observer()); 154 manager_observer()->OnDownloadCreated(manager(), item.get()); 155 EXPECT_EQ(static_cast<content::DownloadItem*>(item.get()), received_item()); 156 } 157 158 // History downloads (downloads that are not in IN_PROGRESS on create) should 159 // not be displayed on the shelf. 160 TEST_F(DownloadUIControllerTest, DownloadUIController_NoNotifyHistory) { 161 scoped_ptr<MockDownloadItem> item = GetMockDownload(); 162 DownloadUIController controller(manager(), GetTestDelegate()); 163 EXPECT_CALL(*item, GetState()) 164 .WillRepeatedly(Return(content::DownloadItem::COMPLETE)); 165 166 ASSERT_TRUE(manager_observer()); 167 manager_observer()->OnDownloadCreated(manager(), item.get()); 168 EXPECT_FALSE(received_item()); 169 170 item_observer()->OnDownloadUpdated(item.get()); 171 EXPECT_FALSE(received_item()); 172 } 173 174 } // namespace 175