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 68namespace { 69 70/////////////////////////////////////////////////////////////////////////// 71// Test fixtures 72 73class 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 92class 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 115TEST_VIEW(LinkInfoBarControllerTest, [controller_ view]); 116 117TEST_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 129TEST_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 137TEST_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 147TEST_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 154TEST_VIEW(ConfirmInfoBarControllerTest, [controller_ view]); 155 156TEST_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 174TEST_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 184TEST_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 196TEST_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 206TEST_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 218TEST_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 228TEST_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 240TEST_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