[Metrics] Make MetricsStateManager take a callback param to check if UMA is enabled.
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / download / download_shelf_controller_unittest.mm
blob8ce96cad72aa9bec077c9012862965e706ca1517
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.
5 #import <Cocoa/Cocoa.h>
7 #import "base/mac/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"
20 using ::testing::Return;
21 using ::testing::AnyNumber;
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_;
29 - (id)initWithMockDownload:(scoped_ptr<content::MockDownloadItem>)download;
30 - (content::DownloadItem*)download;
31 - (content::MockDownloadItem*)mockDownload;
32 @end
34 @implementation WrappedMockDownloadItem
35 - (id)initWithMockDownload:(scoped_ptr<content::MockDownloadItem>)download {
36   if ((self = [super init])) {
37     download_ = download.Pass();
38   }
39   return self;
42 - (content::DownloadItem*)download {
43   return download_.get();
46 - (content::MockDownloadItem*)mockDownload {
47   return download_.get();
49 @end
51 // Test method for accessing the wrapped MockDownloadItem.
52 @interface DownloadItemController (DownloadShelfControllerTest) {
54 - (WrappedMockDownloadItem*)wrappedMockDownload;
55 @end
57 @implementation DownloadItemController (DownloadShelfControllerTest)
58 - (WrappedMockDownloadItem*)wrappedMockDownload {
59   return nil;
61 @end
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_;
73 @end
75 @implementation CountingDownloadShelfController
77 -(void)scheduleAutoClose {
78   ++scheduleAutoCloseCount_;
81 -(void)cancelAutoClose {
82   ++cancelAutoCloseCount_;
84 @end
86 namespace {
88 class DownloadShelfControllerTest : public CocoaProfileTest {
89  public:
90   virtual void SetUp() OVERRIDE {
91     CocoaProfileTest::SetUp();
92     ASSERT_TRUE(browser());
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   }
102   virtual void TearDown() OVERRIDE {
103     if (shelf_.get()) {
104       [shelf_ exiting];
105       shelf_.reset();
106     }
107     CocoaProfileTest::TearDown();
108   }
110  protected:
111   id CreateItemController();
113   base::scoped_nsobject<CountingDownloadShelfController> shelf_;
114   base::scoped_nsobject<ViewResizerPong> resize_delegate_;
117 id DownloadShelfControllerTest::CreateItemController() {
118   scoped_ptr<content::MockDownloadItem> download(
119       new ::testing::NiceMock<content::MockDownloadItem>);
120   ON_CALL(*download.get(), GetOpened())
121       .WillByDefault(Return(false));
122   ON_CALL(*download.get(), GetState())
123       .WillByDefault(Return(content::DownloadItem::IN_PROGRESS));
125   base::scoped_nsobject<WrappedMockDownloadItem> wrappedMockDownload(
126       [[WrappedMockDownloadItem alloc] initWithMockDownload:download.Pass()]);
128   id item_controller =
129       [OCMockObject mockForClass:[DownloadItemController class]];
130   base::scoped_nsobject<NSView> view([[NSView alloc] initWithFrame:NSZeroRect]);
131   [[[item_controller stub] andCall:@selector(download)
132                           onObject:wrappedMockDownload.get()] download];
133   [[item_controller stub] updateVisibility:[OCMArg any]];
134   [[[item_controller stub]
135      andReturnValue:[NSValue valueWithSize:NSMakeSize(10,10)]] preferredSize];
136   [[[item_controller stub] andReturn:view.get()] view];
137   [[[item_controller stub]
138      andReturn:wrappedMockDownload.get()] wrappedMockDownload];
139   return [item_controller retain];
142 TEST_VIEW(DownloadShelfControllerTest, [shelf_ view]);
144 // Removing the last download from the shelf should cause it to close
145 // immediately.
146 TEST_F(DownloadShelfControllerTest, AddAndRemoveDownload) {
147   base::scoped_nsobject<DownloadItemController> item(CreateItemController());
148   [shelf_ showDownloadShelf:YES
149                isUserAction:NO];
150   EXPECT_TRUE([shelf_ isVisible]);
151   EXPECT_TRUE([shelf_ bridge]->IsShowing());
152   [shelf_ add:item];
153   [shelf_ remove:item];
154   EXPECT_FALSE([shelf_ isVisible]);
155   EXPECT_FALSE([shelf_ bridge]->IsShowing());
156   // The shelf should be closed without scheduling an autoClose.
157   EXPECT_EQ(0, shelf_.get()->scheduleAutoCloseCount_);
160 // Test that the shelf doesn't close automatically after a removal if there are
161 // active download items still on the shelf.
162 TEST_F(DownloadShelfControllerTest, AddAndRemoveWithActiveItem) {
163   base::scoped_nsobject<DownloadItemController> item1(CreateItemController());
164   base::scoped_nsobject<DownloadItemController> item2(CreateItemController());
165   [shelf_ showDownloadShelf:YES
166                isUserAction:NO];
167   EXPECT_TRUE([shelf_ isVisible]);
168   [shelf_ add:item1.get()];
169   [shelf_ add:item2.get()];
170   [shelf_ remove:item1.get()];
171   EXPECT_TRUE([shelf_ isVisible]);
172   [shelf_ remove:item2.get()];
173   EXPECT_FALSE([shelf_ isVisible]);
174   EXPECT_EQ(0, shelf_.get()->scheduleAutoCloseCount_);
177 // DownloadShelf::Unhide() should cause the shelf to be displayed if there are
178 // active downloads on it.
179 TEST_F(DownloadShelfControllerTest, HideAndUnhide) {
180   base::scoped_nsobject<DownloadItemController> item(CreateItemController());
181   [shelf_ showDownloadShelf:YES
182                isUserAction:NO];
183   EXPECT_TRUE([shelf_ isVisible]);
184   [shelf_ add:item.get()];
185   [shelf_ bridge]->Hide();
186   EXPECT_FALSE([shelf_ isVisible]);
187   [shelf_ bridge]->Unhide();
188   EXPECT_TRUE([shelf_ isVisible]);
189   [shelf_ remove:item.get()];
190   EXPECT_FALSE([shelf_ isVisible]);
193 // DownloadShelf::Unhide() shouldn't cause the shelf to be displayed if all
194 // active downloads are removed from the shelf while the shelf was hidden.
195 TEST_F(DownloadShelfControllerTest, HideAutocloseUnhide) {
196   base::scoped_nsobject<DownloadItemController> item(CreateItemController());
197   [shelf_ showDownloadShelf:YES
198                isUserAction:NO];
199   EXPECT_TRUE([shelf_ isVisible]);
200   [shelf_ add:item.get()];
201   [shelf_ bridge]->Hide();
202   EXPECT_FALSE([shelf_ isVisible]);
203   [shelf_ remove:item.get()];
204   EXPECT_FALSE([shelf_ isVisible]);
205   [shelf_ bridge]->Unhide();
206   EXPECT_FALSE([shelf_ isVisible]);
209 // Test of autoclosing behavior after opening a download item. The mouse is on
210 // the download shelf at the time the autoclose is scheduled.
211 TEST_F(DownloadShelfControllerTest, AutoCloseAfterOpenWithMouseInShelf) {
212   base::scoped_nsobject<DownloadItemController> item(CreateItemController());
213   [shelf_ showDownloadShelf:YES
214                isUserAction:NO];
215   EXPECT_TRUE([shelf_ isVisible]);
216   [shelf_ add:item.get()];
217   // Expect 2 cancelAutoClose calls: From the showDownloadShelf: call and the
218   // add: call.
219   EXPECT_EQ(2, shelf_.get()->cancelAutoCloseCount_);
220   shelf_.get()->cancelAutoCloseCount_ = 0;
222   // The mouse enters the shelf.
223   [shelf_ mouseEntered:nil];
224   EXPECT_EQ(0, shelf_.get()->scheduleAutoCloseCount_);
226   // The download opens.
227   EXPECT_CALL(*[[item wrappedMockDownload] mockDownload], GetOpened())
228       .WillRepeatedly(Return(true));
229   [shelf_ downloadWasOpened:item.get()];
231   // The shelf should now be waiting for the mouse to exit.
232   EXPECT_TRUE([shelf_ isVisible]);
233   EXPECT_EQ(0, shelf_.get()->scheduleAutoCloseCount_);
234   EXPECT_EQ(0, shelf_.get()->cancelAutoCloseCount_);
236   // The mouse exits the shelf. autoClose should be scheduled now.
237   [shelf_ mouseExited:nil];
238   EXPECT_EQ(1, shelf_.get()->scheduleAutoCloseCount_);
239   EXPECT_EQ(0, shelf_.get()->cancelAutoCloseCount_);
241   // The mouse enters the shelf again. The autoClose should be cancelled.
242   [shelf_ mouseEntered:nil];
243   EXPECT_EQ(1, shelf_.get()->scheduleAutoCloseCount_);
244   EXPECT_EQ(1, shelf_.get()->cancelAutoCloseCount_);
247 // Test of autoclosing behavior after opening a download item.
248 TEST_F(DownloadShelfControllerTest, AutoCloseAfterOpenWithMouseOffShelf) {
249   base::scoped_nsobject<DownloadItemController> item(CreateItemController());
250   [shelf_ showDownloadShelf:YES
251                isUserAction:NO];
252   EXPECT_TRUE([shelf_ isVisible]);
253   [shelf_ add:item.get()];
255   // The download is opened.
256   EXPECT_CALL(*[[item wrappedMockDownload] mockDownload], GetOpened())
257       .WillRepeatedly(Return(true));
258   [shelf_ downloadWasOpened:item.get()];
260   // The shelf should be closed immediately since the mouse is not over the
261   // shelf.
262   EXPECT_FALSE([shelf_ isVisible]);
265 // Test that if the shelf is closed while an autoClose is pending, the pending
266 // autoClose is cancelled.
267 TEST_F(DownloadShelfControllerTest, CloseWithPendingAutoClose) {
268   base::scoped_nsobject<DownloadItemController> item(CreateItemController());
269   [shelf_ showDownloadShelf:YES
270                isUserAction:NO];
271   EXPECT_TRUE([shelf_ isVisible]);
272   [shelf_ add:item.get()];
273   // Expect 2 cancelAutoClose calls: From the showDownloadShelf: call and the
274   // add: call.
275   EXPECT_EQ(2, shelf_.get()->cancelAutoCloseCount_);
276   shelf_.get()->cancelAutoCloseCount_ = 0;
278   // The mouse enters the shelf.
279   [shelf_ mouseEntered:nil];
280   EXPECT_EQ(0, shelf_.get()->scheduleAutoCloseCount_);
282   // The download opens.
283   EXPECT_CALL(*[[item wrappedMockDownload] mockDownload], GetOpened())
284       .WillRepeatedly(Return(true));
285   [shelf_ downloadWasOpened:item.get()];
287   // The shelf should now be waiting for the mouse to exit. autoClose should not
288   // be scheduled yet.
289   EXPECT_TRUE([shelf_ isVisible]);
290   EXPECT_EQ(0, shelf_.get()->scheduleAutoCloseCount_);
291   EXPECT_EQ(0, shelf_.get()->cancelAutoCloseCount_);
293   // The mouse exits the shelf. autoClose should be scheduled now.
294   [shelf_ mouseExited:nil];
295   EXPECT_EQ(1, shelf_.get()->scheduleAutoCloseCount_);
296   EXPECT_EQ(0, shelf_.get()->cancelAutoCloseCount_);
298   // Remove the download item. This should cause the download shelf to be hidden
299   // immediately. The pending autoClose should be cancelled.
300   [shelf_ remove:item];
301   EXPECT_EQ(1, shelf_.get()->scheduleAutoCloseCount_);
302   EXPECT_EQ(1, shelf_.get()->cancelAutoCloseCount_);
303   EXPECT_FALSE([shelf_ isVisible]);
306 // That that the shelf cancels a pending autoClose if a new download item is
307 // added to it.
308 TEST_F(DownloadShelfControllerTest, AddItemWithPendingAutoClose) {
309   base::scoped_nsobject<DownloadItemController> item(CreateItemController());
310   [shelf_ showDownloadShelf:YES
311                isUserAction:NO];
312   EXPECT_TRUE([shelf_ isVisible]);
313   [shelf_ add:item.get()];
314   // Expect 2 cancelAutoClose calls: From the showDownloadShelf: call and the
315   // add: call.
316   EXPECT_EQ(2, shelf_.get()->cancelAutoCloseCount_);
317   shelf_.get()->cancelAutoCloseCount_ = 0;
319   // The mouse enters the shelf.
320   [shelf_ mouseEntered:nil];
321   EXPECT_EQ(0, shelf_.get()->scheduleAutoCloseCount_);
323   // The download opens.
324   EXPECT_CALL(*[[item wrappedMockDownload] mockDownload], GetOpened())
325       .WillRepeatedly(Return(true));
326   [shelf_ downloadWasOpened:item.get()];
328   // The shelf should now be waiting for the mouse to exit. autoClose should not
329   // be scheduled yet.
330   EXPECT_TRUE([shelf_ isVisible]);
331   EXPECT_EQ(0, shelf_.get()->scheduleAutoCloseCount_);
332   EXPECT_EQ(0, shelf_.get()->cancelAutoCloseCount_);
334   // The mouse exits the shelf. autoClose should be scheduled now.
335   [shelf_ mouseExited:nil];
336   EXPECT_EQ(1, shelf_.get()->scheduleAutoCloseCount_);
337   EXPECT_EQ(0, shelf_.get()->cancelAutoCloseCount_);
339   // Add a new download item. The pending autoClose should be cancelled.
340   base::scoped_nsobject<DownloadItemController> item2(CreateItemController());
341   [shelf_ add:item.get()];
342   EXPECT_EQ(1, shelf_.get()->scheduleAutoCloseCount_);
343   EXPECT_EQ(1, shelf_.get()->cancelAutoCloseCount_);
344   EXPECT_TRUE([shelf_ isVisible]);
347 // Test that pending autoClose calls are cancelled when exiting.
348 TEST_F(DownloadShelfControllerTest, CancelAutoCloseOnExit) {
349   base::scoped_nsobject<DownloadItemController> item(CreateItemController());
350   [shelf_ showDownloadShelf:YES
351                isUserAction:NO];
352   EXPECT_TRUE([shelf_ isVisible]);
353   [shelf_ add:item.get()];
354   EXPECT_EQ(0, shelf_.get()->scheduleAutoCloseCount_);
355   EXPECT_EQ(2, shelf_.get()->cancelAutoCloseCount_);
357   [shelf_ exiting];
358   EXPECT_EQ(0, shelf_.get()->scheduleAutoCloseCount_);
359   EXPECT_EQ(3, shelf_.get()->cancelAutoCloseCount_);
360   shelf_.reset();
363 }  // namespace