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
3// found in the LICENSE file.
4
5#include "base/compiler_specific.h"
6#include "base/strings/string16.h"
7#include "base/strings/utf_string_conversions.h"
8#include "chrome/browser/ui/cocoa/cocoa_test_helper.h"
9#import "chrome/browser/ui/cocoa/confirm_bubble_cocoa.h"
10#import "chrome/browser/ui/cocoa/confirm_bubble_controller.h"
11#include "chrome/browser/ui/confirm_bubble_model.h"
12#include "grit/theme_resources.h"
13#import "testing/gtest_mac.h"
14#include "ui/base/resource/resource_bundle.h"
15#import "ui/gfx/point.h"
16
17namespace {
18
19// The model object used in this test. This model implements all methods and
20// updates its status when ConfirmBubbleController calls its methods.
21class TestConfirmBubbleModel : public ConfirmBubbleModel {
22 public:
23  TestConfirmBubbleModel(bool* model_deleted,
24                         bool* accept_clicked,
25                         bool* cancel_clicked,
26                         bool* link_clicked);
27  TestConfirmBubbleModel();
28  virtual ~TestConfirmBubbleModel() OVERRIDE;
29  virtual base::string16 GetTitle() const OVERRIDE;
30  virtual base::string16 GetMessageText() const OVERRIDE;
31  virtual gfx::Image* GetIcon() const OVERRIDE;
32  virtual int GetButtons() const OVERRIDE;
33  virtual base::string16 GetButtonLabel(BubbleButton button) const OVERRIDE;
34  virtual void Accept() OVERRIDE;
35  virtual void Cancel() OVERRIDE;
36  virtual base::string16 GetLinkText() const OVERRIDE;
37  virtual void LinkClicked() OVERRIDE;
38
39 private:
40  bool* model_deleted_;
41  bool* accept_clicked_;
42  bool* cancel_clicked_;
43  bool* link_clicked_;
44};
45
46TestConfirmBubbleModel::TestConfirmBubbleModel(bool* model_deleted,
47                                               bool* accept_clicked,
48                                               bool* cancel_clicked,
49                                               bool* link_clicked)
50    : model_deleted_(model_deleted),
51      accept_clicked_(accept_clicked),
52      cancel_clicked_(cancel_clicked),
53      link_clicked_(link_clicked) {
54}
55
56TestConfirmBubbleModel::~TestConfirmBubbleModel() {
57  *model_deleted_ = true;
58}
59
60base::string16 TestConfirmBubbleModel::GetTitle() const {
61  return base::ASCIIToUTF16("Test");
62}
63
64base::string16 TestConfirmBubbleModel::GetMessageText() const {
65  return base::ASCIIToUTF16("Test Message");
66}
67
68gfx::Image* TestConfirmBubbleModel::GetIcon() const {
69  return &ResourceBundle::GetSharedInstance().GetImageNamed(
70      IDR_PRODUCT_LOGO_16);
71}
72
73int TestConfirmBubbleModel::GetButtons() const {
74  return BUTTON_OK | BUTTON_CANCEL;
75}
76
77base::string16 TestConfirmBubbleModel::GetButtonLabel(
78    BubbleButton button) const {
79  return button == BUTTON_OK ? base::ASCIIToUTF16("OK")
80                             : base::ASCIIToUTF16("Cancel");
81}
82
83void TestConfirmBubbleModel::Accept() {
84  *accept_clicked_ = true;
85}
86
87void TestConfirmBubbleModel::Cancel() {
88  *cancel_clicked_ = true;
89}
90
91base::string16 TestConfirmBubbleModel::GetLinkText() const {
92  return base::ASCIIToUTF16("Link");
93}
94
95void TestConfirmBubbleModel::LinkClicked() {
96  *link_clicked_ = true;
97}
98
99}  // namespace
100
101class ConfirmBubbleControllerTest : public CocoaTest {
102 public:
103  ConfirmBubbleControllerTest()
104      : model_deleted_(false),
105        accept_clicked_(false),
106        cancel_clicked_(false),
107        link_clicked_(false) {
108    NSView* view = [test_window() contentView];
109    // This model is owned by the controller created below.
110    model_ = new TestConfirmBubbleModel(&model_deleted_,
111                                        &accept_clicked_,
112                                        &cancel_clicked_,
113                                        &link_clicked_);
114    gfx::Point origin(0, 0);
115    controller_ =
116        [[ConfirmBubbleController alloc] initWithParent:view
117                                                 origin:origin.ToCGPoint()
118                                                  model:model_];
119    [view addSubview:[controller_ view]
120          positioned:NSWindowAbove
121          relativeTo:nil];
122  }
123
124  ConfirmBubbleCocoa* GetBubble() const {
125    return (ConfirmBubbleCocoa*)[controller_ view];
126  }
127
128  TestConfirmBubbleModel* model() const { return model_; }
129  bool model_deleted() const { return model_deleted_; }
130  bool accept_clicked() const { return accept_clicked_; }
131  bool cancel_clicked() const { return cancel_clicked_; }
132  bool link_clicked() const { return link_clicked_; }
133
134 private:
135  ConfirmBubbleController* controller_;  // weak; owns self
136  TestConfirmBubbleModel* model_;  // weak
137  bool model_deleted_;
138  bool accept_clicked_;
139  bool cancel_clicked_;
140  bool link_clicked_;
141};
142
143// Verify clicking a button or a link removes the ConfirmBubbleCocoa object and
144// calls an appropriate model method.
145TEST_F(ConfirmBubbleControllerTest, ClickOk) {
146  NSView* view = [test_window() contentView];
147  ConfirmBubbleCocoa* bubble = GetBubble();
148  bool contains_bubble_view = [[view subviews] containsObject:bubble];
149  EXPECT_TRUE(contains_bubble_view);
150
151  // Click its OK button and verify this view has been removed from the test
152  // window. Also verify TestConfirmBubbleModel::Accept() has been called.
153  [bubble clickOk];
154
155  contains_bubble_view = [[view subviews] containsObject:bubble];
156  EXPECT_FALSE(contains_bubble_view);
157  EXPECT_TRUE(accept_clicked());
158  EXPECT_FALSE(cancel_clicked());
159  EXPECT_FALSE(link_clicked());
160}
161
162TEST_F(ConfirmBubbleControllerTest, ClickCancel) {
163  NSView* view = [test_window() contentView];
164  ConfirmBubbleCocoa* bubble = GetBubble();
165  bool contains_bubble_view = [[view subviews] containsObject:bubble];
166  EXPECT_TRUE(contains_bubble_view);
167
168  // Click its cancel button and verify this view has been removed from the test
169  // window. Also verify TestConfirmBubbleModel::Cancel() has been called.
170  [bubble clickCancel];
171
172  contains_bubble_view = [[view subviews] containsObject:bubble];
173  EXPECT_FALSE(contains_bubble_view);
174  EXPECT_FALSE(accept_clicked());
175  EXPECT_TRUE(cancel_clicked());
176  EXPECT_FALSE(link_clicked());
177}
178
179TEST_F(ConfirmBubbleControllerTest, ClickLink) {
180  NSView* view = [test_window() contentView];
181  ConfirmBubbleCocoa* bubble = GetBubble();
182  bool contains_bubble_view = [[view subviews] containsObject:bubble];
183  EXPECT_TRUE(contains_bubble_view);
184
185  // Click its link and verify this view has been removed from the test window.
186  // Also verify TestConfirmBubbleModel::LinkClicked() has been called.
187  [bubble clickLink];
188
189  contains_bubble_view = [[view subviews] containsObject:bubble];
190  EXPECT_FALSE(contains_bubble_view);
191  EXPECT_FALSE(accept_clicked());
192  EXPECT_FALSE(cancel_clicked());
193  EXPECT_TRUE(link_clicked());
194}
195