| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "chrome/browser/ui/cocoa/permission_bubble/permission_bubble_controller.
h" | 5 #import "chrome/browser/ui/cocoa/permission_bubble/permission_bubble_controller.
h" |
| 6 | 6 |
| 7 #include <Carbon/Carbon.h> | 7 #include <Carbon/Carbon.h> |
| 8 | 8 |
| 9 #include "base/mac/foundation_util.h" | 9 #include "base/mac/foundation_util.h" |
| 10 #import "base/mac/scoped_objc_class_swizzler.h" | 10 #import "base/mac/scoped_objc_class_swizzler.h" |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 [controller_ close]; | 90 [controller_ close]; |
| 91 chrome::testing::NSRunLoopRunAllPending(); | 91 chrome::testing::NSRunLoopRunAllPending(); |
| 92 owned_requests_.clear(); | 92 owned_requests_.clear(); |
| 93 CocoaProfileTest::TearDown(); | 93 CocoaProfileTest::TearDown(); |
| 94 } | 94 } |
| 95 | 95 |
| 96 const std::vector<PermissionRequest*>& Requests() override { | 96 const std::vector<PermissionRequest*>& Requests() override { |
| 97 return requests_; | 97 return requests_; |
| 98 } | 98 } |
| 99 | 99 |
| 100 const std::vector<bool>& AcceptStates() override { return accept_states_; } | 100 const std::vector<bool>& AcceptStates() override { |
| 101 // TODO(crbug.com/728483): Remove this function. |
| 102 CR_DEFINE_STATIC_LOCAL(std::vector<bool>, accept_states, ()); |
| 103 return accept_states; |
| 104 } |
| 101 | 105 |
| 102 void AddRequest(const std::string& title) { | 106 void AddRequest(const std::string& title) { |
| 103 std::unique_ptr<MockPermissionRequest> request = | 107 std::unique_ptr<MockPermissionRequest> request = |
| 104 base::MakeUnique<MockPermissionRequest>( | 108 base::MakeUnique<MockPermissionRequest>( |
| 105 title, l10n_util::GetStringUTF8(IDS_PERMISSION_ALLOW), | 109 title, l10n_util::GetStringUTF8(IDS_PERMISSION_ALLOW), |
| 106 l10n_util::GetStringUTF8(IDS_PERMISSION_DENY)); | 110 l10n_util::GetStringUTF8(IDS_PERMISSION_DENY)); |
| 107 requests_.push_back(request.get()); | 111 requests_.push_back(request.get()); |
| 108 owned_requests_.push_back(std::move(request)); | 112 owned_requests_.push_back(std::move(request)); |
| 109 } | 113 } |
| 110 | 114 |
| 111 NSButton* FindButtonWithTitle(const std::string& title) { | 115 NSButton* FindButtonWithTitle(const std::string& title) { |
| 112 return FindButtonWithTitle(base::SysUTF8ToNSString(title), | 116 return FindButtonWithTitle(base::SysUTF8ToNSString(title), |
| 113 [ConstrainedWindowButton class]); | 117 [ConstrainedWindowButton class]); |
| 114 } | 118 } |
| 115 | 119 |
| 116 NSButton* FindButtonWithTitle(int title_id) { | 120 NSButton* FindButtonWithTitle(int title_id) { |
| 117 return FindButtonWithTitle(l10n_util::GetNSString(title_id), | 121 return FindButtonWithTitle(l10n_util::GetNSString(title_id), |
| 118 [ConstrainedWindowButton class]); | 122 [ConstrainedWindowButton class]); |
| 119 } | 123 } |
| 120 | 124 |
| 121 NSButton* FindMenuButtonWithTitle(int title_id) { | |
| 122 return FindButtonWithTitle(l10n_util::GetNSString(title_id), | |
| 123 [NSPopUpButton class]); | |
| 124 } | |
| 125 | |
| 126 // IDS_PERMISSION_ALLOW and IDS_PERMISSION_DENY are used for two distinct | 125 // IDS_PERMISSION_ALLOW and IDS_PERMISSION_DENY are used for two distinct |
| 127 // UI elements, both of which derive from NSButton. So check the expected | 126 // UI elements, both of which derive from NSButton. So check the expected |
| 128 // class, not just NSButton, as well as the title. | 127 // class, not just NSButton, as well as the title. |
| 129 NSButton* FindButtonWithTitle(NSString* title, Class button_class) { | 128 NSButton* FindButtonWithTitle(NSString* title, Class button_class) { |
| 130 for (NSButton* view in [[controller_ bubble] subviews]) { | 129 for (NSButton* view in [[controller_ bubble] subviews]) { |
| 131 if ([view isKindOfClass:button_class] && | 130 if ([view isKindOfClass:button_class] && |
| 132 [title isEqualToString:[view title]]) { | 131 [title isEqualToString:[view title]]) { |
| 133 return view; | 132 return view; |
| 134 } | 133 } |
| 135 } | 134 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 147 textField = base::mac::ObjCCast<NSTextField>(child); | 146 textField = base::mac::ObjCCast<NSTextField>(child); |
| 148 if (![[textField stringValue] hasSuffix:text]) { | 147 if (![[textField stringValue] hasSuffix:text]) { |
| 149 textField = FindTextFieldWithString(child, text); | 148 textField = FindTextFieldWithString(child, text); |
| 150 if (textField) | 149 if (textField) |
| 151 break; | 150 break; |
| 152 } | 151 } |
| 153 } | 152 } |
| 154 return textField; | 153 return textField; |
| 155 } | 154 } |
| 156 | 155 |
| 157 void ChangePermissionMenuSelection(NSButton* menu_button, int next_title_id) { | |
| 158 NSMenu* menu = [base::mac::ObjCCastStrict<NSPopUpButton>(menu_button) menu]; | |
| 159 NSString* next_title = l10n_util::GetNSString(next_title_id); | |
| 160 EXPECT_EQ([[menu itemWithTitle:[menu_button title]] state], NSOnState); | |
| 161 NSMenuItem* next_item = [menu itemWithTitle:next_title]; | |
| 162 EXPECT_EQ([next_item state], NSOffState); | |
| 163 [menu performActionForItemAtIndex:[menu indexOfItem:next_item]]; | |
| 164 } | |
| 165 | |
| 166 protected: | 156 protected: |
| 167 PermissionBubbleController* controller_; // Weak; it deletes itself. | 157 PermissionBubbleController* controller_; // Weak; it deletes itself. |
| 168 std::unique_ptr<PermissionBubbleCocoa> bridge_; | 158 std::unique_ptr<PermissionBubbleCocoa> bridge_; |
| 169 std::vector<PermissionRequest*> requests_; | 159 std::vector<PermissionRequest*> requests_; |
| 170 std::vector<std::unique_ptr<PermissionRequest>> owned_requests_; | 160 std::vector<std::unique_ptr<PermissionRequest>> owned_requests_; |
| 171 std::vector<bool> accept_states_; | 161 std::vector<bool> accept_states_; |
| 172 }; | 162 }; |
| 173 | 163 |
| 174 TEST_F(PermissionBubbleControllerTest, ShowAndClose) { | 164 TEST_F(PermissionBubbleControllerTest, ShowAndClose) { |
| 175 EXPECT_FALSE([[controller_ window] isVisible]); | 165 EXPECT_FALSE([[controller_ window] isVisible]); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 196 [controller_ close]; | 186 [controller_ close]; |
| 197 EXPECT_FALSE(decoration->active()); | 187 EXPECT_FALSE(decoration->active()); |
| 198 } | 188 } |
| 199 | 189 |
| 200 TEST_F(PermissionBubbleControllerTest, ShowSinglePermission) { | 190 TEST_F(PermissionBubbleControllerTest, ShowSinglePermission) { |
| 201 [controller_ showWithDelegate:this]; | 191 [controller_ showWithDelegate:this]; |
| 202 | 192 |
| 203 EXPECT_TRUE(FindTextFieldWithString(kPermissionA)); | 193 EXPECT_TRUE(FindTextFieldWithString(kPermissionA)); |
| 204 EXPECT_TRUE(FindButtonWithTitle(IDS_PERMISSION_ALLOW)); | 194 EXPECT_TRUE(FindButtonWithTitle(IDS_PERMISSION_ALLOW)); |
| 205 EXPECT_TRUE(FindButtonWithTitle(IDS_PERMISSION_DENY)); | 195 EXPECT_TRUE(FindButtonWithTitle(IDS_PERMISSION_DENY)); |
| 206 EXPECT_FALSE(FindButtonWithTitle(IDS_OK)); | |
| 207 } | 196 } |
| 208 | 197 |
| 209 TEST_F(PermissionBubbleControllerTest, ShowMultiplePermissions) { | 198 TEST_F(PermissionBubbleControllerTest, ShowMultiplePermissions) { |
| 210 AddRequest(kPermissionB); | 199 AddRequest(kPermissionB); |
| 211 AddRequest(kPermissionC); | 200 AddRequest(kPermissionC); |
| 212 | 201 |
| 213 accept_states_.push_back(true); // A | |
| 214 accept_states_.push_back(true); // B | |
| 215 accept_states_.push_back(true); // C | |
| 216 | |
| 217 [controller_ showWithDelegate:this]; | 202 [controller_ showWithDelegate:this]; |
| 218 | 203 |
| 219 EXPECT_TRUE(FindTextFieldWithString(kPermissionA)); | 204 EXPECT_TRUE(FindTextFieldWithString(kPermissionA)); |
| 220 EXPECT_TRUE(FindTextFieldWithString(kPermissionB)); | 205 EXPECT_TRUE(FindTextFieldWithString(kPermissionB)); |
| 221 EXPECT_TRUE(FindTextFieldWithString(kPermissionC)); | 206 EXPECT_TRUE(FindTextFieldWithString(kPermissionC)); |
| 222 | 207 |
| 223 EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_ALLOW)); | 208 EXPECT_TRUE(FindButtonWithTitle(IDS_PERMISSION_ALLOW)); |
| 224 EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_DENY)); | 209 EXPECT_TRUE(FindButtonWithTitle(IDS_PERMISSION_DENY)); |
| 225 EXPECT_TRUE(FindButtonWithTitle(IDS_OK)); | |
| 226 } | |
| 227 | |
| 228 TEST_F(PermissionBubbleControllerTest, ShowMultiplePermissionsAllow) { | |
| 229 AddRequest(kPermissionB); | |
| 230 | |
| 231 accept_states_.push_back(true); // A | |
| 232 accept_states_.push_back(true); // B | |
| 233 | |
| 234 [controller_ showWithDelegate:this]; | |
| 235 | |
| 236 // Test that all menus have 'Allow' visible. | |
| 237 EXPECT_TRUE(FindMenuButtonWithTitle(IDS_PERMISSION_ALLOW)); | |
| 238 EXPECT_FALSE(FindMenuButtonWithTitle(IDS_PERMISSION_DENY)); | |
| 239 | |
| 240 EXPECT_TRUE(FindButtonWithTitle(IDS_OK)); | |
| 241 EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_ALLOW)); | |
| 242 EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_DENY)); | |
| 243 } | |
| 244 | |
| 245 TEST_F(PermissionBubbleControllerTest, ShowMultiplePermissionsBlock) { | |
| 246 AddRequest(kPermissionB); | |
| 247 | |
| 248 accept_states_.push_back(false); // A | |
| 249 accept_states_.push_back(false); // B | |
| 250 | |
| 251 [controller_ showWithDelegate:this]; | |
| 252 | |
| 253 // Test that all menus have 'Block' visible. | |
| 254 EXPECT_TRUE(FindMenuButtonWithTitle(IDS_PERMISSION_DENY)); | |
| 255 EXPECT_FALSE(FindMenuButtonWithTitle(IDS_PERMISSION_ALLOW)); | |
| 256 | |
| 257 EXPECT_TRUE(FindButtonWithTitle(IDS_OK)); | |
| 258 EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_ALLOW)); | |
| 259 EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_DENY)); | |
| 260 } | |
| 261 | |
| 262 TEST_F(PermissionBubbleControllerTest, ShowMultiplePermissionsMixed) { | |
| 263 AddRequest(kPermissionB); | |
| 264 AddRequest(kPermissionC); | |
| 265 | |
| 266 accept_states_.push_back(false); // A | |
| 267 accept_states_.push_back(false); // B | |
| 268 accept_states_.push_back(true); // C | |
| 269 | |
| 270 [controller_ showWithDelegate:this]; | |
| 271 | |
| 272 // Test that both 'allow' and 'deny' are visible. | |
| 273 EXPECT_TRUE(FindMenuButtonWithTitle(IDS_PERMISSION_DENY)); | |
| 274 EXPECT_TRUE(FindMenuButtonWithTitle(IDS_PERMISSION_ALLOW)); | |
| 275 | |
| 276 EXPECT_TRUE(FindButtonWithTitle(IDS_OK)); | |
| 277 EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_ALLOW)); | |
| 278 EXPECT_FALSE(FindButtonWithTitle(IDS_PERMISSION_DENY)); | |
| 279 } | |
| 280 | |
| 281 TEST_F(PermissionBubbleControllerTest, OK) { | |
| 282 AddRequest(kPermissionB); | |
| 283 | |
| 284 accept_states_.push_back(true); // A | |
| 285 accept_states_.push_back(true); // B | |
| 286 | |
| 287 [controller_ showWithDelegate:this]; | |
| 288 | |
| 289 EXPECT_CALL(*this, Accept()).Times(1); | |
| 290 [FindButtonWithTitle(IDS_OK) performClick:nil]; | |
| 291 } | 210 } |
| 292 | 211 |
| 293 TEST_F(PermissionBubbleControllerTest, Allow) { | 212 TEST_F(PermissionBubbleControllerTest, Allow) { |
| 294 [controller_ showWithDelegate:this]; | 213 [controller_ showWithDelegate:this]; |
| 295 | 214 |
| 296 EXPECT_CALL(*this, Accept()).Times(1); | 215 EXPECT_CALL(*this, Accept()).Times(1); |
| 216 [FindButtonWithTitle(IDS_PERMISSION_ALLOW) performClick:nil]; |
| 217 } |
| 218 |
| 219 TEST_F(PermissionBubbleControllerTest, AllowMultiple) { |
| 220 AddRequest(kPermissionB); |
| 221 |
| 222 [controller_ showWithDelegate:this]; |
| 223 |
| 224 EXPECT_CALL(*this, Accept()).Times(1); |
| 297 [FindButtonWithTitle(IDS_PERMISSION_ALLOW) performClick:nil]; | 225 [FindButtonWithTitle(IDS_PERMISSION_ALLOW) performClick:nil]; |
| 298 } | 226 } |
| 299 | 227 |
| 300 TEST_F(PermissionBubbleControllerTest, Deny) { | 228 TEST_F(PermissionBubbleControllerTest, Deny) { |
| 301 [controller_ showWithDelegate:this]; | 229 [controller_ showWithDelegate:this]; |
| 302 | 230 |
| 303 EXPECT_CALL(*this, Deny()).Times(1); | 231 EXPECT_CALL(*this, Deny()).Times(1); |
| 304 [FindButtonWithTitle(IDS_PERMISSION_DENY) performClick:nil]; | 232 [FindButtonWithTitle(IDS_PERMISSION_DENY) performClick:nil]; |
| 305 } | 233 } |
| 306 | 234 |
| 307 TEST_F(PermissionBubbleControllerTest, ChangePermissionSelection) { | 235 TEST_F(PermissionBubbleControllerTest, DenyMultiple) { |
| 308 AddRequest(kPermissionB); | 236 AddRequest(kPermissionB); |
| 309 | 237 |
| 310 accept_states_.push_back(true); // A | |
| 311 accept_states_.push_back(false); // B | |
| 312 | |
| 313 [controller_ showWithDelegate:this]; | 238 [controller_ showWithDelegate:this]; |
| 314 | 239 |
| 315 EXPECT_CALL(*this, ToggleAccept(0, false)).Times(1); | 240 EXPECT_CALL(*this, Deny()).Times(1); |
| 316 EXPECT_CALL(*this, ToggleAccept(1, true)).Times(1); | 241 [FindButtonWithTitle(IDS_PERMISSION_DENY) performClick:nil]; |
| 317 NSButton* menu_a = FindMenuButtonWithTitle(IDS_PERMISSION_ALLOW); | |
| 318 NSButton* menu_b = FindMenuButtonWithTitle(IDS_PERMISSION_DENY); | |
| 319 ChangePermissionMenuSelection(menu_a, IDS_PERMISSION_DENY); | |
| 320 ChangePermissionMenuSelection(menu_b, IDS_PERMISSION_ALLOW); | |
| 321 } | 242 } |
| 322 | 243 |
| 323 TEST_F(PermissionBubbleControllerTest, EscapeCloses) { | 244 TEST_F(PermissionBubbleControllerTest, EscapeCloses) { |
| 324 [controller_ showWithDelegate:this]; | 245 [controller_ showWithDelegate:this]; |
| 325 | 246 |
| 326 EXPECT_TRUE([[controller_ window] isVisible]); | 247 EXPECT_TRUE([[controller_ window] isVisible]); |
| 327 [[controller_ window] | 248 [[controller_ window] |
| 328 performKeyEquivalent:cocoa_test_event_utils::KeyEventWithKeyCode( | 249 performKeyEquivalent:cocoa_test_event_utils::KeyEventWithKeyCode( |
| 329 kVK_Escape, '\e', NSKeyDown, 0)]; | 250 kVK_Escape, '\e', NSKeyDown, 0)]; |
| 330 EXPECT_FALSE([[controller_ window] isVisible]); | 251 EXPECT_FALSE([[controller_ window] isVisible]); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 base::mac::ScopedObjCClassSwizzler locationSwizzle( | 328 base::mac::ScopedObjCClassSwizzler locationSwizzle( |
| 408 [PermissionBubbleController class], [MockBubbleNoLocationBar class], | 329 [PermissionBubbleController class], [MockBubbleNoLocationBar class], |
| 409 @selector(hasVisibleLocationBarForBrowser:)); | 330 @selector(hasVisibleLocationBarForBrowser:)); |
| 410 withoutLocationBar = [controller_ getExpectedAnchorPoint]; | 331 withoutLocationBar = [controller_ getExpectedAnchorPoint]; |
| 411 } | 332 } |
| 412 | 333 |
| 413 // The bubble should be in different places depending if the location bar is | 334 // The bubble should be in different places depending if the location bar is |
| 414 // available or not. | 335 // available or not. |
| 415 EXPECT_NSNE(withLocationBar, withoutLocationBar); | 336 EXPECT_NSNE(withLocationBar, withoutLocationBar); |
| 416 } | 337 } |
| OLD | NEW |