Index: chrome/browser/ui/cocoa/permission_bubble_controller_unittest.mm |
diff --git a/chrome/browser/ui/cocoa/permission_bubble_controller_unittest.mm b/chrome/browser/ui/cocoa/permission_bubble_controller_unittest.mm |
new file mode 100644 |
index 0000000000000000000000000000000000000000..792224b560ccd5f7159ba42869267cf6932cecdd |
--- /dev/null |
+++ b/chrome/browser/ui/cocoa/permission_bubble_controller_unittest.mm |
@@ -0,0 +1,294 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#import "chrome/browser/ui/cocoa/permission_bubble_controller.h" |
+ |
+#include "base/strings/sys_string_conversions.h" |
+#include "base/strings/utf_string_conversions.h" |
+#import "chrome/browser/ui/cocoa/cocoa_test_helper.h" |
+#import "chrome/browser/ui/cocoa/permission_bubble_cocoa.h" |
+#include "chrome/browser/ui/cocoa/run_loop_testing.h" |
+#include "chrome/browser/ui/website_settings/mock_permission_bubble_delegate.h" |
+ |
+@interface PermissionBubbleController (ExposedForTesting) |
+- (void)ok; |
+- (void)allow; |
+- (void)block; |
+- (void)customize; |
+- (void)checkboxChanged:(id)sender; |
+@end |
+ |
+class PermissionBubbleControllerTest : public CocoaTest, |
+ public PermissionBubbleView::Delegate { |
+ public: |
+ |
+ MOCK_METHOD2(ToggleAccept, void(int, bool)); |
+ MOCK_METHOD0(SetCustomizationMode, void()); |
+ MOCK_METHOD0(Accept, void()); |
+ MOCK_METHOD0(Deny, void()); |
+ MOCK_METHOD0(Closing, void()); |
+ |
+ virtual void SetUp() OVERRIDE { |
+ CocoaTest::SetUp(); |
+ bridge_.reset(new PermissionBubbleCocoa(nil)); |
+ controller_ = [[PermissionBubbleController alloc] |
+ initWithParentWindow:test_window() |
+ bridge:bridge_.get()]; |
+ } |
+ |
+ virtual void TearDown() OVERRIDE { |
+ [controller_ close]; |
+ chrome::testing::NSRunLoopRunAllPending(); |
+ CocoaTest::TearDown(); |
+ } |
+ |
+ NSButton* FindButtonWithTitle(NSView* parent, |
+ const base::string16& text) { |
+ NSString* title = base::SysUTF16ToNSString(text); |
+ for (NSView* child in [parent subviews]) { |
+ if ([child isKindOfClass:[NSButton class]]) { |
+ NSButton* button = (NSButton*)child; |
groby-ooo-7-16
2014/01/31 22:31:51
base::ObjCCast
leng
2014/02/03 22:38:04
Done.
|
+ if ([title isEqualToString:[button title]]) { |
+ return button; |
+ } |
+ } |
+ } |
+ return nil; |
+ } |
+ |
+ NSTextField* FindTextFieldWithString(NSView* parent, |
+ const base::string16& text, |
+ BOOL exactMatch) { |
+ NSString* title = base::SysUTF16ToNSString(text); |
+ for (NSView* child in [parent subviews]) { |
+ if ([child isKindOfClass:[NSTextField class]]) { |
+ NSTextField* textField = (NSTextField*)child; |
+ // When multiple requests are made, a bullet point will be inserted |
+ // at the beginning of every line. So in that case, only a partial |
+ // match is required. For a single request, expect an exact match. |
groby-ooo-7-16
2014/01/31 22:31:51
You can probably always test hasSuffix and skip th
leng
2014/02/03 22:38:04
You're right.
Done.
|
+ if ([title isEqualToString:[textField stringValue]]) { |
+ return textField; |
+ } else if (!exactMatch && [[textField stringValue] hasSuffix:title]) { |
+ return textField; |
+ } |
+ } |
+ } |
+ return nil; |
+ } |
+ |
+ protected: |
+ PermissionBubbleController* controller_; // Weak; it deletes itself. |
+ scoped_ptr<PermissionBubbleCocoa> bridge_; |
+}; |
+ |
+TEST_F(PermissionBubbleControllerTest, ShowAndClose) { |
+ EXPECT_FALSE([[controller_ window] isVisible]); |
+ [controller_ showWindow:nil]; |
+ EXPECT_TRUE([[controller_ window] isVisible]); |
+} |
+ |
+TEST_F(PermissionBubbleControllerTest, ShowSinglePermission) { |
+ MockPermissionBubbleDelegate delegate_a; |
+ base::string16 permission_a = base::UTF8ToUTF16("Permission A"); |
+ delegate_a.SetText(permission_a); |
+ EXPECT_CALL(delegate_a, GetMessageTextFragment()).Times(1); |
+ |
+ std::vector<PermissionBubbleDelegate*> requests; |
+ requests.push_back(&delegate_a); |
+ std::vector<bool> acceptStates; |
+ |
+ [controller_ showAtAnchor:NSMakePoint(0, 0) |
groby-ooo-7-16
2014/01/31 22:31:51
NSZeroPoint
leng
2014/02/03 22:38:04
Done.
|
+ withDelegate:this |
+ forRequests:requests |
+ acceptStates:acceptStates |
+ customizationMode:NO]; |
+ |
+ NSView* bubble = (NSView*)[controller_ bubble]; |
+ NSTextField* textField = FindTextFieldWithString(bubble, permission_a, true); |
groby-ooo-7-16
2014/01/31 22:31:51
Since the fixture has controller_, and you never s
leng
2014/02/03 22:38:04
Done. It's much simpler now, thanks!
|
+ EXPECT_TRUE(textField); |
+ NSButton* allowButton = |
+ FindButtonWithTitle(bubble, base::UTF8ToUTF16("Allow")); |
+ EXPECT_TRUE(allowButton); |
+ NSButton* blockButton = |
+ FindButtonWithTitle(bubble, base::UTF8ToUTF16("Block")); |
+ EXPECT_TRUE(blockButton); |
+ NSButton* okButton = FindButtonWithTitle(bubble, base::UTF8ToUTF16("OK")); |
+ EXPECT_FALSE(okButton); |
+} |
+ |
+TEST_F(PermissionBubbleControllerTest, ShowMultiplePermissions) { |
+ MockPermissionBubbleDelegate delegate_a; |
+ MockPermissionBubbleDelegate delegate_b; |
+ MockPermissionBubbleDelegate delegate_c; |
+ base::string16 permission_a = base::UTF8ToUTF16("Permission A"); |
+ base::string16 permission_b = base::UTF8ToUTF16("Permission B"); |
+ base::string16 permission_c = base::UTF8ToUTF16("Permission C"); |
+ delegate_a.SetText(permission_a); |
groby-ooo-7-16
2014/01/31 22:31:51
Is it possible to take the text in the ctor? And d
leng
2014/02/03 22:38:04
Done. Fewer lines of code is better, especially i
|
+ delegate_b.SetText(permission_b); |
+ delegate_c.SetText(permission_c); |
+ EXPECT_CALL(delegate_a, GetMessageTextFragment()).Times(1); |
+ EXPECT_CALL(delegate_b, GetMessageTextFragment()).Times(1); |
+ EXPECT_CALL(delegate_c, GetMessageTextFragment()).Times(1); |
+ |
+ std::vector<PermissionBubbleDelegate*> requests; |
+ requests.push_back(&delegate_a); |
+ requests.push_back(&delegate_b); |
+ requests.push_back(&delegate_c); |
+ std::vector<bool> acceptStates; |
+ |
+ [controller_ showAtAnchor:NSMakePoint(0, 0) |
+ withDelegate:this |
+ forRequests:requests |
+ acceptStates:acceptStates |
+ customizationMode:NO]; |
+ |
+ NSView* bubble = (NSView*)[controller_ bubble]; |
+ NSTextField* textField = FindTextFieldWithString(bubble, permission_a, false); |
+ EXPECT_TRUE(textField); |
+ textField = FindTextFieldWithString(bubble, permission_b, false); |
+ EXPECT_TRUE(textField); |
+ textField = FindTextFieldWithString(bubble, permission_c, false); |
+ EXPECT_TRUE(textField); |
+ |
+ NSButton* allowButton = FindButtonWithTitle(bubble, |
+ base::UTF8ToUTF16("Allow")); |
+ EXPECT_TRUE(allowButton); |
+ NSButton* blockButton = FindButtonWithTitle(bubble, |
+ base::UTF8ToUTF16("Block")); |
+ EXPECT_TRUE(blockButton); |
+ NSButton* okButton = FindButtonWithTitle(bubble, base::UTF8ToUTF16("OK")); |
+ EXPECT_FALSE(okButton); |
+} |
+ |
+TEST_F(PermissionBubbleControllerTest, ShowCustomizationMode) { |
+ MockPermissionBubbleDelegate delegate_a; |
+ MockPermissionBubbleDelegate delegate_b; |
+ base::string16 permission_a = base::UTF8ToUTF16("Permission A"); |
+ base::string16 permission_b = base::UTF8ToUTF16("Permission B"); |
+ delegate_a.SetText(permission_a); |
+ delegate_b.SetText(permission_b); |
+ EXPECT_CALL(delegate_a, GetMessageTextFragment()).Times(1); |
+ EXPECT_CALL(delegate_b, GetMessageTextFragment()).Times(1); |
+ |
+ std::vector<PermissionBubbleDelegate*> requests; |
+ requests.push_back(&delegate_a); |
+ requests.push_back(&delegate_b); |
+ |
+ std::vector<bool> acceptStates; |
+ acceptStates.push_back(true); |
+ acceptStates.push_back(false); |
+ |
+ [controller_ showAtAnchor:NSMakePoint(0, 0) |
+ withDelegate:this |
+ forRequests:requests |
+ acceptStates:acceptStates |
+ customizationMode:YES]; |
+ |
+ // Test that each checkbox is visible and only the first is checked. |
+ NSView* bubble = (NSView*)[controller_ bubble]; |
+ NSButton* checkbox_a = FindButtonWithTitle(bubble, permission_a); |
+ NSButton* checkbox_b = FindButtonWithTitle(bubble, permission_b); |
+ EXPECT_TRUE(checkbox_a); |
+ EXPECT_TRUE(checkbox_b); |
+ EXPECT_EQ(NSOnState, [checkbox_a state]); |
+ EXPECT_EQ(NSOffState, [checkbox_b state]); |
+ |
+ NSButton* okButton = FindButtonWithTitle(bubble, base::UTF8ToUTF16("OK")); |
+ EXPECT_TRUE(okButton); |
+ NSButton* allowButton = |
+ FindButtonWithTitle(bubble, base::UTF8ToUTF16("Allow")); |
+ EXPECT_FALSE(allowButton); |
+ NSButton* blockButton = |
+ FindButtonWithTitle(bubble, base::UTF8ToUTF16("Block")); |
+ EXPECT_FALSE(blockButton); |
+} |
+ |
+TEST_F(PermissionBubbleControllerTest, OK) { |
groby-ooo-7-16
2014/01/31 22:31:51
I'm not sure you need these tests - all of these f
leng
2014/02/03 22:38:04
I changed them all to push the button, so they're
|
+ std::vector<PermissionBubbleDelegate*> requests; |
+ std::vector<bool> acceptStates; |
+ [controller_ showAtAnchor:NSMakePoint(0, 0) |
+ withDelegate:this |
+ forRequests:requests |
+ acceptStates:acceptStates |
+ customizationMode:NO]; |
+ |
+ EXPECT_CALL(*this, Closing()).Times(1); |
+ [controller_ ok]; |
+} |
+ |
+TEST_F(PermissionBubbleControllerTest, Allow) { |
+ std::vector<PermissionBubbleDelegate*> requests; |
+ std::vector<bool> acceptStates; |
+ [controller_ showAtAnchor:NSMakePoint(0, 0) |
+ withDelegate:this |
+ forRequests:requests |
+ acceptStates:acceptStates |
+ customizationMode:NO]; |
+ |
+ EXPECT_CALL(*this, Accept()).Times(1); |
+ [controller_ allow]; |
+} |
+ |
+TEST_F(PermissionBubbleControllerTest, Deny) { |
+ std::vector<PermissionBubbleDelegate*> requests; |
+ std::vector<bool> acceptStates; |
+ [controller_ showAtAnchor:NSMakePoint(0, 0) |
+ withDelegate:this |
+ forRequests:requests |
+ acceptStates:acceptStates |
+ customizationMode:NO]; |
+ |
+ EXPECT_CALL(*this, Deny()).Times(1); |
+ [controller_ block]; |
+} |
+ |
+TEST_F(PermissionBubbleControllerTest, ToggleCheckbox) { |
+ MockPermissionBubbleDelegate delegate_a; |
+ MockPermissionBubbleDelegate delegate_b; |
+ base::string16 permission_a = base::UTF8ToUTF16("Permission A"); |
+ base::string16 permission_b = base::UTF8ToUTF16("Permission B"); |
+ delegate_a.SetText(permission_a); |
+ delegate_b.SetText(permission_b); |
+ EXPECT_CALL(delegate_a, GetMessageTextFragment()).Times(1); |
+ EXPECT_CALL(delegate_b, GetMessageTextFragment()).Times(1); |
+ |
+ std::vector<PermissionBubbleDelegate*> requests; |
+ requests.push_back(&delegate_a); |
+ requests.push_back(&delegate_b); |
+ |
+ std::vector<bool> acceptStates; |
+ acceptStates.push_back(true); |
+ acceptStates.push_back(false); |
+ |
+ [controller_ showAtAnchor:NSMakePoint(0, 0) |
+ withDelegate:this |
+ forRequests:requests |
+ acceptStates:acceptStates |
+ customizationMode:YES]; |
+ |
+ NSButton* checkbox_a = |
+ FindButtonWithTitle((NSView*)[controller_ bubble], permission_a); |
+ NSButton* checkbox_b = |
+ FindButtonWithTitle((NSView*)[controller_ bubble], permission_b); |
+ |
+ // Because calling -checkboxChanged: directly does not change the state of |
+ // the NSButton, expect the same toggle value as was set originally. |
groby-ooo-7-16
2014/01/31 22:31:51
You can simulate a button press by [button perform
leng
2014/02/03 22:38:04
Done - Thanks for the suggestion!
|
+ EXPECT_CALL(*this, ToggleAccept(0, true)).Times(1); |
+ EXPECT_CALL(*this, ToggleAccept(1, false)).Times(1); |
+ [controller_ checkboxChanged:checkbox_a]; |
+ [controller_ checkboxChanged:checkbox_b]; |
+} |
+ |
+TEST_F(PermissionBubbleControllerTest, ClickCustomize) { |
+ std::vector<PermissionBubbleDelegate*> requests; |
+ std::vector<bool> acceptStates; |
+ [controller_ showAtAnchor:NSMakePoint(0, 0) |
+ withDelegate:this |
+ forRequests:requests |
+ acceptStates:acceptStates |
+ customizationMode:NO]; |
+ |
+ EXPECT_CALL(*this, SetCustomizationMode()).Times(1); |
+ [controller_ customize]; |
+} |