Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / website_settings / permission_bubble_controller_unittest.mm
1 // Copyright 2014 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 "chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.h"
6
7 #include "base/mac/foundation_util.h"
8 #include "base/stl_util.h"
9 #include "base/strings/sys_string_conversions.h"
10 #include "base/strings/utf_string_conversions.h"
11 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
12 #include "chrome/browser/ui/cocoa/run_loop_testing.h"
13 #import "chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.h"
14 #import "chrome/browser/ui/cocoa/website_settings/split_block_button.h"
15 #include "chrome/browser/ui/website_settings/mock_permission_bubble_request.h"
16 #include "grit/generated_resources.h"
17 #include "ui/base/l10n/l10n_util.h"
18 #include "ui/base/l10n/l10n_util_mac.h"
19 #import "ui/events/test/cocoa_test_event_utils.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21
22 @class ConstrainedWindowButton;
23
24 @interface PermissionBubbleController (ExposedForTesting)
25 - (void)ok:(id)sender;
26 - (void)onAllow:(id)sender;
27 - (void)onBlock:(id)sender;
28 - (void)onCustomize:(id)sender;
29 - (void)onCheckboxChanged:(id)sender;
30 @end
31
32 @interface SplitBlockButton (ExposedForTesting)
33 - (NSMenu*)menu;
34 @end
35
36 namespace {
37 const char* const kPermissionA = "Permission A";
38 const char* const kPermissionB = "Permission B";
39 const char* const kPermissionC = "Permission C";
40 }
41
42 class PermissionBubbleControllerTest : public CocoaTest,
43   public PermissionBubbleView::Delegate {
44  public:
45
46   MOCK_METHOD2(ToggleAccept, void(int, bool));
47   MOCK_METHOD0(SetCustomizationMode, void());
48   MOCK_METHOD0(Accept, void());
49   MOCK_METHOD0(Deny, void());
50   MOCK_METHOD0(Closing, void());
51   MOCK_METHOD1(SetView, void(PermissionBubbleView*));
52
53   virtual void SetUp() OVERRIDE {
54     CocoaTest::SetUp();
55     bridge_.reset(new PermissionBubbleCocoa(nil));
56     AddRequest(kPermissionA);
57     controller_ = [[PermissionBubbleController alloc]
58         initWithParentWindow:test_window()
59                       bridge:bridge_.get()];
60   }
61
62   virtual void TearDown() OVERRIDE {
63     [controller_ close];
64     chrome::testing::NSRunLoopRunAllPending();
65     STLDeleteElements(&requests_);
66     CocoaTest::TearDown();
67   }
68
69   void AddRequest(const std::string& title) {
70     MockPermissionBubbleRequest* request = new MockPermissionBubbleRequest(
71         title,
72         l10n_util::GetStringUTF8(IDS_PERMISSION_ALLOW),
73         l10n_util::GetStringUTF8(IDS_PERMISSION_DENY));
74     requests_.push_back(request);
75   }
76
77   NSButton* FindButtonWithTitle(const std::string& title) {
78     return FindButtonWithTitle(base::SysUTF8ToNSString(title),
79                                [ConstrainedWindowButton class]);
80   }
81
82   NSButton* FindButtonWithTitle(int title_id) {
83     return FindButtonWithTitle(l10n_util::GetNSString(title_id),
84                                [ConstrainedWindowButton class]);
85   }
86
87   NSButton* FindMenuButtonWithTitle(int title_id) {
88     return FindButtonWithTitle(l10n_util::GetNSString(title_id),
89                                [NSPopUpButton class]);
90   }
91
92   // IDS_PERMISSION_ALLOW and IDS_PERMISSION_DENY are used for two distinct
93   // UI elements, both of which derive from NSButton.  So check the expected
94   // class, not just NSButton, as well as the title.
95   NSButton* FindButtonWithTitle(NSString* title, Class button_class) {
96     for (NSButton* view in [[controller_ bubble] subviews]) {
97       if ([view isKindOfClass:button_class] &&
98           [title isEqualToString:[view title]]) {
99         return view;
100       }
101     }
102     return nil;
103   }
104
105   NSTextField* FindTextFieldWithString(const std::string& text) {
106     NSView* parent = base::mac::ObjCCastStrict<NSView>([controller_ bubble]);
107     return FindTextFieldWithString(parent, base::SysUTF8ToNSString(text));
108   }
109
110   NSTextField* FindTextFieldWithString(NSView* view, NSString* text) {
111     NSTextField* textField = nil;
112     for (NSView* child in [view subviews]) {
113       textField = base::mac::ObjCCast<NSTextField>(child);
114       if (![[textField stringValue] hasSuffix:text]) {
115         textField = FindTextFieldWithString(child, text);
116         if (textField)
117           break;
118       }
119     }
120     return textField;
121   }
122
123   void ChangePermissionMenuSelection(NSButton* menu_button, int next_title_id) {
124     NSMenu* menu = [base::mac::ObjCCastStrict<NSPopUpButton>(menu_button) menu];
125     NSString* next_title = l10n_util::GetNSString(next_title_id);
126     EXPECT_EQ([[menu itemWithTitle:[menu_button title]] state], NSOnState);
127     NSMenuItem* next_item = [menu itemWithTitle:next_title];
128     EXPECT_EQ([next_item state], NSOffState);
129     [menu performActionForItemAtIndex:[menu indexOfItem:next_item]];
130   }
131
132   NSMenuItem* FindCustomizeMenuItem() {
133     NSButton* button = FindButtonWithTitle(IDS_PERMISSION_DENY);
134     if (!button || ![button isKindOfClass:[SplitBlockButton class]])
135       return nil;
136     NSString* customize = l10n_util::GetNSString(IDS_PERMISSION_CUSTOMIZE);
137     SplitBlockButton* block_button =
138         base::mac::ObjCCast<SplitBlockButton>(button);
139     for (NSMenuItem* item in [[block_button menu] itemArray]) {
140       if ([[item title] isEqualToString:customize])
141         return item;
142     }
143     return nil;
144   }
145
146  protected:
147   PermissionBubbleController* controller_;  // Weak;  it deletes itself.
148   scoped_ptr<PermissionBubbleCocoa> bridge_;
149   std::vector<PermissionBubbleRequest*> requests_;
150   std::vector<bool> accept_states_;
151 };
152
153 TEST_F(PermissionBubbleControllerTest, ShowAndClose) {
154   EXPECT_FALSE([[controller_ window] isVisible]);
155   [controller_ showWindow:nil];
156   EXPECT_TRUE([[controller_ window] isVisible]);
157 }
158
159 TEST_F(PermissionBubbleControllerTest, ShowSinglePermission) {
160   [controller_ showAtAnchor:NSZeroPoint
161               withDelegate:this
162                forRequests:requests_
163               acceptStates:accept_states_
164          customizationMode:NO];
165
166   EXPECT_TRUE(FindTextFieldWithString(kPermissionA));
167   EXPECT_TRUE(FindButtonWithTitle(IDS_PERMISSION_ALLOW));
168   EXPECT_TRUE(FindButtonWithTitle(IDS_PERMISSION_DENY));
169   EXPECT_FALSE(FindButtonWithTitle(IDS_OK));
170   EXPECT_FALSE(FindCustomizeMenuItem());
171 }
172
173 TEST_F(PermissionBubbleControllerTest, ShowMultiplePermissions) {
174   AddRequest(kPermissionB);
175   AddRequest(kPermissionC);
176
177   [controller_ showAtAnchor:NSZeroPoint
178               withDelegate:this
179                forRequests:requests_
180               acceptStates:accept_states_
181          customizationMode:NO];
182
183   EXPECT_TRUE(FindTextFieldWithString(kPermissionA));
184   EXPECT_TRUE(FindTextFieldWithString(kPermissionB));
185   EXPECT_TRUE(FindTextFieldWithString(kPermissionC));
186
187   EXPECT_TRUE(FindButtonWithTitle(IDS_PERMISSION_ALLOW));
188   EXPECT_TRUE(FindButtonWithTitle(IDS_PERMISSION_DENY));
189   EXPECT_TRUE(FindCustomizeMenuItem());
190   EXPECT_FALSE(FindButtonWithTitle(IDS_OK));
191 }
192
193 TEST_F(PermissionBubbleControllerTest, ShowCustomizationModeAllow) {
194   accept_states_.push_back(true);
195   [controller_ showAtAnchor:NSZeroPoint
196                withDelegate:this
197                 forRequests:requests_
198                acceptStates:accept_states_
199           customizationMode:YES];
200
201   // Test that there is one menu, with 'Allow' visible.
202   EXPECT_TRUE(FindMenuButtonWithTitle(IDS_PERMISSION_ALLOW));
203   EXPECT_FALSE(FindMenuButtonWithTitle(IDS_PERMISSION_DENY));
204
205   EXPECT_TRUE(FindButtonWithTitle(IDS_OK));
206   EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_ALLOW));
207   EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_DENY));
208   EXPECT_FALSE(FindCustomizeMenuItem());
209 }
210
211 TEST_F(PermissionBubbleControllerTest, ShowCustomizationModeBlock) {
212   accept_states_.push_back(false);
213   [controller_ showAtAnchor:NSZeroPoint
214               withDelegate:this
215                forRequests:requests_
216               acceptStates:accept_states_
217          customizationMode:YES];
218
219   // Test that there is one menu, with 'Block' visible.
220   EXPECT_TRUE(FindMenuButtonWithTitle(IDS_PERMISSION_DENY));
221   EXPECT_FALSE(FindMenuButtonWithTitle(IDS_PERMISSION_ALLOW));
222
223   EXPECT_TRUE(FindButtonWithTitle(IDS_OK));
224   EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_ALLOW));
225   EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_DENY));
226   EXPECT_FALSE(FindCustomizeMenuItem());
227 }
228
229 TEST_F(PermissionBubbleControllerTest, OK) {
230   accept_states_.push_back(true);
231   [controller_ showAtAnchor:NSZeroPoint
232               withDelegate:this
233                forRequests:requests_
234               acceptStates:accept_states_
235          customizationMode:YES];
236
237   EXPECT_CALL(*this, Closing()).Times(1);
238   [FindButtonWithTitle(IDS_OK) performClick:nil];
239 }
240
241 TEST_F(PermissionBubbleControllerTest, Allow) {
242   [controller_ showAtAnchor:NSZeroPoint
243               withDelegate:this
244                forRequests:requests_
245               acceptStates:accept_states_
246          customizationMode:NO];
247
248   EXPECT_CALL(*this, Accept()).Times(1);
249   [FindButtonWithTitle(IDS_PERMISSION_ALLOW) performClick:nil];
250 }
251
252 TEST_F(PermissionBubbleControllerTest, Deny) {
253   [controller_ showAtAnchor:NSZeroPoint
254               withDelegate:this
255                forRequests:requests_
256               acceptStates:accept_states_
257          customizationMode:NO];
258
259   EXPECT_CALL(*this, Deny()).Times(1);
260   [FindButtonWithTitle(IDS_PERMISSION_DENY) performClick:nil];
261 }
262
263 TEST_F(PermissionBubbleControllerTest, ChangePermissionSelection) {
264   AddRequest(kPermissionB);
265
266   accept_states_.push_back(true);
267   accept_states_.push_back(false);
268
269   [controller_ showAtAnchor:NSZeroPoint
270               withDelegate:this
271                forRequests:requests_
272               acceptStates:accept_states_
273          customizationMode:YES];
274
275   EXPECT_CALL(*this, ToggleAccept(0, false)).Times(1);
276   EXPECT_CALL(*this, ToggleAccept(1, true)).Times(1);
277   NSButton* menu_a = FindMenuButtonWithTitle(IDS_PERMISSION_ALLOW);
278   NSButton* menu_b = FindMenuButtonWithTitle(IDS_PERMISSION_DENY);
279   ChangePermissionMenuSelection(menu_a, IDS_PERMISSION_DENY);
280   ChangePermissionMenuSelection(menu_b, IDS_PERMISSION_ALLOW);
281 }
282
283 TEST_F(PermissionBubbleControllerTest, ClickCustomize) {
284   AddRequest(kPermissionB);
285   [controller_ showAtAnchor:NSZeroPoint
286               withDelegate:this
287                forRequests:requests_
288               acceptStates:accept_states_
289          customizationMode:NO];
290
291   EXPECT_CALL(*this, SetCustomizationMode()).Times(1);
292   NSMenuItem* customize_item = FindCustomizeMenuItem();
293   EXPECT_TRUE(customize_item);
294   NSMenu* menu = [customize_item menu];
295   [menu performActionForItemAtIndex:[menu indexOfItem:customize_item]];
296 }