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 "base/compiler_specific.h" 6 #include "base/memory/scoped_ptr.h" 7 #include "base/message_loop/message_loop.h" 8 #include "base/run_loop.h" 9 #include "chrome/browser/chrome_notification_types.h" 10 #include "chrome/browser/download/download_item_model.h" 11 #include "chrome/browser/download/download_service.h" 12 #include "chrome/browser/download/download_service_factory.h" 13 #include "chrome/browser/download/test_download_shelf.h" 14 #include "chrome/test/base/testing_profile.h" 15 #include "content/public/browser/notification_service.h" 16 #include "content/public/test/mock_download_item.h" 17 #include "content/public/test/mock_download_manager.h" 18 #include "content/public/test/test_browser_thread.h" 19 #include "extensions/common/extension.h" 20 #include "testing/gmock/include/gmock/gmock.h" 21 #include "testing/gtest/include/gtest/gtest.h" 22 23 using ::testing::Return; 24 using ::testing::ReturnRefOfCopy; 25 using ::testing::SaveArg; 26 using ::testing::_; 27 using content::DownloadItem; 28 29 namespace { 30 31 KeyedService* CreateDownloadService(content::BrowserContext* context) { 32 return new DownloadService(Profile::FromBrowserContext(context)); 33 } 34 35 class DownloadShelfTest : public testing::Test { 36 public: 37 DownloadShelfTest(); 38 39 protected: 40 content::MockDownloadItem* download_item() { 41 return download_item_.get(); 42 } 43 content::MockDownloadManager* download_manager() { 44 return download_manager_.get(); 45 } 46 TestDownloadShelf* shelf() { 47 return &shelf_; 48 } 49 Profile* profile() { return profile_.get(); } 50 51 virtual void SetUp() OVERRIDE { 52 DownloadServiceFactory::GetInstance()->SetTestingFactory( 53 profile(), &CreateDownloadService); 54 } 55 56 virtual void TearDown() OVERRIDE { 57 DownloadServiceFactory::GetInstance()->SetTestingFactory( 58 profile(), NULL); 59 } 60 61 private: 62 scoped_ptr<content::MockDownloadItem> GetInProgressMockDownload(); 63 64 base::MessageLoopForUI message_loop_; 65 content::TestBrowserThread ui_thread_; 66 scoped_ptr<content::MockDownloadItem> download_item_; 67 scoped_ptr<content::MockDownloadManager> download_manager_; 68 TestDownloadShelf shelf_; 69 scoped_ptr<TestingProfile> profile_; 70 }; 71 72 DownloadShelfTest::DownloadShelfTest() 73 : ui_thread_(content::BrowserThread::UI, &message_loop_), 74 profile_(new TestingProfile()) { 75 download_item_.reset(new ::testing::NiceMock<content::MockDownloadItem>()); 76 ON_CALL(*download_item_, GetAutoOpened()).WillByDefault(Return(false)); 77 ON_CALL(*download_item_, GetMimeType()).WillByDefault(Return("text/plain")); 78 ON_CALL(*download_item_, GetOpenWhenComplete()).WillByDefault(Return(false)); 79 ON_CALL(*download_item_, GetTargetDisposition()) 80 .WillByDefault(Return(DownloadItem::TARGET_DISPOSITION_OVERWRITE)); 81 ON_CALL(*download_item_, GetURL()) 82 .WillByDefault(ReturnRefOfCopy(GURL("http://example.com/foo"))); 83 ON_CALL(*download_item_, GetState()) 84 .WillByDefault(Return(DownloadItem::IN_PROGRESS)); 85 ON_CALL(*download_item_, IsTemporary()).WillByDefault(Return(false)); 86 ON_CALL(*download_item_, ShouldOpenFileBasedOnExtension()) 87 .WillByDefault(Return(false)); 88 ON_CALL(*download_item_, GetBrowserContext()) 89 .WillByDefault(Return(profile())); 90 91 download_manager_.reset( 92 new ::testing::NiceMock<content::MockDownloadManager>()); 93 ON_CALL(*download_manager_, GetDownload(_)) 94 .WillByDefault(Return(download_item_.get())); 95 ON_CALL(*download_manager_, GetBrowserContext()) 96 .WillByDefault(Return(profile())); 97 98 shelf_.set_download_manager(download_manager_.get()); 99 } 100 101 } // namespace 102 103 TEST_F(DownloadShelfTest, ClosesShelfWhenHidden) { 104 shelf()->Show(); 105 EXPECT_TRUE(shelf()->IsShowing()); 106 shelf()->Hide(); 107 EXPECT_FALSE(shelf()->IsShowing()); 108 shelf()->Unhide(); 109 EXPECT_TRUE(shelf()->IsShowing()); 110 } 111 112 TEST_F(DownloadShelfTest, CloseWhileHiddenPreventsShowOnUnhide) { 113 shelf()->Show(); 114 shelf()->Hide(); 115 shelf()->Close(DownloadShelf::AUTOMATIC); 116 shelf()->Unhide(); 117 EXPECT_FALSE(shelf()->IsShowing()); 118 } 119 120 TEST_F(DownloadShelfTest, UnhideDoesntShowIfNotShownOnHide) { 121 shelf()->Hide(); 122 shelf()->Unhide(); 123 EXPECT_FALSE(shelf()->IsShowing()); 124 } 125 126 TEST_F(DownloadShelfTest, AddDownloadWhileHiddenUnhides) { 127 shelf()->Show(); 128 shelf()->Hide(); 129 shelf()->AddDownload(download_item()); 130 EXPECT_TRUE(shelf()->IsShowing()); 131 } 132 133 TEST_F(DownloadShelfTest, AddDownloadWhileHiddenUnhidesAndShows) { 134 shelf()->Hide(); 135 shelf()->AddDownload(download_item()); 136 EXPECT_TRUE(shelf()->IsShowing()); 137 } 138 139 // Normal downloads should be added synchronously and cause the shelf to show. 140 TEST_F(DownloadShelfTest, AddNormalDownload) { 141 EXPECT_FALSE(shelf()->IsShowing()); 142 shelf()->AddDownload(download_item()); 143 EXPECT_TRUE(shelf()->did_add_download()); 144 EXPECT_TRUE(shelf()->IsShowing()); 145 } 146 147 // Add a transient download. It should not be added immediately. Instead it 148 // should be added after a delay. For testing, the delay is set to 0 seconds. So 149 // the download should be added once the message loop is flushed. 150 TEST_F(DownloadShelfTest, AddDelayedDownload) { 151 EXPECT_CALL(*download_item(), ShouldOpenFileBasedOnExtension()) 152 .WillRepeatedly(Return(true)); 153 ASSERT_TRUE(DownloadItemModel(download_item()) 154 .ShouldRemoveFromShelfWhenComplete()); 155 shelf()->AddDownload(download_item()); 156 157 EXPECT_FALSE(shelf()->did_add_download()); 158 EXPECT_FALSE(shelf()->IsShowing()); 159 160 base::RunLoop run_loop; 161 run_loop.RunUntilIdle(); 162 163 EXPECT_TRUE(shelf()->did_add_download()); 164 EXPECT_TRUE(shelf()->IsShowing()); 165 } 166 167 // Add a transient download that completes before the delay. It should not be 168 // displayed on the shelf. 169 TEST_F(DownloadShelfTest, AddDelayedCompletedDownload) { 170 EXPECT_CALL(*download_item(), ShouldOpenFileBasedOnExtension()) 171 .WillRepeatedly(Return(true)); 172 ASSERT_TRUE(DownloadItemModel(download_item()) 173 .ShouldRemoveFromShelfWhenComplete()); 174 shelf()->AddDownload(download_item()); 175 176 EXPECT_FALSE(shelf()->did_add_download()); 177 EXPECT_FALSE(shelf()->IsShowing()); 178 179 EXPECT_CALL(*download_item(), GetState()) 180 .WillRepeatedly(Return(DownloadItem::COMPLETE)); 181 EXPECT_CALL(*download_item(), GetAutoOpened()) 182 .WillRepeatedly(Return(true)); 183 184 base::RunLoop run_loop; 185 run_loop.RunUntilIdle(); 186 187 EXPECT_FALSE(shelf()->did_add_download()); 188 EXPECT_FALSE(shelf()->IsShowing()); 189 } 190 191 // Add a transient download that completes and becomes non-transient before the 192 // delay. It should be displayed on the shelf even though it is complete. 193 TEST_F(DownloadShelfTest, AddDelayedCompleteNonTransientDownload) { 194 EXPECT_CALL(*download_item(), ShouldOpenFileBasedOnExtension()) 195 .WillRepeatedly(Return(true)); 196 ASSERT_TRUE(DownloadItemModel(download_item()) 197 .ShouldRemoveFromShelfWhenComplete()); 198 shelf()->AddDownload(download_item()); 199 200 EXPECT_FALSE(shelf()->did_add_download()); 201 EXPECT_FALSE(shelf()->IsShowing()); 202 203 EXPECT_CALL(*download_item(), GetState()) 204 .WillRepeatedly(Return(DownloadItem::COMPLETE)); 205 EXPECT_CALL(*download_item(), ShouldOpenFileBasedOnExtension()) 206 .WillRepeatedly(Return(false)); 207 ASSERT_FALSE(DownloadItemModel(download_item()) 208 .ShouldRemoveFromShelfWhenComplete()); 209 210 base::RunLoop run_loop; 211 run_loop.RunUntilIdle(); 212 213 EXPECT_TRUE(shelf()->did_add_download()); 214 EXPECT_TRUE(shelf()->IsShowing()); 215 } 216