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.
5 #import "chrome/browser/ui/cocoa/infobars/confirm_infobar_controller.h"
7 #include "base/mac/scoped_nsobject.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/sys_string_conversions.h"
10 #include "chrome/browser/infobars/infobar_service.h"
11 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h"
12 #import "chrome/browser/ui/cocoa/infobars/infobar_cocoa.h"
13 #import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h"
14 #include "chrome/browser/ui/cocoa/infobars/mock_confirm_infobar_delegate.h"
15 #include "chrome/browser/ui/cocoa/run_loop_testing.h"
16 #include "chrome/test/base/testing_profile.h"
17 #include "components/infobars/core/confirm_infobar_delegate.h"
18 #import "content/public/browser/web_contents.h"
19 #include "ipc/ipc_message.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "testing/platform_test.h"
23 using content::WebContents;
25 @interface InfoBarController (ExposedForTesting)
26 - (NSString*)labelString;
30 @implementation InfoBarController (ExposedForTesting)
31 - (NSString*)labelString {
32 return [label_.get() string];
34 - (NSRect)labelFrame {
35 return [label_.get() frame];
40 @interface InfoBarContainerTest : NSObject<InfoBarContainerControllerBase> {
41 InfoBarController* controller_;
44 - (id)initWithController:(InfoBarController*)controller;
48 @implementation InfoBarContainerTest
50 - (id)initWithController:(InfoBarController*)controller {
51 if ((self = [super init])) {
52 controller_ = controller;
57 - (BrowserWindowController*)browserWindowController {
61 - (BOOL)shouldSuppressTopInfoBarTip {
65 - (CGFloat)infobarArrowX {
71 @interface TestConfirmInfoBarController : ConfirmInfoBarController
75 @implementation TestConfirmInfoBarController
77 [self infobarWillClose];
79 [self infobar]->CloseSoon();
85 class ConfirmInfoBarControllerTest : public CocoaProfileTest,
86 public MockConfirmInfoBarDelegate::Owner {
88 void SetUp() override {
89 CocoaProfileTest::SetUp();
91 WebContents::Create(WebContents::CreateParams(profile())));
92 InfoBarService::CreateForWebContents(web_contents_.get());
94 scoped_ptr<infobars::InfoBarDelegate> delegate(
95 new MockConfirmInfoBarDelegate(this));
96 infobar_ = new InfoBarCocoa(delegate.Pass());
97 infobar_->SetOwner(InfoBarService::FromWebContents(web_contents_.get()));
99 controller_.reset([[TestConfirmInfoBarController alloc]
100 initWithInfoBar:infobar_]);
101 infobar_->set_controller(controller_);
104 [[InfoBarContainerTest alloc] initWithController:controller_]);
105 [controller_ setContainerController:container_];
106 [[test_window() contentView] addSubview:[controller_ view]];
107 closed_delegate_ok_clicked_ = false;
108 closed_delegate_cancel_clicked_ = false;
109 closed_delegate_link_clicked_ = false;
110 delegate_closed_ = false;
113 void TearDown() override {
114 [controller_ removeSelf];
115 CocoaProfileTest::TearDown();
119 // True if delegate is closed.
120 bool delegate_closed() const { return delegate_closed_; }
122 MockConfirmInfoBarDelegate* delegate() const {
123 return static_cast<MockConfirmInfoBarDelegate*>(infobar_->delegate());
126 base::scoped_nsobject<id> container_;
127 base::scoped_nsobject<ConfirmInfoBarController> controller_;
128 bool closed_delegate_ok_clicked_;
129 bool closed_delegate_cancel_clicked_;
130 bool closed_delegate_link_clicked_;
133 void OnInfoBarDelegateClosed() override {
134 closed_delegate_ok_clicked_ = delegate()->ok_clicked();
135 closed_delegate_cancel_clicked_ = delegate()->cancel_clicked();
136 closed_delegate_link_clicked_ = delegate()->link_clicked();
137 delegate_closed_ = true;
141 scoped_ptr<WebContents> web_contents_;
142 InfoBarCocoa* infobar_; // Weak, will delete itself.
143 bool delegate_closed_;
147 TEST_VIEW(ConfirmInfoBarControllerTest, [controller_ view]);
149 TEST_F(ConfirmInfoBarControllerTest, ShowAndDismiss) {
150 // Make sure someone looked at the message, link, and icon.
151 EXPECT_TRUE(delegate()->message_text_accessed());
152 EXPECT_TRUE(delegate()->link_text_accessed());
153 EXPECT_TRUE(delegate()->icon_accessed());
155 // Check to make sure the infobar message was set properly.
156 EXPECT_EQ(MockConfirmInfoBarDelegate::kMessage,
157 base::SysNSStringToUTF8([controller_.get() labelString]));
159 // Check that dismissing the infobar deletes the delegate.
160 [controller_ removeSelf];
161 ASSERT_TRUE(delegate_closed());
162 EXPECT_FALSE(closed_delegate_ok_clicked_);
163 EXPECT_FALSE(closed_delegate_cancel_clicked_);
164 EXPECT_FALSE(closed_delegate_link_clicked_);
167 TEST_F(ConfirmInfoBarControllerTest, ShowAndClickOK) {
168 // Check that clicking the OK button calls Accept() and then closes
170 [controller_ ok:nil];
171 ASSERT_TRUE(delegate_closed());
172 EXPECT_TRUE(closed_delegate_ok_clicked_);
173 EXPECT_FALSE(closed_delegate_cancel_clicked_);
174 EXPECT_FALSE(closed_delegate_link_clicked_);
177 TEST_F(ConfirmInfoBarControllerTest, ShowAndClickOKWithoutClosing) {
178 delegate()->set_dont_close_on_action();
180 // Check that clicking the OK button calls Accept() but does not close
182 [controller_ ok:nil];
183 ASSERT_FALSE(delegate_closed());
184 EXPECT_TRUE(delegate()->ok_clicked());
185 EXPECT_FALSE(delegate()->cancel_clicked());
186 EXPECT_FALSE(delegate()->link_clicked());
189 TEST_F(ConfirmInfoBarControllerTest, ShowAndClickCancel) {
190 // Check that clicking the cancel button calls Cancel() and closes
192 [controller_ cancel:nil];
193 ASSERT_TRUE(delegate_closed());
194 EXPECT_FALSE(closed_delegate_ok_clicked_);
195 EXPECT_TRUE(closed_delegate_cancel_clicked_);
196 EXPECT_FALSE(closed_delegate_link_clicked_);
199 TEST_F(ConfirmInfoBarControllerTest, ShowAndClickCancelWithoutClosing) {
200 delegate()->set_dont_close_on_action();
202 // Check that clicking the cancel button calls Cancel() but does not close
204 [controller_ cancel:nil];
205 ASSERT_FALSE(delegate_closed());
206 EXPECT_FALSE(delegate()->ok_clicked());
207 EXPECT_TRUE(delegate()->cancel_clicked());
208 EXPECT_FALSE(delegate()->link_clicked());
211 TEST_F(ConfirmInfoBarControllerTest, ShowAndClickLink) {
212 // Check that clicking on the link calls LinkClicked() on the
213 // delegate. It should also close the infobar.
214 [controller_ linkClicked];
215 ASSERT_TRUE(delegate_closed());
216 EXPECT_FALSE(closed_delegate_ok_clicked_);
217 EXPECT_FALSE(closed_delegate_cancel_clicked_);
218 EXPECT_TRUE(closed_delegate_link_clicked_);
221 TEST_F(ConfirmInfoBarControllerTest, ShowAndClickLinkWithoutClosing) {
222 delegate()->set_dont_close_on_action();
224 // Check that clicking on the link calls LinkClicked() on the
225 // delegate. It should not close the infobar.
226 [controller_ linkClicked];
227 ASSERT_FALSE(delegate_closed());
228 EXPECT_FALSE(delegate()->ok_clicked());
229 EXPECT_FALSE(delegate()->cancel_clicked());
230 EXPECT_TRUE(delegate()->link_clicked());
233 TEST_F(ConfirmInfoBarControllerTest, ResizeView) {
234 NSRect originalLabelFrame = [controller_ labelFrame];
236 // Expand the view by 20 pixels and make sure the label frame changes
238 const CGFloat width = 20;
239 NSRect newViewFrame = [[controller_ view] frame];
240 newViewFrame.size.width += width;
241 [[controller_ view] setFrame:newViewFrame];
243 NSRect newLabelFrame = [controller_ labelFrame];
244 EXPECT_EQ(NSWidth(newLabelFrame), NSWidth(originalLabelFrame) + width);