| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import <Cocoa/Cocoa.h> | 5 #import <Cocoa/Cocoa.h> |
| 6 | 6 |
| 7 #import "base/mac/scoped_nsobject.h" | 7 #import "base/mac/scoped_nsobject.h" |
| 8 #include "base/prefs/pref_service.h" | 8 #include "base/prefs/pref_service.h" |
| 9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
| 10 #include "chrome/app/chrome_command_ids.h" | 10 #include "chrome/app/chrome_command_ids.h" |
| 11 #include "chrome/browser/command_updater.h" | 11 #include "chrome/browser/command_updater.h" |
| 12 #include "chrome/browser/ui/browser.h" | 12 #include "chrome/browser/ui/browser.h" |
| 13 #include "chrome/browser/ui/browser_command_controller.h" | 13 #include "chrome/browser/ui/browser_command_controller.h" |
| 14 #include "chrome/browser/ui/browser_commands.h" | 14 #include "chrome/browser/ui/browser_commands.h" |
| 15 #include "chrome/browser/ui/browser_list.h" | 15 #include "chrome/browser/ui/browser_list.h" |
| 16 #include "chrome/browser/ui/browser_list_observer.h" | 16 #include "chrome/browser/ui/browser_list_observer.h" |
| 17 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h" | 17 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h" |
| 18 #import "chrome/browser/ui/cocoa/image_button_cell.h" | 18 #import "chrome/browser/ui/cocoa/image_button_cell.h" |
| 19 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" | 19 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" |
| 20 #import "chrome/browser/ui/cocoa/view_resizer_pong.h" |
| 20 #include "chrome/common/pref_names.h" | 21 #include "chrome/common/pref_names.h" |
| 21 #include "chrome/test/base/testing_profile.h" | 22 #include "chrome/test/base/testing_profile.h" |
| 22 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
| 23 #import "testing/gtest_mac.h" | 24 #import "testing/gtest_mac.h" |
| 24 #include "testing/platform_test.h" | 25 #include "testing/platform_test.h" |
| 25 | 26 |
| 26 // An NSView that fakes out hitTest:. | 27 // An NSView that fakes out hitTest:. |
| 27 @interface HitView : NSView { | 28 @interface HitView : NSView { |
| 28 id hitTestReturn_; | 29 id hitTestReturn_; |
| 29 } | 30 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 } | 63 } |
| 63 @end | 64 @end |
| 64 | 65 |
| 65 namespace { | 66 namespace { |
| 66 | 67 |
| 67 class ToolbarControllerTest : public CocoaProfileTest { | 68 class ToolbarControllerTest : public CocoaProfileTest { |
| 68 public: | 69 public: |
| 69 | 70 |
| 70 // Indexes that match the ordering returned by the private ToolbarController | 71 // Indexes that match the ordering returned by the private ToolbarController |
| 71 // |-toolbarViews| method. | 72 // |-toolbarViews| method. |
| 72 enum { | 73 enum SubviewIndex { |
| 73 kBackIndex, kForwardIndex, kReloadIndex, kHomeIndex, | 74 kBackIndex, kForwardIndex, kReloadIndex, kHomeIndex, |
| 74 kWrenchIndex, kLocationIndex, kBrowserActionContainerViewIndex | 75 kWrenchIndex, kLocationIndex, kBrowserActionContainerViewIndex |
| 75 }; | 76 }; |
| 76 | 77 |
| 77 void SetUp() override { | 78 void SetUp() override { |
| 78 CocoaProfileTest::SetUp(); | 79 CocoaProfileTest::SetUp(); |
| 79 ASSERT_TRUE(browser()); | 80 ASSERT_TRUE(browser()); |
| 80 | 81 |
| 82 resizeDelegate_.reset([[ViewResizerPong alloc] init]); |
| 83 |
| 81 CommandUpdater* updater = | 84 CommandUpdater* updater = |
| 82 browser()->command_controller()->command_updater(); | 85 browser()->command_controller()->command_updater(); |
| 83 // The default state for the commands is true, set a couple to false to | 86 // The default state for the commands is true, set a couple to false to |
| 84 // ensure they get picked up correct on initialization | 87 // ensure they get picked up correct on initialization |
| 85 updater->UpdateCommandEnabled(IDC_BACK, false); | 88 updater->UpdateCommandEnabled(IDC_BACK, false); |
| 86 updater->UpdateCommandEnabled(IDC_FORWARD, false); | 89 updater->UpdateCommandEnabled(IDC_FORWARD, false); |
| 87 bar_.reset([[TestToolbarController alloc] | 90 bar_.reset([[TestToolbarController alloc] |
| 88 initWithCommands:browser()->command_controller()->command_updater() | 91 initWithCommands:browser()->command_controller()->command_updater() |
| 89 profile:profile() | 92 profile:profile() |
| 90 browser:browser()]); | 93 browser:browser() |
| 94 resizeDelegate:resizeDelegate_.get()]); |
| 91 EXPECT_TRUE([bar_ view]); | 95 EXPECT_TRUE([bar_ view]); |
| 92 NSView* parent = [test_window() contentView]; | 96 NSView* parent = [test_window() contentView]; |
| 93 [parent addSubview:[bar_ view]]; | 97 [parent addSubview:[bar_ view]]; |
| 94 } | 98 } |
| 95 | 99 |
| 96 void TearDown() override { | 100 void TearDown() override { |
| 97 bar_.reset(); // browser() must outlive the ToolbarController. | 101 bar_.reset(); // browser() must outlive the ToolbarController. |
| 98 CocoaProfileTest::TearDown(); | 102 CocoaProfileTest::TearDown(); |
| 99 } | 103 } |
| 100 | 104 |
| 101 // Make sure the enabled state of the view is the same as the corresponding | 105 // Make sure the enabled state of the view is the same as the corresponding |
| 102 // command in the updater. The views are in the declaration order of outlets. | 106 // command in the updater. The views are in the declaration order of outlets. |
| 103 void CompareState(CommandUpdater* updater, NSArray* views) { | 107 void CompareState(CommandUpdater* updater, NSArray* views) { |
| 104 EXPECT_EQ(updater->IsCommandEnabled(IDC_BACK), | 108 EXPECT_EQ(updater->IsCommandEnabled(IDC_BACK), |
| 105 [[views objectAtIndex:kBackIndex] isEnabled] ? true : false); | 109 [[views objectAtIndex:kBackIndex] isEnabled] ? true : false); |
| 106 EXPECT_EQ(updater->IsCommandEnabled(IDC_FORWARD), | 110 EXPECT_EQ(updater->IsCommandEnabled(IDC_FORWARD), |
| 107 [[views objectAtIndex:kForwardIndex] isEnabled] ? true : false); | 111 [[views objectAtIndex:kForwardIndex] isEnabled] ? true : false); |
| 108 EXPECT_EQ(updater->IsCommandEnabled(IDC_RELOAD), | 112 EXPECT_EQ(updater->IsCommandEnabled(IDC_RELOAD), |
| 109 [[views objectAtIndex:kReloadIndex] isEnabled] ? true : false); | 113 [[views objectAtIndex:kReloadIndex] isEnabled] ? true : false); |
| 110 EXPECT_EQ(updater->IsCommandEnabled(IDC_HOME), | 114 EXPECT_EQ(updater->IsCommandEnabled(IDC_HOME), |
| 111 [[views objectAtIndex:kHomeIndex] isEnabled] ? true : false); | 115 [[views objectAtIndex:kHomeIndex] isEnabled] ? true : false); |
| 112 } | 116 } |
| 113 | 117 |
| 118 NSView* GetSubviewAt(SubviewIndex index) { |
| 119 return [[bar_ toolbarViews] objectAtIndex:index]; |
| 120 } |
| 121 |
| 122 base::scoped_nsobject<ViewResizerPong> resizeDelegate_; |
| 114 base::scoped_nsobject<TestToolbarController> bar_; | 123 base::scoped_nsobject<TestToolbarController> bar_; |
| 115 }; | 124 }; |
| 116 | 125 |
| 117 TEST_VIEW(ToolbarControllerTest, [bar_ view]) | 126 TEST_VIEW(ToolbarControllerTest, [bar_ view]) |
| 118 | 127 |
| 119 // Test the initial state that everything is sync'd up | 128 // Test the initial state that everything is sync'd up |
| 120 TEST_F(ToolbarControllerTest, InitialState) { | 129 TEST_F(ToolbarControllerTest, InitialState) { |
| 121 CommandUpdater* updater = browser()->command_controller()->command_updater(); | 130 CommandUpdater* updater = browser()->command_controller()->command_updater(); |
| 122 CompareState(updater, [bar_ toolbarViews]); | 131 CompareState(updater, [bar_ toolbarViews]); |
| 123 } | 132 } |
| 124 | 133 |
| 125 // Make sure a "titlebar only" toolbar with location bar works. | 134 // Make sure a "titlebar only" toolbar with location bar works. |
| 126 TEST_F(ToolbarControllerTest, TitlebarOnly) { | 135 TEST_F(ToolbarControllerTest, TitlebarOnly) { |
| 127 NSView* view = [bar_ view]; | 136 NSView* view = [bar_ view]; |
| 128 | 137 |
| 129 [bar_ setHasToolbar:NO hasLocationBar:YES]; | 138 [bar_ setHasToolbar:NO hasLocationBar:YES]; |
| 130 EXPECT_NE(view, [bar_ view]); | 139 EXPECT_EQ(view, [bar_ view]); |
| 131 | 140 |
| 132 // Simulate a popup going fullscreen and back by performing the reparenting | 141 // Simulate a popup going fullscreen and back by performing the reparenting |
| 133 // that happens during fullscreen transitions | 142 // that happens during fullscreen transitions |
| 134 NSView* superview = [view superview]; | 143 NSView* superview = [view superview]; |
| 135 [view removeFromSuperview]; | 144 [view removeFromSuperview]; |
| 136 [superview addSubview:view]; | 145 [superview addSubview:view]; |
| 137 | 146 |
| 147 EXPECT_EQ(view, [bar_ view]); |
| 148 } |
| 149 |
| 150 // Test updateVisibility with location bar only; this method is used by bookmark |
| 151 // apps, and should never be called when the toolbar is enabled. Ensure that the |
| 152 // buttons remain in the correct state. |
| 153 TEST_F(ToolbarControllerTest, UpdateVisibility) { |
| 154 NSView* view = [bar_ view]; |
| 155 |
| 156 // Test the escapable states first. |
| 138 [bar_ setHasToolbar:YES hasLocationBar:YES]; | 157 [bar_ setHasToolbar:YES hasLocationBar:YES]; |
| 139 EXPECT_EQ(view, [bar_ view]); | 158 EXPECT_GT([[bar_ view] frame].size.height, 0); |
| 159 EXPECT_GT([[bar_ view] frame].size.height, |
| 160 [GetSubviewAt(kLocationIndex) frame].size.height); |
| 161 EXPECT_GT([[bar_ view] frame].size.width, |
| 162 [GetSubviewAt(kLocationIndex) frame].size.width); |
| 163 EXPECT_FALSE([view isHidden]); |
| 164 EXPECT_FALSE([GetSubviewAt(kLocationIndex) isHidden]); |
| 165 EXPECT_FALSE([GetSubviewAt(kBackIndex) isHidden]); |
| 166 EXPECT_FALSE([GetSubviewAt(kForwardIndex) isHidden]); |
| 167 EXPECT_FALSE([GetSubviewAt(kReloadIndex) isHidden]); |
| 168 EXPECT_FALSE([GetSubviewAt(kWrenchIndex) isHidden]); |
| 169 EXPECT_TRUE([GetSubviewAt(kHomeIndex) isHidden]); |
| 170 EXPECT_TRUE([GetSubviewAt(kBrowserActionContainerViewIndex) isHidden]); |
| 140 | 171 |
| 141 // Leave it off to make sure that's fine | 172 // For NO/NO, only the top level toolbar view is hidden. |
| 173 [bar_ setHasToolbar:NO hasLocationBar:NO]; |
| 174 EXPECT_TRUE([view isHidden]); |
| 175 EXPECT_FALSE([GetSubviewAt(kLocationIndex) isHidden]); |
| 176 EXPECT_FALSE([GetSubviewAt(kBackIndex) isHidden]); |
| 177 EXPECT_FALSE([GetSubviewAt(kForwardIndex) isHidden]); |
| 178 EXPECT_FALSE([GetSubviewAt(kReloadIndex) isHidden]); |
| 179 EXPECT_FALSE([GetSubviewAt(kWrenchIndex) isHidden]); |
| 180 EXPECT_TRUE([GetSubviewAt(kHomeIndex) isHidden]); |
| 181 EXPECT_TRUE([GetSubviewAt(kBrowserActionContainerViewIndex) isHidden]); |
| 182 |
| 183 // Now test the inescapable state. |
| 142 [bar_ setHasToolbar:NO hasLocationBar:YES]; | 184 [bar_ setHasToolbar:NO hasLocationBar:YES]; |
| 185 EXPECT_GT([[bar_ view] frame].size.height, 0); |
| 186 EXPECT_EQ([[bar_ view] frame].size.height, |
| 187 [GetSubviewAt(kLocationIndex) frame].size.height); |
| 188 EXPECT_EQ([[bar_ view] frame].size.width, |
| 189 [GetSubviewAt(kLocationIndex) frame].size.width); |
| 190 EXPECT_FALSE([view isHidden]); |
| 191 EXPECT_FALSE([GetSubviewAt(kLocationIndex) isHidden]); |
| 192 EXPECT_TRUE([GetSubviewAt(kBackIndex) isHidden]); |
| 193 EXPECT_TRUE([GetSubviewAt(kForwardIndex) isHidden]); |
| 194 EXPECT_TRUE([GetSubviewAt(kReloadIndex) isHidden]); |
| 195 EXPECT_TRUE([GetSubviewAt(kWrenchIndex) isHidden]); |
| 196 EXPECT_TRUE([GetSubviewAt(kHomeIndex) isHidden]); |
| 197 EXPECT_TRUE([GetSubviewAt(kBrowserActionContainerViewIndex) isHidden]); |
| 198 |
| 199 // Maintain visible state. |
| 200 [bar_ updateVisibility:YES withAnimation:NO]; |
| 201 EXPECT_GT([[bar_ view] frame].size.height, 0); |
| 202 EXPECT_EQ([[bar_ view] frame].size.height, |
| 203 [GetSubviewAt(kLocationIndex) frame].size.height); |
| 204 EXPECT_EQ([[bar_ view] frame].size.width, |
| 205 [GetSubviewAt(kLocationIndex) frame].size.width); |
| 206 EXPECT_FALSE([view isHidden]); |
| 207 EXPECT_FALSE([GetSubviewAt(kLocationIndex) isHidden]); |
| 208 EXPECT_TRUE([GetSubviewAt(kBackIndex) isHidden]); |
| 209 EXPECT_TRUE([GetSubviewAt(kForwardIndex) isHidden]); |
| 210 EXPECT_TRUE([GetSubviewAt(kReloadIndex) isHidden]); |
| 211 EXPECT_TRUE([GetSubviewAt(kWrenchIndex) isHidden]); |
| 212 EXPECT_TRUE([GetSubviewAt(kHomeIndex) isHidden]); |
| 213 EXPECT_TRUE([GetSubviewAt(kBrowserActionContainerViewIndex) isHidden]); |
| 214 |
| 215 // Hide the toolbar and ensure it has height 0. |
| 216 [bar_ updateVisibility:NO withAnimation:NO]; |
| 217 EXPECT_FALSE([view isHidden]); |
| 218 EXPECT_EQ(0, [resizeDelegate_ height]); |
| 219 EXPECT_EQ(0, [[bar_ view] frame].size.height); |
| 220 |
| 221 // Try to show the home button. |
| 222 [bar_ showOptionalHomeButton]; |
| 223 |
| 224 // Re-show the bar. Buttons should remain hidden, including the home button. |
| 225 [bar_ updateVisibility:YES withAnimation:NO]; |
| 226 EXPECT_GT([resizeDelegate_ height], 0); |
| 227 EXPECT_GT([[bar_ view] frame].size.height, 0); |
| 228 EXPECT_EQ([[bar_ view] frame].size.height, |
| 229 [GetSubviewAt(kLocationIndex) frame].size.height); |
| 230 EXPECT_EQ([[bar_ view] frame].size.width, |
| 231 [GetSubviewAt(kLocationIndex) frame].size.width); |
| 232 EXPECT_FALSE([view isHidden]); |
| 233 EXPECT_FALSE([GetSubviewAt(kLocationIndex) isHidden]); |
| 234 EXPECT_TRUE([GetSubviewAt(kBackIndex) isHidden]); |
| 235 EXPECT_TRUE([GetSubviewAt(kForwardIndex) isHidden]); |
| 236 EXPECT_TRUE([GetSubviewAt(kReloadIndex) isHidden]); |
| 237 EXPECT_TRUE([GetSubviewAt(kWrenchIndex) isHidden]); |
| 238 EXPECT_TRUE([GetSubviewAt(kHomeIndex) isHidden]); |
| 239 EXPECT_TRUE([GetSubviewAt(kBrowserActionContainerViewIndex) isHidden]); |
| 143 } | 240 } |
| 144 | 241 |
| 145 // Make sure it works in the completely undecorated case. | 242 // Make sure it works in the completely undecorated case. |
| 146 TEST_F(ToolbarControllerTest, NoLocationBar) { | 243 TEST_F(ToolbarControllerTest, NoLocationBar) { |
| 147 NSView* view = [bar_ view]; | 244 NSView* view = [bar_ view]; |
| 148 | 245 |
| 149 [bar_ setHasToolbar:NO hasLocationBar:NO]; | 246 [bar_ setHasToolbar:NO hasLocationBar:NO]; |
| 150 EXPECT_NE(view, [bar_ view]); | |
| 151 EXPECT_TRUE([[bar_ view] isHidden]); | 247 EXPECT_TRUE([[bar_ view] isHidden]); |
| 152 | 248 |
| 153 // Simulate a popup going fullscreen and back by performing the reparenting | 249 // Simulate a popup going fullscreen and back by performing the reparenting |
| 154 // that happens during fullscreen transitions | 250 // that happens during fullscreen transitions |
| 155 NSView* superview = [view superview]; | 251 NSView* superview = [view superview]; |
| 156 [view removeFromSuperview]; | 252 [view removeFromSuperview]; |
| 157 [superview addSubview:view]; | 253 [superview addSubview:view]; |
| 158 } | 254 } |
| 159 | 255 |
| 160 // Make some changes to the enabled state of a few of the buttons and ensure | 256 // Make some changes to the enabled state of a few of the buttons and ensure |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 BrowserRemovedObserver observer; | 394 BrowserRemovedObserver observer; |
| 299 // This is normally called by BrowserWindowController, but since |bar_| is not | 395 // This is normally called by BrowserWindowController, but since |bar_| is not |
| 300 // owned by one, call it here. | 396 // owned by one, call it here. |
| 301 [bar_ browserWillBeDestroyed]; | 397 [bar_ browserWillBeDestroyed]; |
| 302 CloseBrowserWindow(); | 398 CloseBrowserWindow(); |
| 303 observer.WaitUntilBrowserRemoved(); | 399 observer.WaitUntilBrowserRemoved(); |
| 304 // |bar_| is released in TearDown(). | 400 // |bar_| is released in TearDown(). |
| 305 } | 401 } |
| 306 | 402 |
| 307 } // namespace | 403 } // namespace |
| OLD | NEW |