Check USB device path access when prompting users to select a device.
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / website_settings / permission_bubble_controller_unittest.mm
blob1699a4912d516c5f63891ecc21bd93ec68ac187c
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.
5 #import "chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.h"
7 #include <Carbon/Carbon.h>
9 #include "base/mac/foundation_util.h"
10 #include "base/stl_util.h"
11 #include "base/strings/sys_string_conversions.h"
12 #include "base/strings/utf_string_conversions.h"
13 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
14 #include "chrome/browser/ui/cocoa/run_loop_testing.h"
15 #import "chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.h"
16 #import "chrome/browser/ui/cocoa/website_settings/split_block_button.h"
17 #include "chrome/browser/ui/website_settings/mock_permission_bubble_request.h"
18 #include "chrome/grit/generated_resources.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "ui/base/l10n/l10n_util.h"
21 #include "ui/base/l10n/l10n_util_mac.h"
22 #import "ui/events/test/cocoa_test_event_utils.h"
24 @class ConstrainedWindowButton;
26 @interface PermissionBubbleController (ExposedForTesting)
27 - (void)ok:(id)sender;
28 - (void)onAllow:(id)sender;
29 - (void)onBlock:(id)sender;
30 - (void)onCustomize:(id)sender;
31 - (void)onCheckboxChanged:(id)sender;
32 @end
34 @interface SplitBlockButton (ExposedForTesting)
35 - (NSMenu*)menu;
36 @end
38 namespace {
39 const char* const kPermissionA = "Permission A";
40 const char* const kPermissionB = "Permission B";
41 const char* const kPermissionC = "Permission C";
44 class PermissionBubbleControllerTest : public CocoaTest,
45   public PermissionBubbleView::Delegate {
46  public:
48   MOCK_METHOD2(ToggleAccept, void(int, bool));
49   MOCK_METHOD0(SetCustomizationMode, void());
50   MOCK_METHOD0(Accept, void());
51   MOCK_METHOD0(Deny, void());
52   MOCK_METHOD0(Closing, void());
53   MOCK_METHOD1(SetView, void(PermissionBubbleView*));
55   virtual void SetUp() override {
56     CocoaTest::SetUp();
57     bridge_.reset(new PermissionBubbleCocoa(nil));
58     AddRequest(kPermissionA);
59     controller_ = [[PermissionBubbleController alloc]
60         initWithParentWindow:test_window()
61                       bridge:bridge_.get()];
62   }
64   virtual void TearDown() override {
65     [controller_ close];
66     chrome::testing::NSRunLoopRunAllPending();
67     STLDeleteElements(&requests_);
68     CocoaTest::TearDown();
69   }
71   void AddRequest(const std::string& title) {
72     MockPermissionBubbleRequest* request = new MockPermissionBubbleRequest(
73         title,
74         l10n_util::GetStringUTF8(IDS_PERMISSION_ALLOW),
75         l10n_util::GetStringUTF8(IDS_PERMISSION_DENY));
76     requests_.push_back(request);
77   }
79   NSButton* FindButtonWithTitle(const std::string& title) {
80     return FindButtonWithTitle(base::SysUTF8ToNSString(title),
81                                [ConstrainedWindowButton class]);
82   }
84   NSButton* FindButtonWithTitle(int title_id) {
85     return FindButtonWithTitle(l10n_util::GetNSString(title_id),
86                                [ConstrainedWindowButton class]);
87   }
89   NSButton* FindMenuButtonWithTitle(int title_id) {
90     return FindButtonWithTitle(l10n_util::GetNSString(title_id),
91                                [NSPopUpButton class]);
92   }
94   // IDS_PERMISSION_ALLOW and IDS_PERMISSION_DENY are used for two distinct
95   // UI elements, both of which derive from NSButton.  So check the expected
96   // class, not just NSButton, as well as the title.
97   NSButton* FindButtonWithTitle(NSString* title, Class button_class) {
98     for (NSButton* view in [[controller_ bubble] subviews]) {
99       if ([view isKindOfClass:button_class] &&
100           [title isEqualToString:[view title]]) {
101         return view;
102       }
103     }
104     return nil;
105   }
107   NSTextField* FindTextFieldWithString(const std::string& text) {
108     NSView* parent = base::mac::ObjCCastStrict<NSView>([controller_ bubble]);
109     return FindTextFieldWithString(parent, base::SysUTF8ToNSString(text));
110   }
112   NSTextField* FindTextFieldWithString(NSView* view, NSString* text) {
113     NSTextField* textField = nil;
114     for (NSView* child in [view subviews]) {
115       textField = base::mac::ObjCCast<NSTextField>(child);
116       if (![[textField stringValue] hasSuffix:text]) {
117         textField = FindTextFieldWithString(child, text);
118         if (textField)
119           break;
120       }
121     }
122     return textField;
123   }
125   void ChangePermissionMenuSelection(NSButton* menu_button, int next_title_id) {
126     NSMenu* menu = [base::mac::ObjCCastStrict<NSPopUpButton>(menu_button) menu];
127     NSString* next_title = l10n_util::GetNSString(next_title_id);
128     EXPECT_EQ([[menu itemWithTitle:[menu_button title]] state], NSOnState);
129     NSMenuItem* next_item = [menu itemWithTitle:next_title];
130     EXPECT_EQ([next_item state], NSOffState);
131     [menu performActionForItemAtIndex:[menu indexOfItem:next_item]];
132   }
134  protected:
135   PermissionBubbleController* controller_;  // Weak;  it deletes itself.
136   scoped_ptr<PermissionBubbleCocoa> bridge_;
137   std::vector<PermissionBubbleRequest*> requests_;
138   std::vector<bool> accept_states_;
141 TEST_F(PermissionBubbleControllerTest, ShowAndClose) {
142   EXPECT_FALSE([[controller_ window] isVisible]);
143   [controller_ showWindow:nil];
144   EXPECT_TRUE([[controller_ window] isVisible]);
147 TEST_F(PermissionBubbleControllerTest, ShowSinglePermission) {
148   [controller_ showAtAnchor:NSZeroPoint
149               withDelegate:this
150                forRequests:requests_
151               acceptStates:accept_states_];
153   EXPECT_TRUE(FindTextFieldWithString(kPermissionA));
154   EXPECT_TRUE(FindButtonWithTitle(IDS_PERMISSION_ALLOW));
155   EXPECT_TRUE(FindButtonWithTitle(IDS_PERMISSION_DENY));
156   EXPECT_FALSE(FindButtonWithTitle(IDS_OK));
159 TEST_F(PermissionBubbleControllerTest, ShowMultiplePermissions) {
160   AddRequest(kPermissionB);
161   AddRequest(kPermissionC);
163   accept_states_.push_back(true);  // A
164   accept_states_.push_back(true);  // B
165   accept_states_.push_back(true);  // C
167   [controller_ showAtAnchor:NSZeroPoint
168               withDelegate:this
169                forRequests:requests_
170               acceptStates:accept_states_];
172   EXPECT_TRUE(FindTextFieldWithString(kPermissionA));
173   EXPECT_TRUE(FindTextFieldWithString(kPermissionB));
174   EXPECT_TRUE(FindTextFieldWithString(kPermissionC));
176   EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_ALLOW));
177   EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_DENY));
178   EXPECT_TRUE(FindButtonWithTitle(IDS_OK));
181 TEST_F(PermissionBubbleControllerTest, ShowMultiplePermissionsAllow) {
182   AddRequest(kPermissionB);
184   accept_states_.push_back(true);  // A
185   accept_states_.push_back(true);  // B
187   [controller_ showAtAnchor:NSZeroPoint
188                withDelegate:this
189                 forRequests:requests_
190                acceptStates:accept_states_];
192   // Test that all menus have 'Allow' visible.
193   EXPECT_TRUE(FindMenuButtonWithTitle(IDS_PERMISSION_ALLOW));
194   EXPECT_FALSE(FindMenuButtonWithTitle(IDS_PERMISSION_DENY));
196   EXPECT_TRUE(FindButtonWithTitle(IDS_OK));
197   EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_ALLOW));
198   EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_DENY));
201 TEST_F(PermissionBubbleControllerTest, ShowMultiplePermissionsBlock) {
202   AddRequest(kPermissionB);
204   accept_states_.push_back(false);  // A
205   accept_states_.push_back(false);  // B
207   [controller_ showAtAnchor:NSZeroPoint
208               withDelegate:this
209                forRequests:requests_
210               acceptStates:accept_states_];
212   // Test that all menus have 'Block' visible.
213   EXPECT_TRUE(FindMenuButtonWithTitle(IDS_PERMISSION_DENY));
214   EXPECT_FALSE(FindMenuButtonWithTitle(IDS_PERMISSION_ALLOW));
216   EXPECT_TRUE(FindButtonWithTitle(IDS_OK));
217   EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_ALLOW));
218   EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_DENY));
221 TEST_F(PermissionBubbleControllerTest, ShowMultiplePermissionsMixed) {
222   AddRequest(kPermissionB);
223   AddRequest(kPermissionC);
225   accept_states_.push_back(false);  // A
226   accept_states_.push_back(false);  // B
227   accept_states_.push_back(true);   // C
229   [controller_ showAtAnchor:NSZeroPoint
230               withDelegate:this
231                forRequests:requests_
232               acceptStates:accept_states_];
234   // Test that both 'allow' and 'deny' are visible.
235   EXPECT_TRUE(FindMenuButtonWithTitle(IDS_PERMISSION_DENY));
236   EXPECT_TRUE(FindMenuButtonWithTitle(IDS_PERMISSION_ALLOW));
238   EXPECT_TRUE(FindButtonWithTitle(IDS_OK));
239   EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_ALLOW));
240   EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_DENY));
243 TEST_F(PermissionBubbleControllerTest, OK) {
244   AddRequest(kPermissionB);
246   accept_states_.push_back(true);  // A
247   accept_states_.push_back(true);  // B
249   [controller_ showAtAnchor:NSZeroPoint
250               withDelegate:this
251                forRequests:requests_
252               acceptStates:accept_states_];
254   EXPECT_CALL(*this, Accept()).Times(1);
255   [FindButtonWithTitle(IDS_OK) performClick:nil];
258 TEST_F(PermissionBubbleControllerTest, Allow) {
259   [controller_ showAtAnchor:NSZeroPoint
260               withDelegate:this
261                forRequests:requests_
262               acceptStates:accept_states_];
264   EXPECT_CALL(*this, Accept()).Times(1);
265   [FindButtonWithTitle(IDS_PERMISSION_ALLOW) performClick:nil];
268 TEST_F(PermissionBubbleControllerTest, Deny) {
269   [controller_ showAtAnchor:NSZeroPoint
270               withDelegate:this
271                forRequests:requests_
272               acceptStates:accept_states_];
274   EXPECT_CALL(*this, Deny()).Times(1);
275   [FindButtonWithTitle(IDS_PERMISSION_DENY) performClick:nil];
278 TEST_F(PermissionBubbleControllerTest, ChangePermissionSelection) {
279   AddRequest(kPermissionB);
281   accept_states_.push_back(true);   // A
282   accept_states_.push_back(false);  // B
284   [controller_ showAtAnchor:NSZeroPoint
285               withDelegate:this
286                forRequests:requests_
287               acceptStates:accept_states_];
289   EXPECT_CALL(*this, ToggleAccept(0, false)).Times(1);
290   EXPECT_CALL(*this, ToggleAccept(1, true)).Times(1);
291   NSButton* menu_a = FindMenuButtonWithTitle(IDS_PERMISSION_ALLOW);
292   NSButton* menu_b = FindMenuButtonWithTitle(IDS_PERMISSION_DENY);
293   ChangePermissionMenuSelection(menu_a, IDS_PERMISSION_DENY);
294   ChangePermissionMenuSelection(menu_b, IDS_PERMISSION_ALLOW);
297 TEST_F(PermissionBubbleControllerTest, EscapeCloses) {
298   [controller_ showAtAnchor:NSZeroPoint
299                withDelegate:this
300                 forRequests:requests_
301                acceptStates:accept_states_];
303   EXPECT_TRUE([[controller_ window] isVisible]);
304   [[controller_ window]
305       performKeyEquivalent:cocoa_test_event_utils::KeyEventWithKeyCode(
306                                kVK_Escape, '\e', NSKeyDown, 0)];
307   EXPECT_FALSE([[controller_ window] isVisible]);