OLD | NEW |
(Empty) | |
| 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 #import <Cocoa/Cocoa.h> |
| 6 |
| 7 #import "base/memory/scoped_nsobject.h" |
| 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "chrome/browser/download/download_shelf.h" |
| 10 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h" |
| 11 #import "chrome/browser/ui/cocoa/download/download_item_controller.h" |
| 12 #import "chrome/browser/ui/cocoa/download/download_shelf_controller.h" |
| 13 #import "chrome/browser/ui/cocoa/view_resizer_pong.h" |
| 14 #include "content/public/test/mock_download_item.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" |
| 16 #include "testing/platform_test.h" |
| 17 #import "third_party/ocmock/OCMock/OCMock.h" |
| 18 #import "third_party/ocmock/gtest_support.h" |
| 19 |
| 20 using ::testing::Return; |
| 21 using ::testing::AnyNumber; |
| 22 |
| 23 // Wraps a content::MockDownloadItem so it can be retained by the mock |
| 24 // DownloadItemController. |
| 25 @interface WrappedMockDownloadItem : NSObject { |
| 26 @private |
| 27 scoped_ptr<content::MockDownloadItem> download_; |
| 28 } |
| 29 - (id)initWithMockDownload:(scoped_ptr<content::MockDownloadItem>)download; |
| 30 - (content::DownloadItem*)download; |
| 31 - (content::MockDownloadItem*)mockDownload; |
| 32 @end |
| 33 |
| 34 @implementation WrappedMockDownloadItem |
| 35 - (id)initWithMockDownload:(scoped_ptr<content::MockDownloadItem>)download { |
| 36 if ((self = [super init])) { |
| 37 download_ = download.Pass(); |
| 38 } |
| 39 return self; |
| 40 } |
| 41 |
| 42 - (content::DownloadItem*)download { |
| 43 return download_.get(); |
| 44 } |
| 45 |
| 46 - (content::MockDownloadItem*)mockDownload { |
| 47 return download_.get(); |
| 48 } |
| 49 @end |
| 50 |
| 51 // Test method for accessing the wrapped MockDownloadItem. |
| 52 @interface DownloadItemController (DownloadShelfControllerTest) { |
| 53 } |
| 54 - (WrappedMockDownloadItem*)wrappedMockDownload; |
| 55 @end |
| 56 |
| 57 @implementation DownloadItemController (DownloadShelfControllerTest) |
| 58 - (WrappedMockDownloadItem*)wrappedMockDownload { |
| 59 return nil; |
| 60 } |
| 61 @end |
| 62 |
| 63 // Subclass of the DownloadShelfController to override scheduleAutoClose and |
| 64 // cancelAutoClose. During regular operation, a scheduled autoClose waits for 5 |
| 65 // seconds before closing the shelf (unless it is cancelled during this |
| 66 // time). For testing purposes, we count the number of invocations of |
| 67 // {schedule,cancel}AutoClose instead of actually scheduling and cancelling. |
| 68 @interface CountingDownloadShelfController : DownloadShelfController { |
| 69 @public |
| 70 int scheduleAutoCloseCount_; |
| 71 int cancelAutoCloseCount_; |
| 72 } |
| 73 @end |
| 74 |
| 75 @implementation CountingDownloadShelfController |
| 76 |
| 77 -(void)scheduleAutoClose { |
| 78 ++scheduleAutoCloseCount_; |
| 79 } |
| 80 |
| 81 -(void)cancelAutoClose { |
| 82 ++cancelAutoCloseCount_; |
| 83 } |
| 84 @end |
| 85 |
| 86 namespace { |
| 87 |
| 88 class DownloadShelfControllerTest : public CocoaProfileTest { |
| 89 public: |
| 90 virtual void SetUp() OVERRIDE { |
| 91 CocoaProfileTest::SetUp(); |
| 92 ASSERT_TRUE(browser()); |
| 93 |
| 94 resize_delegate_.reset([[ViewResizerPong alloc] init]); |
| 95 shelf_.reset([[CountingDownloadShelfController alloc] |
| 96 initWithBrowser:browser() |
| 97 resizeDelegate:resize_delegate_.get()]); |
| 98 EXPECT_TRUE([shelf_ view]); |
| 99 [[test_window() contentView] addSubview:[shelf_ view]]; |
| 100 } |
| 101 |
| 102 virtual void TearDown() OVERRIDE { |
| 103 [shelf_ exiting]; |
| 104 shelf_.reset(); |
| 105 CocoaProfileTest::TearDown(); |
| 106 } |
| 107 |
| 108 protected: |
| 109 id CreateItemController(); |
| 110 |
| 111 scoped_nsobject<CountingDownloadShelfController> shelf_; |
| 112 scoped_nsobject<ViewResizerPong> resize_delegate_; |
| 113 }; |
| 114 |
| 115 id DownloadShelfControllerTest::CreateItemController() { |
| 116 scoped_ptr<content::MockDownloadItem> download( |
| 117 new ::testing::NiceMock<content::MockDownloadItem>); |
| 118 ON_CALL(*download.get(), GetOpened()) |
| 119 .WillByDefault(Return(false)); |
| 120 ON_CALL(*download.get(), IsInProgress()) |
| 121 .WillByDefault(Return(true)); |
| 122 |
| 123 scoped_nsobject<WrappedMockDownloadItem> wrappedMockDownload( |
| 124 [[WrappedMockDownloadItem alloc] initWithMockDownload:download.Pass()]); |
| 125 |
| 126 id item_controller = |
| 127 [OCMockObject mockForClass:[DownloadItemController class]]; |
| 128 scoped_nsobject<NSView> view([[NSView alloc] initWithFrame:NSZeroRect]); |
| 129 [[[item_controller stub] andCall:@selector(download) |
| 130 onObject:wrappedMockDownload.get()] download]; |
| 131 [[item_controller stub] updateVisibility:[OCMArg any]]; |
| 132 [[[item_controller stub] |
| 133 andReturnValue:[NSValue valueWithSize:NSMakeSize(10,10)]] preferredSize]; |
| 134 [[[item_controller stub] andReturn:view.get()] view]; |
| 135 [[[item_controller stub] |
| 136 andReturn:wrappedMockDownload.get()] wrappedMockDownload]; |
| 137 return [item_controller retain]; |
| 138 } |
| 139 |
| 140 TEST_VIEW(DownloadShelfControllerTest, [shelf_ view]); |
| 141 |
| 142 // Removing the last download from the shelf should cause it to close |
| 143 // immediately. |
| 144 TEST_F(DownloadShelfControllerTest, AddAndRemoveDownload) { |
| 145 scoped_nsobject<DownloadItemController> item(CreateItemController()); |
| 146 [shelf_ showDownloadShelf:YES |
| 147 isUserAction:NO]; |
| 148 EXPECT_TRUE([shelf_ isVisible]); |
| 149 EXPECT_TRUE([shelf_ bridge]->IsShowing()); |
| 150 [shelf_ add:item]; |
| 151 [shelf_ remove:item]; |
| 152 EXPECT_FALSE([shelf_ isVisible]); |
| 153 EXPECT_FALSE([shelf_ bridge]->IsShowing()); |
| 154 // The shelf should be closed without scheduling an autoClose. |
| 155 EXPECT_EQ(0, shelf_.get()->scheduleAutoCloseCount_); |
| 156 } |
| 157 |
| 158 // Test that the shelf doesn't close automatically after a removal if there are |
| 159 // active download items still on the shelf. |
| 160 TEST_F(DownloadShelfControllerTest, AddAndRemoveWithActiveItem) { |
| 161 scoped_nsobject<DownloadItemController> item1(CreateItemController()); |
| 162 scoped_nsobject<DownloadItemController> item2(CreateItemController()); |
| 163 [shelf_ showDownloadShelf:YES |
| 164 isUserAction:NO]; |
| 165 EXPECT_TRUE([shelf_ isVisible]); |
| 166 [shelf_ add:item1.get()]; |
| 167 [shelf_ add:item2.get()]; |
| 168 [shelf_ remove:item1.get()]; |
| 169 EXPECT_TRUE([shelf_ isVisible]); |
| 170 [shelf_ remove:item2.get()]; |
| 171 EXPECT_FALSE([shelf_ isVisible]); |
| 172 EXPECT_EQ(0, shelf_.get()->scheduleAutoCloseCount_); |
| 173 } |
| 174 |
| 175 // DownloadShelf::Unhide() should cause the shelf to be displayed if there are |
| 176 // active downloads on it. |
| 177 TEST_F(DownloadShelfControllerTest, HideAndUnhide) { |
| 178 scoped_nsobject<DownloadItemController> item(CreateItemController()); |
| 179 [shelf_ showDownloadShelf:YES |
| 180 isUserAction:NO]; |
| 181 EXPECT_TRUE([shelf_ isVisible]); |
| 182 [shelf_ add:item.get()]; |
| 183 [shelf_ bridge]->Hide(); |
| 184 EXPECT_FALSE([shelf_ isVisible]); |
| 185 [shelf_ bridge]->Unhide(); |
| 186 EXPECT_TRUE([shelf_ isVisible]); |
| 187 [shelf_ remove:item.get()]; |
| 188 EXPECT_FALSE([shelf_ isVisible]); |
| 189 } |
| 190 |
| 191 // DownloadShelf::Unhide() shouldn't cause the shelf to be displayed if all |
| 192 // active downloads are removed from the shelf while the shelf was hidden. |
| 193 TEST_F(DownloadShelfControllerTest, HideAutocloseUnhide) { |
| 194 scoped_nsobject<DownloadItemController> item(CreateItemController()); |
| 195 [shelf_ showDownloadShelf:YES |
| 196 isUserAction:NO]; |
| 197 EXPECT_TRUE([shelf_ isVisible]); |
| 198 [shelf_ add:item.get()]; |
| 199 [shelf_ bridge]->Hide(); |
| 200 EXPECT_FALSE([shelf_ isVisible]); |
| 201 [shelf_ remove:item.get()]; |
| 202 EXPECT_FALSE([shelf_ isVisible]); |
| 203 [shelf_ bridge]->Unhide(); |
| 204 EXPECT_FALSE([shelf_ isVisible]); |
| 205 } |
| 206 |
| 207 // Test of autoclosing behavior after opening a download item. The mouse is on |
| 208 // the download shelf at the time the autoclose is scheduled. |
| 209 TEST_F(DownloadShelfControllerTest, AutoCloseAfterOpenWithMouseInShelf) { |
| 210 scoped_nsobject<DownloadItemController> item(CreateItemController()); |
| 211 [shelf_ showDownloadShelf:YES |
| 212 isUserAction:NO]; |
| 213 EXPECT_TRUE([shelf_ isVisible]); |
| 214 [shelf_ add:item.get()]; |
| 215 |
| 216 // The mouse enters the shelf. |
| 217 [shelf_ mouseEntered:nil]; |
| 218 EXPECT_EQ(0, shelf_.get()->scheduleAutoCloseCount_); |
| 219 |
| 220 // The download opens. |
| 221 EXPECT_CALL(*[[item wrappedMockDownload] mockDownload], GetOpened()) |
| 222 .WillRepeatedly(Return(true)); |
| 223 [shelf_ downloadWasOpened:item.get()]; |
| 224 |
| 225 // The shelf should now be waiting for the mouse to exit. autoClose should not |
| 226 // be scheduled yet. |
| 227 EXPECT_TRUE([shelf_ isVisible]); |
| 228 EXPECT_EQ(0, shelf_.get()->scheduleAutoCloseCount_); |
| 229 |
| 230 // The mouse exits the shelf. autoClose should be scheduled now. |
| 231 [shelf_ mouseExited:nil]; |
| 232 EXPECT_EQ(1, shelf_.get()->scheduleAutoCloseCount_); |
| 233 EXPECT_EQ(0, shelf_.get()->cancelAutoCloseCount_); |
| 234 |
| 235 // The mouse enters the shelf again. The autoClose should be cancelled. |
| 236 [shelf_ mouseEntered:nil]; |
| 237 EXPECT_EQ(1, shelf_.get()->scheduleAutoCloseCount_); |
| 238 EXPECT_EQ(1, shelf_.get()->cancelAutoCloseCount_); |
| 239 } |
| 240 |
| 241 // Test of autoclosing behavior after opening a download item. |
| 242 TEST_F(DownloadShelfControllerTest, AutoCloseAfterOpenWithMouseOffShelf) { |
| 243 scoped_nsobject<DownloadItemController> item(CreateItemController()); |
| 244 [shelf_ showDownloadShelf:YES |
| 245 isUserAction:NO]; |
| 246 EXPECT_TRUE([shelf_ isVisible]); |
| 247 [shelf_ add:item.get()]; |
| 248 |
| 249 // The download is opened. |
| 250 EXPECT_CALL(*[[item wrappedMockDownload] mockDownload], GetOpened()) |
| 251 .WillRepeatedly(Return(true)); |
| 252 [shelf_ downloadWasOpened:item.get()]; |
| 253 |
| 254 // The shelf should be closed immediately since the mouse is not over the |
| 255 // shelf. |
| 256 EXPECT_FALSE([shelf_ isVisible]); |
| 257 } |
| 258 |
| 259 } // namespace |
OLD | NEW |