[Metrics] Make MetricsStateManager take a callback param to check if UMA is enabled.
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / toolbar / toolbar_controller_unittest.mm
blob469a9f188d1391a358a04ad99ba319f82e2dba67
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.
5 #import <Cocoa/Cocoa.h>
7 #import "base/mac/scoped_nsobject.h"
8 #include "base/prefs/pref_service.h"
9 #include "chrome/app/chrome_command_ids.h"
10 #include "chrome/browser/command_updater.h"
11 #include "chrome/browser/ui/browser.h"
12 #include "chrome/browser/ui/browser_command_controller.h"
13 #include "chrome/browser/ui/browser_commands.h"
14 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h"
15 #import "chrome/browser/ui/cocoa/gradient_button_cell.h"
16 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
17 #import "chrome/browser/ui/cocoa/view_resizer_pong.h"
18 #include "chrome/common/pref_names.h"
19 #include "chrome/test/base/testing_profile.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "testing/platform_test.h"
23 // An NSView that fakes out hitTest:.
24 @interface HitView : NSView {
25   id hitTestReturn_;
27 @end
29 @implementation HitView
31 - (void)setHitTestReturn:(id)rtn {
32   hitTestReturn_ = rtn;
35 - (NSView *)hitTest:(NSPoint)aPoint {
36   return hitTestReturn_;
39 @end
42 namespace {
44 class ToolbarControllerTest : public CocoaProfileTest {
45  public:
47   // Indexes that match the ordering returned by the private ToolbarController
48   // |-toolbarViews| method.
49   enum {
50     kBackIndex, kForwardIndex, kReloadIndex, kHomeIndex,
51     kWrenchIndex, kLocationIndex, kBrowserActionContainerViewIndex
52   };
54   virtual void SetUp() OVERRIDE {
55     CocoaProfileTest::SetUp();
56     ASSERT_TRUE(browser());
58     CommandUpdater* updater =
59         browser()->command_controller()->command_updater();
60     // The default state for the commands is true, set a couple to false to
61     // ensure they get picked up correct on initialization
62     updater->UpdateCommandEnabled(IDC_BACK, false);
63     updater->UpdateCommandEnabled(IDC_FORWARD, false);
64     resizeDelegate_.reset([[ViewResizerPong alloc] init]);
65     bar_.reset(
66         [[ToolbarController alloc]
67             initWithCommands:browser()->command_controller()->command_updater()
68                      profile:profile()
69                      browser:browser()
70               resizeDelegate:resizeDelegate_.get()]);
71     EXPECT_TRUE([bar_ view]);
72     NSView* parent = [test_window() contentView];
73     [parent addSubview:[bar_ view]];
74   }
76   virtual void TearDown() OVERRIDE {
77     bar_.reset();  // browser() must outlive the ToolbarController.
78     CocoaProfileTest::TearDown();
79   }
81   // Make sure the enabled state of the view is the same as the corresponding
82   // command in the updater. The views are in the declaration order of outlets.
83   void CompareState(CommandUpdater* updater, NSArray* views) {
84     EXPECT_EQ(updater->IsCommandEnabled(IDC_BACK),
85               [[views objectAtIndex:kBackIndex] isEnabled] ? true : false);
86     EXPECT_EQ(updater->IsCommandEnabled(IDC_FORWARD),
87               [[views objectAtIndex:kForwardIndex] isEnabled] ? true : false);
88     EXPECT_EQ(updater->IsCommandEnabled(IDC_RELOAD),
89               [[views objectAtIndex:kReloadIndex] isEnabled] ? true : false);
90     EXPECT_EQ(updater->IsCommandEnabled(IDC_HOME),
91               [[views objectAtIndex:kHomeIndex] isEnabled] ? true : false);
92   }
94   base::scoped_nsobject<ViewResizerPong> resizeDelegate_;
95   base::scoped_nsobject<ToolbarController> bar_;
98 TEST_VIEW(ToolbarControllerTest, [bar_ view])
100 // Test the initial state that everything is sync'd up
101 TEST_F(ToolbarControllerTest, InitialState) {
102   CommandUpdater* updater = browser()->command_controller()->command_updater();
103   CompareState(updater, [bar_ toolbarViews]);
106 // Make sure a "titlebar only" toolbar with location bar works.
107 TEST_F(ToolbarControllerTest, TitlebarOnly) {
108   NSView* view = [bar_ view];
110   [bar_ setHasToolbar:NO hasLocationBar:YES];
111   EXPECT_NE(view, [bar_ view]);
113   // Simulate a popup going fullscreen and back by performing the reparenting
114   // that happens during fullscreen transitions
115   NSView* superview = [view superview];
116   [view removeFromSuperview];
117   [superview addSubview:view];
119   [bar_ setHasToolbar:YES hasLocationBar:YES];
120   EXPECT_EQ(view, [bar_ view]);
122   // Leave it off to make sure that's fine
123   [bar_ setHasToolbar:NO hasLocationBar:YES];
126 // Make sure it works in the completely undecorated case.
127 TEST_F(ToolbarControllerTest, NoLocationBar) {
128   NSView* view = [bar_ view];
130   [bar_ setHasToolbar:NO hasLocationBar:NO];
131   EXPECT_NE(view, [bar_ view]);
132   EXPECT_TRUE([[bar_ view] isHidden]);
134   // Simulate a popup going fullscreen and back by performing the reparenting
135   // that happens during fullscreen transitions
136   NSView* superview = [view superview];
137   [view removeFromSuperview];
138   [superview addSubview:view];
141 // Make some changes to the enabled state of a few of the buttons and ensure
142 // that we're still in sync.
143 TEST_F(ToolbarControllerTest, UpdateEnabledState) {
144   EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_BACK));
145   EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_FORWARD));
146   chrome::UpdateCommandEnabled(browser(), IDC_BACK, true);
147   chrome::UpdateCommandEnabled(browser(), IDC_FORWARD, true);
148   CommandUpdater* updater = browser()->command_controller()->command_updater();
149   CompareState(updater, [bar_ toolbarViews]);
152 // Focus the location bar and make sure that it's the first responder.
153 TEST_F(ToolbarControllerTest, FocusLocation) {
154   NSWindow* window = test_window();
155   [window makeFirstResponder:[window contentView]];
156   EXPECT_EQ([window firstResponder], [window contentView]);
157   [bar_ focusLocationBar:YES];
158   EXPECT_NE([window firstResponder], [window contentView]);
159   NSView* locationBar = [[bar_ toolbarViews] objectAtIndex:kLocationIndex];
160   EXPECT_EQ([window firstResponder], [(id)locationBar currentEditor]);
163 TEST_F(ToolbarControllerTest, LoadingState) {
164   // In its initial state, the reload button has a tag of
165   // IDC_RELOAD. When loading, it should be IDC_STOP.
166   NSButton* reload = [[bar_ toolbarViews] objectAtIndex:kReloadIndex];
167   EXPECT_EQ([reload tag], IDC_RELOAD);
168   [bar_ setIsLoading:YES force:YES];
169   EXPECT_EQ([reload tag], IDC_STOP);
170   [bar_ setIsLoading:NO force:YES];
171   EXPECT_EQ([reload tag], IDC_RELOAD);
174 // Check that toggling the state of the home button changes the visible
175 // state of the home button and moves the other items accordingly.
176 TEST_F(ToolbarControllerTest, ToggleHome) {
177   PrefService* prefs = profile()->GetPrefs();
178   bool showHome = prefs->GetBoolean(prefs::kShowHomeButton);
179   NSView* homeButton = [[bar_ toolbarViews] objectAtIndex:kHomeIndex];
180   EXPECT_EQ(showHome, ![homeButton isHidden]);
182   NSView* locationBar = [[bar_ toolbarViews] objectAtIndex:kLocationIndex];
183   NSRect originalLocationBarFrame = [locationBar frame];
185   // Toggle the pref and make sure the button changed state and the other
186   // views moved.
187   prefs->SetBoolean(prefs::kShowHomeButton, !showHome);
188   EXPECT_EQ(showHome, [homeButton isHidden]);
189   EXPECT_NE(NSMinX(originalLocationBarFrame), NSMinX([locationBar frame]));
190   EXPECT_NE(NSWidth(originalLocationBarFrame), NSWidth([locationBar frame]));
193 // Ensure that we don't toggle the buttons when we have a strip marked as not
194 // having the full toolbar. Also ensure that the location bar doesn't change
195 // size.
196 TEST_F(ToolbarControllerTest, DontToggleWhenNoToolbar) {
197   [bar_ setHasToolbar:NO hasLocationBar:YES];
198   NSView* homeButton = [[bar_ toolbarViews] objectAtIndex:kHomeIndex];
199   NSView* locationBar = [[bar_ toolbarViews] objectAtIndex:kLocationIndex];
200   NSRect locationBarFrame = [locationBar frame];
201   EXPECT_EQ([homeButton isHidden], YES);
202   [bar_ showOptionalHomeButton];
203   EXPECT_EQ([homeButton isHidden], YES);
204   NSRect newLocationBarFrame = [locationBar frame];
205   EXPECT_TRUE(NSEqualRects(locationBarFrame, newLocationBarFrame));
206   newLocationBarFrame = [locationBar frame];
207   EXPECT_TRUE(NSEqualRects(locationBarFrame, newLocationBarFrame));
210 TEST_F(ToolbarControllerTest, BookmarkBubblePoint) {
211   const NSPoint starPoint = [bar_ bookmarkBubblePoint];
212   const NSRect barFrame =
213       [[bar_ view] convertRect:[[bar_ view] bounds] toView:nil];
215   // Make sure the star is completely inside the location bar.
216   EXPECT_TRUE(NSPointInRect(starPoint, barFrame));
219 TEST_F(ToolbarControllerTest, TranslateBubblePoint) {
220   const NSPoint translatePoint = [bar_ translateBubblePoint];
221   const NSRect barFrame =
222       [[bar_ view] convertRect:[[bar_ view] bounds] toView:nil];
223   EXPECT_TRUE(NSPointInRect(translatePoint, barFrame));
226 TEST_F(ToolbarControllerTest, HoverButtonForEvent) {
227   base::scoped_nsobject<HitView> view(
228       [[HitView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)]);
229   [bar_ setView:view];
230   NSEvent* event = [NSEvent mouseEventWithType:NSMouseMoved
231                                       location:NSMakePoint(10,10)
232                                  modifierFlags:0
233                                      timestamp:0
234                                   windowNumber:0
235                                        context:nil
236                                    eventNumber:0
237                                     clickCount:0
238                                       pressure:0.0];
240   // NOT a match.
241   [view setHitTestReturn:bar_.get()];
242   EXPECT_FALSE([bar_ hoverButtonForEvent:event]);
244   // Not yet...
245   base::scoped_nsobject<NSButton> button([[NSButton alloc] init]);
246   [view setHitTestReturn:button];
247   EXPECT_FALSE([bar_ hoverButtonForEvent:event]);
249   // Now!
250   base::scoped_nsobject<GradientButtonCell> cell(
251       [[GradientButtonCell alloc] init]);
252   [button setCell:cell.get()];
253   EXPECT_TRUE([bar_ hoverButtonForEvent:nil]);
256 }  // namespace