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