OLD | NEW |
(Empty) | |
| 1 // Copyright 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 #import "ios/chrome/browser/ui/toolbar/web_toolbar_controller.h" |
| 6 |
| 7 #import <Foundation/Foundation.h> |
| 8 |
| 9 #include <memory> |
| 10 |
| 11 #include "base/ios/ios_util.h" |
| 12 #include "base/mac/scoped_nsobject.h" |
| 13 #include "base/message_loop/message_loop.h" |
| 14 #include "base/strings/utf_string_conversions.h" |
| 15 #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" |
| 16 #import "ios/chrome/browser/ui/toolbar/test_toolbar_model_ios.h" |
| 17 #import "ios/chrome/browser/ui/toolbar/web_toolbar_controller_private.h" |
| 18 #include "ios/chrome/browser/ui/ui_util.h" |
| 19 #include "ios/chrome/test/block_cleanup_test.h" |
| 20 #include "ios/web/public/test/test_web_thread_bundle.h" |
| 21 #include "testing/gtest/include/gtest/gtest.h" |
| 22 #include "testing/gtest_mac.h" |
| 23 #import "third_party/ocmock/OCMock/OCMock.h" |
| 24 |
| 25 @interface UIView (SubViewTesting) |
| 26 - (NSMutableArray*)allSubviews; |
| 27 @end |
| 28 |
| 29 @implementation UIView (SubViewTesting) |
| 30 - (NSMutableArray*)allSubviews { |
| 31 NSMutableArray* views = [NSMutableArray array]; |
| 32 [views addObject:self]; |
| 33 for (UIView* subview in [self subviews]) { |
| 34 [views addObjectsFromArray:[subview allSubviews]]; |
| 35 } |
| 36 return views; |
| 37 } |
| 38 @end |
| 39 |
| 40 @interface WebToolbarController (TestingAdditions) |
| 41 - (void)layoutOmnibox; |
| 42 @end |
| 43 |
| 44 #pragma mark - |
| 45 |
| 46 namespace { |
| 47 |
| 48 class WebToolbarControllerTest : public BlockCleanupTest { |
| 49 protected: |
| 50 void SetUp() override { |
| 51 BlockCleanupTest::SetUp(); |
| 52 |
| 53 TestChromeBrowserState::Builder test_cbs_builder; |
| 54 chrome_browser_state_ = test_cbs_builder.Build(); |
| 55 // Set some text in the ToolbarModel so that OmniboxView uses the |
| 56 // ToolbarModel's icon instead of the OmniboxEditModel's icon. |
| 57 toolbar_model_ios_.reset(new TestToolbarModelIOS()); |
| 58 toolbar_model_ = (TestToolbarModel*)toolbar_model_ios_->GetToolbarModel(); |
| 59 toolbar_model_->set_text(base::UTF8ToUTF16("foo")); |
| 60 |
| 61 // The OCMOCK_VALUE macro doesn't like std::unique_ptr, but it works just |
| 62 // fine if a temporary variable is used. |
| 63 ToolbarModelIOS* model_for_mock = toolbar_model_ios_.get(); |
| 64 id delegate = |
| 65 [OCMockObject niceMockForProtocol:@protocol(WebToolbarDelegate)]; |
| 66 [[[delegate stub] andReturnValue:OCMOCK_VALUE(model_for_mock)] |
| 67 toolbarModelIOS]; |
| 68 |
| 69 id urlLoader = [OCMockObject niceMockForProtocol:@protocol(UrlLoader)]; |
| 70 |
| 71 // Create the WebToolbarController using the test objects. |
| 72 web_toolbar_controller_.reset([[WebToolbarController alloc] |
| 73 initWithDelegate:delegate |
| 74 urlLoader:urlLoader |
| 75 browserState:chrome_browser_state_.get() |
| 76 preloadProvider:nil]); |
| 77 [web_toolbar_controller_ setUnitTesting:YES]; |
| 78 } |
| 79 void TearDown() override { |
| 80 web_toolbar_controller_.reset(); |
| 81 BlockCleanupTest::TearDown(); |
| 82 } |
| 83 |
| 84 web::TestWebThreadBundle thread_bundle_; |
| 85 std::unique_ptr<TestChromeBrowserState> chrome_browser_state_; |
| 86 TestToolbarModel* toolbar_model_; // weak. Owned by toolbar_model_ios_. |
| 87 std::unique_ptr<TestToolbarModelIOS> toolbar_model_ios_; |
| 88 base::scoped_nsobject<WebToolbarController> web_toolbar_controller_; |
| 89 }; |
| 90 |
| 91 TEST_F(WebToolbarControllerTest, TestUpdateToolbar_NavigationButtonsEnabled) { |
| 92 EXPECT_FALSE([web_toolbar_controller_ isForwardButtonEnabled]); |
| 93 EXPECT_FALSE([web_toolbar_controller_ isBackButtonEnabled]); |
| 94 toolbar_model_ios_->set_can_go_back(true); |
| 95 toolbar_model_ios_->set_can_go_forward(true); |
| 96 [web_toolbar_controller_ updateToolbarState]; |
| 97 EXPECT_TRUE([web_toolbar_controller_ isForwardButtonEnabled]); |
| 98 EXPECT_TRUE([web_toolbar_controller_ isBackButtonEnabled]); |
| 99 } |
| 100 |
| 101 TEST_F(WebToolbarControllerTest, TestUpdateToolbar_NavigationButtonsDisabled) { |
| 102 EXPECT_FALSE([web_toolbar_controller_ isForwardButtonEnabled]); |
| 103 EXPECT_FALSE([web_toolbar_controller_ isBackButtonEnabled]); |
| 104 toolbar_model_ios_->set_can_go_back(false); |
| 105 toolbar_model_ios_->set_can_go_forward(false); |
| 106 [web_toolbar_controller_ updateToolbarState]; |
| 107 EXPECT_FALSE([web_toolbar_controller_ isForwardButtonEnabled]); |
| 108 EXPECT_FALSE([web_toolbar_controller_ isBackButtonEnabled]); |
| 109 } |
| 110 |
| 111 TEST_F(WebToolbarControllerTest, TestUpdateToolbar_StarButton) { |
| 112 // Test tablet only, as star button doesn't get used on phone. |
| 113 if (!IsIPadIdiom()) |
| 114 return; |
| 115 EXPECT_FALSE([web_toolbar_controller_ isStarButtonSelected]); |
| 116 // Set the curent tab to |kWebUrl| and create a bookmark for |kWebUrl|, then |
| 117 // verify that updateToolbar selected the star button. |
| 118 toolbar_model_ios_->set_is_current_tab_bookmarked(true); |
| 119 [web_toolbar_controller_ updateToolbarState]; |
| 120 EXPECT_TRUE([web_toolbar_controller_ isStarButtonSelected]); |
| 121 |
| 122 // Remove the bookmark and verify updateToolbar unselects the star button. |
| 123 toolbar_model_ios_->set_is_current_tab_bookmarked(false); |
| 124 [web_toolbar_controller_ updateToolbarState]; |
| 125 EXPECT_FALSE([web_toolbar_controller_ isStarButtonSelected]); |
| 126 } |
| 127 |
| 128 TEST_F(WebToolbarControllerTest, TestUpdateToolbar_ProgressBarLoading) { |
| 129 // Test phone only, as iPad does not have a progress bar. |
| 130 if (IsIPadIdiom()) |
| 131 return; |
| 132 EXPECT_FALSE([web_toolbar_controller_ isLoading]); |
| 133 toolbar_model_ios_->set_is_loading(true); |
| 134 [web_toolbar_controller_ updateToolbarState]; |
| 135 // Spin the run loop to allow animation to occur. |
| 136 [[NSRunLoop currentRunLoop] |
| 137 runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]; |
| 138 EXPECT_TRUE([web_toolbar_controller_ isLoading]); |
| 139 } |
| 140 |
| 141 TEST_F(WebToolbarControllerTest, TestUpdateToolbar_ProgressBarNotLoading) { |
| 142 // Test phone only, as iPad does not have a progress bar. |
| 143 if (IsIPadIdiom()) |
| 144 return; |
| 145 EXPECT_FALSE([web_toolbar_controller_ isLoading]); |
| 146 toolbar_model_ios_->set_is_loading(false); |
| 147 [web_toolbar_controller_ updateToolbarState]; |
| 148 // Spin the run loop to allow animation to occur. |
| 149 [[NSRunLoop currentRunLoop] |
| 150 runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]; |
| 151 EXPECT_FALSE([web_toolbar_controller_ isLoading]); |
| 152 } |
| 153 |
| 154 TEST_F(WebToolbarControllerTest, TestUpdateToolbar_LoadProgressFraction) { |
| 155 // Test phone only, as iPad does not have a progress bar. |
| 156 if (IsIPadIdiom()) |
| 157 return; |
| 158 CGFloat expectedProgress = 0.5; |
| 159 toolbar_model_ios_->set_is_loading(true); |
| 160 toolbar_model_ios_->set_load_progress_fraction(expectedProgress); |
| 161 [web_toolbar_controller_ updateToolbarState]; |
| 162 EXPECT_EQ(expectedProgress, [web_toolbar_controller_ loadProgressFraction]); |
| 163 } |
| 164 |
| 165 TEST_F(WebToolbarControllerTest, TestUpdateToolbar_PrerenderingAnimation) { |
| 166 // Test phone only, as iPad does not have a progress bar. |
| 167 if (IsIPadIdiom()) |
| 168 return; |
| 169 |
| 170 EXPECT_FALSE([web_toolbar_controller_ isLoading]); |
| 171 EXPECT_FALSE([web_toolbar_controller_ isPrerenderAnimationRunning]); |
| 172 [web_toolbar_controller_ showPrerenderingAnimation]; |
| 173 EXPECT_TRUE([web_toolbar_controller_ isPrerenderAnimationRunning]); |
| 174 // |-updateToolbarState| does not cancel the animation. |
| 175 [web_toolbar_controller_ updateToolbarState]; |
| 176 EXPECT_TRUE([web_toolbar_controller_ isPrerenderAnimationRunning]); |
| 177 } |
| 178 |
| 179 TEST_F(WebToolbarControllerTest, TestUpdateToolbar_WebUrlText) { |
| 180 const char* kExpectedUrlText = "expected URL text"; |
| 181 toolbar_model_->set_text(base::UTF8ToUTF16(kExpectedUrlText)); |
| 182 [web_toolbar_controller_ updateToolbarState]; |
| 183 std::string actualUrlText = [web_toolbar_controller_ getLocationText]; |
| 184 EXPECT_EQ(kExpectedUrlText, actualUrlText); |
| 185 } |
| 186 |
| 187 TEST_F(WebToolbarControllerTest, TestUpdateToolbar_TestLayoutOmnibox) { |
| 188 // Test that the initial setup of the toolbar matches the layout produced by |
| 189 // calling layoutOmnibox. If the initial frames do not match those set during |
| 190 // layoutOmnibox, there will be minor animations during startup. |
| 191 typedef base::hash_map<unsigned long, CGRect> FrameHash; |
| 192 typedef base::hash_map<unsigned long, CGRect>::iterator FrameHashIter; |
| 193 FrameHash initialFrames; |
| 194 FrameHash postLayoutFrames; |
| 195 |
| 196 for (UIView* view in [[web_toolbar_controller_ view] allSubviews]) { |
| 197 initialFrames.insert(std::make_pair<unsigned long, CGRect>( |
| 198 (unsigned long)view, [view frame])); |
| 199 } |
| 200 |
| 201 [web_toolbar_controller_ layoutOmnibox]; |
| 202 |
| 203 for (UIView* view in [[web_toolbar_controller_ view] allSubviews]) { |
| 204 postLayoutFrames.insert(std::make_pair<unsigned long, CGRect>( |
| 205 (unsigned long)view, [view frame])); |
| 206 } |
| 207 |
| 208 FrameHashIter initialIt = initialFrames.begin(); |
| 209 while (initialIt != initialFrames.end()) { |
| 210 FrameHashIter postLayoutIt = postLayoutFrames.find(initialIt->first); |
| 211 EXPECT_TRUE(postLayoutIt != postLayoutFrames.end()); |
| 212 CGRect initialRect = initialIt->second; |
| 213 CGRect layoutRect = postLayoutIt->second; |
| 214 EXPECT_EQ(initialRect.origin.x, layoutRect.origin.x); |
| 215 EXPECT_EQ(initialRect.origin.y, layoutRect.origin.y); |
| 216 EXPECT_EQ(initialRect.size.width, layoutRect.size.width); |
| 217 EXPECT_EQ(initialRect.size.height, layoutRect.size.height); |
| 218 initialIt++; |
| 219 } |
| 220 } |
| 221 } // namespace |
OLD | NEW |