1 // Copyright (c) 2011 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 #include "base/memory/scoped_nsobject.h" 8 #include "base/string_util.h" 9 #include "base/sys_string_conversions.h" 10 #include "chrome/browser/tab_contents/confirm_infobar_delegate.h" 11 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" 12 #import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h" 13 #import "chrome/browser/ui/cocoa/infobars/infobar_controller.h" 14 #include "chrome/browser/ui/cocoa/infobars/mock_confirm_infobar_delegate.h" 15 #include "chrome/browser/ui/cocoa/infobars/mock_link_infobar_delegate.h" 16 #include "testing/gtest/include/gtest/gtest.h" 17 #include "testing/platform_test.h" 18 19 @interface InfoBarController (ExposedForTesting) 20 - (NSString*)labelString; 21 - (NSRect)labelFrame; 22 @end 23 24 @implementation InfoBarController (ExposedForTesting) 25 - (NSString*)labelString { 26 return [label_.get() string]; 27 } 28 - (NSRect)labelFrame { 29 return [label_.get() frame]; 30 } 31 @end 32 33 34 // Calls to removeDelegate: normally start an animation, which removes the 35 // infobar completely when finished. For unittesting purposes, we create a mock 36 // container which calls close: immediately, rather than kicking off an 37 // animation. 38 @interface InfoBarContainerTest : NSObject<InfoBarContainer> { 39 InfoBarController* controller_; 40 } 41 - (id)initWithController:(InfoBarController*)controller; 42 - (void)removeDelegate:(InfoBarDelegate*)delegate; 43 - (void)willRemoveController:(InfoBarController*)controller; 44 - (void)removeController:(InfoBarController*)controller; 45 @end 46 47 @implementation InfoBarContainerTest 48 - (id)initWithController:(InfoBarController*)controller { 49 if ((self = [super init])) { 50 controller_ = controller; 51 } 52 return self; 53 } 54 55 - (void)removeDelegate:(InfoBarDelegate*)delegate { 56 [controller_ close]; 57 } 58 59 - (void)willRemoveController:(InfoBarController*)controller { 60 } 61 62 - (void)removeController:(InfoBarController*)controller { 63 DCHECK(controller_ == controller); 64 controller_ = nil; 65 } 66 @end 67 68 namespace { 69 70 /////////////////////////////////////////////////////////////////////////// 71 // Test fixtures 72 73 class LinkInfoBarControllerTest : public CocoaTest { 74 public: 75 virtual void SetUp() { 76 CocoaTest::SetUp(); 77 78 controller_.reset( 79 [[LinkInfoBarController alloc] initWithDelegate:&delegate_]); 80 container_.reset( 81 [[InfoBarContainerTest alloc] initWithController:controller_]); 82 [controller_ setContainerController:container_]; 83 [[test_window() contentView] addSubview:[controller_ view]]; 84 } 85 86 protected: 87 MockLinkInfoBarDelegate delegate_; 88 scoped_nsobject<id> container_; 89 scoped_nsobject<LinkInfoBarController> controller_; 90 }; 91 92 class ConfirmInfoBarControllerTest : public CocoaTest { 93 public: 94 virtual void SetUp() { 95 CocoaTest::SetUp(); 96 97 controller_.reset( 98 [[ConfirmInfoBarController alloc] initWithDelegate:&delegate_]); 99 container_.reset( 100 [[InfoBarContainerTest alloc] initWithController:controller_]); 101 [controller_ setContainerController:container_]; 102 [[test_window() contentView] addSubview:[controller_ view]]; 103 } 104 105 protected: 106 MockConfirmInfoBarDelegate delegate_; 107 scoped_nsobject<id> container_; 108 scoped_nsobject<ConfirmInfoBarController> controller_; 109 }; 110 111 112 //////////////////////////////////////////////////////////////////////////// 113 // Tests 114 115 TEST_VIEW(LinkInfoBarControllerTest, [controller_ view]); 116 117 TEST_F(LinkInfoBarControllerTest, ShowAndDismiss) { 118 // Make sure someone looked at the message, link, and icon. 119 EXPECT_TRUE(delegate_.message_text_accessed()); 120 EXPECT_TRUE(delegate_.link_text_accessed()); 121 EXPECT_TRUE(delegate_.icon_accessed()); 122 123 // Check that dismissing the infobar calls InfoBarClosed() on the delegate. 124 [controller_ dismiss:nil]; 125 EXPECT_FALSE(delegate_.link_clicked()); 126 EXPECT_TRUE(delegate_.closed()); 127 } 128 129 TEST_F(LinkInfoBarControllerTest, ShowAndClickLink) { 130 // Check that clicking on the link calls LinkClicked() on the 131 // delegate. It should also close the infobar. 132 [controller_ linkClicked]; 133 EXPECT_TRUE(delegate_.link_clicked()); 134 EXPECT_TRUE(delegate_.closed()); 135 } 136 137 TEST_F(LinkInfoBarControllerTest, ShowAndClickLinkWithoutClosing) { 138 delegate_.set_dont_close_on_action(); 139 140 // Check that clicking on the link calls LinkClicked() on the 141 // delegate. It should not close the infobar. 142 [controller_ linkClicked]; 143 EXPECT_TRUE(delegate_.link_clicked()); 144 EXPECT_FALSE(delegate_.closed()); 145 } 146 147 TEST_F(LinkInfoBarControllerTest, DeallocController) { 148 // Test that dealloc'ing the controller does not send an 149 // InfoBarClosed() message to the delegate. 150 controller_.reset(nil); 151 EXPECT_FALSE(delegate_.closed()); 152 } 153 154 TEST_VIEW(ConfirmInfoBarControllerTest, [controller_ view]); 155 156 TEST_F(ConfirmInfoBarControllerTest, ShowAndDismiss) { 157 // Make sure someone looked at the message, link, and icon. 158 EXPECT_TRUE(delegate_.message_text_accessed()); 159 EXPECT_TRUE(delegate_.link_text_accessed()); 160 EXPECT_TRUE(delegate_.icon_accessed()); 161 162 // Check to make sure the infobar message was set properly. 163 EXPECT_EQ(MockConfirmInfoBarDelegate::kMessage, 164 base::SysNSStringToUTF8([controller_.get() labelString])); 165 166 // Check that dismissing the infobar calls InfoBarClosed() on the delegate. 167 [controller_ dismiss:nil]; 168 EXPECT_FALSE(delegate_.ok_clicked()); 169 EXPECT_FALSE(delegate_.cancel_clicked()); 170 EXPECT_FALSE(delegate_.link_clicked()); 171 EXPECT_TRUE(delegate_.closed()); 172 } 173 174 TEST_F(ConfirmInfoBarControllerTest, ShowAndClickOK) { 175 // Check that clicking the OK button calls Accept() and then closes 176 // the infobar. 177 [controller_ ok:nil]; 178 EXPECT_TRUE(delegate_.ok_clicked()); 179 EXPECT_FALSE(delegate_.cancel_clicked()); 180 EXPECT_FALSE(delegate_.link_clicked()); 181 EXPECT_TRUE(delegate_.closed()); 182 } 183 184 TEST_F(ConfirmInfoBarControllerTest, ShowAndClickOKWithoutClosing) { 185 delegate_.set_dont_close_on_action(); 186 187 // Check that clicking the OK button calls Accept() but does not close 188 // the infobar. 189 [controller_ ok:nil]; 190 EXPECT_TRUE(delegate_.ok_clicked()); 191 EXPECT_FALSE(delegate_.cancel_clicked()); 192 EXPECT_FALSE(delegate_.link_clicked()); 193 EXPECT_FALSE(delegate_.closed()); 194 } 195 196 TEST_F(ConfirmInfoBarControllerTest, ShowAndClickCancel) { 197 // Check that clicking the cancel button calls Cancel() and closes 198 // the infobar. 199 [controller_ cancel:nil]; 200 EXPECT_FALSE(delegate_.ok_clicked()); 201 EXPECT_TRUE(delegate_.cancel_clicked()); 202 EXPECT_FALSE(delegate_.link_clicked()); 203 EXPECT_TRUE(delegate_.closed()); 204 } 205 206 TEST_F(ConfirmInfoBarControllerTest, ShowAndClickCancelWithoutClosing) { 207 delegate_.set_dont_close_on_action(); 208 209 // Check that clicking the cancel button calls Cancel() but does not close 210 // the infobar. 211 [controller_ cancel:nil]; 212 EXPECT_FALSE(delegate_.ok_clicked()); 213 EXPECT_TRUE(delegate_.cancel_clicked()); 214 EXPECT_FALSE(delegate_.link_clicked()); 215 EXPECT_FALSE(delegate_.closed()); 216 } 217 218 TEST_F(ConfirmInfoBarControllerTest, ShowAndClickLink) { 219 // Check that clicking on the link calls LinkClicked() on the 220 // delegate. It should also close the infobar. 221 [controller_ linkClicked]; 222 EXPECT_FALSE(delegate_.ok_clicked()); 223 EXPECT_FALSE(delegate_.cancel_clicked()); 224 EXPECT_TRUE(delegate_.link_clicked()); 225 EXPECT_TRUE(delegate_.closed()); 226 } 227 228 TEST_F(ConfirmInfoBarControllerTest, ShowAndClickLinkWithoutClosing) { 229 delegate_.set_dont_close_on_action(); 230 231 // Check that clicking on the link calls LinkClicked() on the 232 // delegate. It should not close the infobar. 233 [controller_ linkClicked]; 234 EXPECT_FALSE(delegate_.ok_clicked()); 235 EXPECT_FALSE(delegate_.cancel_clicked()); 236 EXPECT_TRUE(delegate_.link_clicked()); 237 EXPECT_FALSE(delegate_.closed()); 238 } 239 240 TEST_F(ConfirmInfoBarControllerTest, ResizeView) { 241 NSRect originalLabelFrame = [controller_ labelFrame]; 242 243 // Expand the view by 20 pixels and make sure the label frame changes 244 // accordingly. 245 const CGFloat width = 20; 246 NSRect newViewFrame = [[controller_ view] frame]; 247 newViewFrame.size.width += width; 248 [[controller_ view] setFrame:newViewFrame]; 249 250 NSRect newLabelFrame = [controller_ labelFrame]; 251 EXPECT_EQ(NSWidth(newLabelFrame), NSWidth(originalLabelFrame) + width); 252 } 253 254 } // namespace 255