Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(134)

Side by Side Diff: chrome/browser/ui/cocoa/website_settings/permission_bubble_controller_unittest.mm

Issue 2748443005: Rename website_settings UI folders to permission_bubble. (Closed)
Patch Set: Rebase. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 <Carbon/Carbon.h>
8
9 #include "base/mac/foundation_util.h"
10 #import "base/mac/scoped_objc_class_swizzler.h"
11 #include "base/mac/sdk_forward_declarations.h"
12 #include "base/memory/ptr_util.h"
13 #include "base/strings/sys_string_conversions.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "chrome/browser/permissions/mock_permission_request.h"
16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/browser_window.h"
18 #include "chrome/browser/ui/cocoa/browser_window_controller.h"
19 #include "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
20 #import "chrome/browser/ui/cocoa/page_info/split_block_button.h"
21 #import "chrome/browser/ui/cocoa/test/cocoa_profile_test.h"
22 #include "chrome/browser/ui/cocoa/test/run_loop_testing.h"
23 #import "chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.h"
24 #include "chrome/grit/generated_resources.h"
25 #include "components/strings/grit/components_strings.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #import "testing/gtest_mac.h"
28 #include "ui/base/cocoa/cocoa_base_utils.h"
29 #include "ui/base/l10n/l10n_util.h"
30 #include "ui/base/l10n/l10n_util_mac.h"
31 #import "ui/events/test/cocoa_test_event_utils.h"
32
33 @class ConstrainedWindowButton;
34
35 @interface PermissionBubbleController (ExposedForTesting)
36 - (void)ok:(id)sender;
37 - (void)onAllow:(id)sender;
38 - (void)onBlock:(id)sender;
39 - (void)onCustomize:(id)sender;
40 - (void)onCheckboxChanged:(id)sender;
41 + (NSInteger)getFullscreenLeftOffset;
42 @end
43
44 @interface SplitBlockButton (ExposedForTesting)
45 - (NSMenu*)menu;
46 @end
47
48 @interface MockBubbleYesLocationBar : NSObject
49 @end
50
51 @implementation MockBubbleYesLocationBar
52 + (bool)hasVisibleLocationBarForBrowser:(Browser*)browser { return true; }
53 @end
54
55 @interface MockBubbleNoLocationBar : NSObject
56 @end
57
58 @implementation MockBubbleNoLocationBar
59 + (bool)hasVisibleLocationBarForBrowser:(Browser*)browser { return false; }
60 @end
61
62 namespace {
63 const char* const kPermissionA = "Permission A";
64 const char* const kPermissionB = "Permission B";
65 const char* const kPermissionC = "Permission C";
66 }
67
68 class PermissionBubbleControllerTest : public CocoaProfileTest,
69 public PermissionPrompt::Delegate {
70 public:
71
72 MOCK_METHOD2(ToggleAccept, void(int, bool));
73 MOCK_METHOD1(TogglePersist, void(bool));
74 MOCK_METHOD0(SetCustomizationMode, void());
75 MOCK_METHOD0(Accept, void());
76 MOCK_METHOD0(Deny, void());
77 MOCK_METHOD0(Closing, void());
78 MOCK_METHOD1(SetView, void(PermissionPrompt*));
79
80 void SetUp() override {
81 CocoaProfileTest::SetUp();
82 bridge_.reset(new PermissionBubbleCocoa(browser()));
83 AddRequest(kPermissionA);
84 controller_ =
85 [[PermissionBubbleController alloc] initWithBrowser:browser()
86 bridge:bridge_.get()];
87 }
88
89 void TearDown() override {
90 [controller_ close];
91 chrome::testing::NSRunLoopRunAllPending();
92 owned_requests_.clear();
93 CocoaProfileTest::TearDown();
94 }
95
96 void AddRequest(const std::string& title) {
97 std::unique_ptr<MockPermissionRequest> request =
98 base::MakeUnique<MockPermissionRequest>(
99 title, l10n_util::GetStringUTF8(IDS_PERMISSION_ALLOW),
100 l10n_util::GetStringUTF8(IDS_PERMISSION_DENY));
101 requests_.push_back(request.get());
102 owned_requests_.push_back(std::move(request));
103 }
104
105 NSButton* FindButtonWithTitle(const std::string& title) {
106 return FindButtonWithTitle(base::SysUTF8ToNSString(title),
107 [ConstrainedWindowButton class]);
108 }
109
110 NSButton* FindButtonWithTitle(int title_id) {
111 return FindButtonWithTitle(l10n_util::GetNSString(title_id),
112 [ConstrainedWindowButton class]);
113 }
114
115 NSButton* FindMenuButtonWithTitle(int title_id) {
116 return FindButtonWithTitle(l10n_util::GetNSString(title_id),
117 [NSPopUpButton class]);
118 }
119
120 // IDS_PERMISSION_ALLOW and IDS_PERMISSION_DENY are used for two distinct
121 // UI elements, both of which derive from NSButton. So check the expected
122 // class, not just NSButton, as well as the title.
123 NSButton* FindButtonWithTitle(NSString* title, Class button_class) {
124 for (NSButton* view in [[controller_ bubble] subviews]) {
125 if ([view isKindOfClass:button_class] &&
126 [title isEqualToString:[view title]]) {
127 return view;
128 }
129 }
130 return nil;
131 }
132
133 NSTextField* FindTextFieldWithString(const std::string& text) {
134 NSView* parent = base::mac::ObjCCastStrict<NSView>([controller_ bubble]);
135 return FindTextFieldWithString(parent, base::SysUTF8ToNSString(text));
136 }
137
138 NSTextField* FindTextFieldWithString(NSView* view, NSString* text) {
139 NSTextField* textField = nil;
140 for (NSView* child in [view subviews]) {
141 textField = base::mac::ObjCCast<NSTextField>(child);
142 if (![[textField stringValue] hasSuffix:text]) {
143 textField = FindTextFieldWithString(child, text);
144 if (textField)
145 break;
146 }
147 }
148 return textField;
149 }
150
151 void ChangePermissionMenuSelection(NSButton* menu_button, int next_title_id) {
152 NSMenu* menu = [base::mac::ObjCCastStrict<NSPopUpButton>(menu_button) menu];
153 NSString* next_title = l10n_util::GetNSString(next_title_id);
154 EXPECT_EQ([[menu itemWithTitle:[menu_button title]] state], NSOnState);
155 NSMenuItem* next_item = [menu itemWithTitle:next_title];
156 EXPECT_EQ([next_item state], NSOffState);
157 [menu performActionForItemAtIndex:[menu indexOfItem:next_item]];
158 }
159
160 protected:
161 PermissionBubbleController* controller_; // Weak; it deletes itself.
162 std::unique_ptr<PermissionBubbleCocoa> bridge_;
163 std::vector<PermissionRequest*> requests_;
164 std::vector<std::unique_ptr<PermissionRequest>> owned_requests_;
165 std::vector<bool> accept_states_;
166 };
167
168 TEST_F(PermissionBubbleControllerTest, ShowAndClose) {
169 EXPECT_FALSE([[controller_ window] isVisible]);
170 [controller_ showWindow:nil];
171 EXPECT_TRUE([[controller_ window] isVisible]);
172 }
173
174 TEST_F(PermissionBubbleControllerTest, ShowSinglePermission) {
175 [controller_ showWithDelegate:this
176 forRequests:requests_
177 acceptStates:accept_states_];
178
179 EXPECT_TRUE(FindTextFieldWithString(kPermissionA));
180 EXPECT_TRUE(FindButtonWithTitle(IDS_PERMISSION_ALLOW));
181 EXPECT_TRUE(FindButtonWithTitle(IDS_PERMISSION_DENY));
182 EXPECT_FALSE(FindButtonWithTitle(IDS_OK));
183 }
184
185 TEST_F(PermissionBubbleControllerTest, ShowMultiplePermissions) {
186 AddRequest(kPermissionB);
187 AddRequest(kPermissionC);
188
189 accept_states_.push_back(true); // A
190 accept_states_.push_back(true); // B
191 accept_states_.push_back(true); // C
192
193 [controller_ showWithDelegate:this
194 forRequests:requests_
195 acceptStates:accept_states_];
196
197 EXPECT_TRUE(FindTextFieldWithString(kPermissionA));
198 EXPECT_TRUE(FindTextFieldWithString(kPermissionB));
199 EXPECT_TRUE(FindTextFieldWithString(kPermissionC));
200
201 EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_ALLOW));
202 EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_DENY));
203 EXPECT_TRUE(FindButtonWithTitle(IDS_OK));
204 }
205
206 TEST_F(PermissionBubbleControllerTest, ShowMultiplePermissionsAllow) {
207 AddRequest(kPermissionB);
208
209 accept_states_.push_back(true); // A
210 accept_states_.push_back(true); // B
211
212 [controller_ showWithDelegate:this
213 forRequests:requests_
214 acceptStates:accept_states_];
215
216 // Test that all menus have 'Allow' visible.
217 EXPECT_TRUE(FindMenuButtonWithTitle(IDS_PERMISSION_ALLOW));
218 EXPECT_FALSE(FindMenuButtonWithTitle(IDS_PERMISSION_DENY));
219
220 EXPECT_TRUE(FindButtonWithTitle(IDS_OK));
221 EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_ALLOW));
222 EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_DENY));
223 }
224
225 TEST_F(PermissionBubbleControllerTest, ShowMultiplePermissionsBlock) {
226 AddRequest(kPermissionB);
227
228 accept_states_.push_back(false); // A
229 accept_states_.push_back(false); // B
230
231 [controller_ showWithDelegate:this
232 forRequests:requests_
233 acceptStates:accept_states_];
234
235 // Test that all menus have 'Block' visible.
236 EXPECT_TRUE(FindMenuButtonWithTitle(IDS_PERMISSION_DENY));
237 EXPECT_FALSE(FindMenuButtonWithTitle(IDS_PERMISSION_ALLOW));
238
239 EXPECT_TRUE(FindButtonWithTitle(IDS_OK));
240 EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_ALLOW));
241 EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_DENY));
242 }
243
244 TEST_F(PermissionBubbleControllerTest, ShowMultiplePermissionsMixed) {
245 AddRequest(kPermissionB);
246 AddRequest(kPermissionC);
247
248 accept_states_.push_back(false); // A
249 accept_states_.push_back(false); // B
250 accept_states_.push_back(true); // C
251
252 [controller_ showWithDelegate:this
253 forRequests:requests_
254 acceptStates:accept_states_];
255
256 // Test that both 'allow' and 'deny' are visible.
257 EXPECT_TRUE(FindMenuButtonWithTitle(IDS_PERMISSION_DENY));
258 EXPECT_TRUE(FindMenuButtonWithTitle(IDS_PERMISSION_ALLOW));
259
260 EXPECT_TRUE(FindButtonWithTitle(IDS_OK));
261 EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_ALLOW));
262 EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_DENY));
263 }
264
265 TEST_F(PermissionBubbleControllerTest, OK) {
266 AddRequest(kPermissionB);
267
268 accept_states_.push_back(true); // A
269 accept_states_.push_back(true); // B
270
271 [controller_ showWithDelegate:this
272 forRequests:requests_
273 acceptStates:accept_states_];
274
275 EXPECT_CALL(*this, Accept()).Times(1);
276 [FindButtonWithTitle(IDS_OK) performClick:nil];
277 }
278
279 TEST_F(PermissionBubbleControllerTest, Allow) {
280 [controller_ showWithDelegate:this
281 forRequests:requests_
282 acceptStates:accept_states_];
283
284 EXPECT_CALL(*this, Accept()).Times(1);
285 [FindButtonWithTitle(IDS_PERMISSION_ALLOW) performClick:nil];
286 }
287
288 TEST_F(PermissionBubbleControllerTest, Deny) {
289 [controller_ showWithDelegate:this
290 forRequests:requests_
291 acceptStates:accept_states_];
292
293 EXPECT_CALL(*this, Deny()).Times(1);
294 [FindButtonWithTitle(IDS_PERMISSION_DENY) performClick:nil];
295 }
296
297 TEST_F(PermissionBubbleControllerTest, ChangePermissionSelection) {
298 AddRequest(kPermissionB);
299
300 accept_states_.push_back(true); // A
301 accept_states_.push_back(false); // B
302
303 [controller_ showWithDelegate:this
304 forRequests:requests_
305 acceptStates:accept_states_];
306
307 EXPECT_CALL(*this, ToggleAccept(0, false)).Times(1);
308 EXPECT_CALL(*this, ToggleAccept(1, true)).Times(1);
309 NSButton* menu_a = FindMenuButtonWithTitle(IDS_PERMISSION_ALLOW);
310 NSButton* menu_b = FindMenuButtonWithTitle(IDS_PERMISSION_DENY);
311 ChangePermissionMenuSelection(menu_a, IDS_PERMISSION_DENY);
312 ChangePermissionMenuSelection(menu_b, IDS_PERMISSION_ALLOW);
313 }
314
315 TEST_F(PermissionBubbleControllerTest, EscapeCloses) {
316 [controller_ showWithDelegate:this
317 forRequests:requests_
318 acceptStates:accept_states_];
319
320 EXPECT_TRUE([[controller_ window] isVisible]);
321 [[controller_ window]
322 performKeyEquivalent:cocoa_test_event_utils::KeyEventWithKeyCode(
323 kVK_Escape, '\e', NSKeyDown, 0)];
324 EXPECT_FALSE([[controller_ window] isVisible]);
325 }
326
327 TEST_F(PermissionBubbleControllerTest, EnterFullscreen) {
328 [controller_ showWithDelegate:this
329 forRequests:requests_
330 acceptStates:accept_states_];
331
332 EXPECT_TRUE([[controller_ window] isVisible]);
333
334 // Post the "enter fullscreen" notification.
335 NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
336 [center postNotificationName:NSWindowWillEnterFullScreenNotification
337 object:test_window()];
338
339 EXPECT_TRUE([[controller_ window] isVisible]);
340 }
341
342 TEST_F(PermissionBubbleControllerTest, ExitFullscreen) {
343 [controller_ showWithDelegate:this
344 forRequests:requests_
345 acceptStates:accept_states_];
346
347 EXPECT_TRUE([[controller_ window] isVisible]);
348
349 // Post the "enter fullscreen" notification.
350 NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
351 [center postNotificationName:NSWindowWillExitFullScreenNotification
352 object:test_window()];
353
354 EXPECT_TRUE([[controller_ window] isVisible]);
355 }
356
357 TEST_F(PermissionBubbleControllerTest, AnchorPositionWithLocationBar) {
358 base::mac::ScopedObjCClassSwizzler locationSwizzle(
359 [PermissionBubbleController class], [MockBubbleYesLocationBar class],
360 @selector(hasVisibleLocationBarForBrowser:));
361
362 NSPoint anchor = [controller_ getExpectedAnchorPoint];
363
364 // Expected anchor location will be the same as the page info bubble.
365 NSWindow* window = browser()->window()->GetNativeWindow();
366 BrowserWindowController* controller =
367 [BrowserWindowController browserWindowControllerForWindow:window];
368 LocationBarViewMac* location_bar_bridge = [controller locationBarBridge];
369 NSPoint expected = location_bar_bridge->GetPageInfoBubblePoint();
370 expected = ui::ConvertPointFromWindowToScreen(window, expected);
371 EXPECT_NSEQ(expected, anchor);
372 }
373
374 TEST_F(PermissionBubbleControllerTest, AnchorPositionWithoutLocationBar) {
375 base::mac::ScopedObjCClassSwizzler locationSwizzle(
376 [PermissionBubbleController class], [MockBubbleNoLocationBar class],
377 @selector(hasVisibleLocationBarForBrowser:));
378
379 NSPoint anchor = [controller_ getExpectedAnchorPoint];
380
381 // Expected anchor location will be top left when there's no location bar.
382 NSWindow* window = browser()->window()->GetNativeWindow();
383 NSRect frame = [[window contentView] frame];
384 NSPoint expected = NSMakePoint(
385 NSMinX(frame) + [PermissionBubbleController getFullscreenLeftOffset],
386 NSMaxY(frame));
387 expected = ui::ConvertPointFromWindowToScreen(window, expected);
388 EXPECT_NSEQ(expected, anchor);
389 }
390
391 TEST_F(PermissionBubbleControllerTest,
392 AnchorPositionDifferentWithAndWithoutLocationBar) {
393 NSPoint withLocationBar;
394 {
395 base::mac::ScopedObjCClassSwizzler locationSwizzle(
396 [PermissionBubbleController class], [MockBubbleYesLocationBar class],
397 @selector(hasVisibleLocationBarForBrowser:));
398 withLocationBar = [controller_ getExpectedAnchorPoint];
399 }
400
401 NSPoint withoutLocationBar;
402 {
403 base::mac::ScopedObjCClassSwizzler locationSwizzle(
404 [PermissionBubbleController class], [MockBubbleNoLocationBar class],
405 @selector(hasVisibleLocationBarForBrowser:));
406 withoutLocationBar = [controller_ getExpectedAnchorPoint];
407 }
408
409 // The bubble should be in different places depending if the location bar is
410 // available or not.
411 EXPECT_NSNE(withLocationBar, withoutLocationBar);
412 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698