OLD | NEW |
---|---|
(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/permission_bubble_controller.h" | |
6 | |
7 #include "base/strings/sys_string_conversions.h" | |
8 #include "base/strings/utf_string_conversions.h" | |
9 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" | |
10 #import "chrome/browser/ui/cocoa/permission_bubble_cocoa.h" | |
11 #include "chrome/browser/ui/cocoa/run_loop_testing.h" | |
12 #include "chrome/browser/ui/website_settings/mock_permission_bubble_delegate.h" | |
13 | |
14 @interface PermissionBubbleController (ExposedForTesting) | |
15 - (void)ok; | |
16 - (void)allow; | |
17 - (void)block; | |
18 - (void)customize; | |
19 - (void)checkboxChanged:(id)sender; | |
20 @end | |
21 | |
22 class PermissionBubbleControllerTest : public CocoaTest, | |
23 public PermissionBubbleView::Delegate { | |
24 public: | |
25 | |
26 MOCK_METHOD2(ToggleAccept, void(int, bool)); | |
27 MOCK_METHOD0(SetCustomizationMode, void()); | |
28 MOCK_METHOD0(Accept, void()); | |
29 MOCK_METHOD0(Deny, void()); | |
30 MOCK_METHOD0(Closing, void()); | |
31 | |
32 virtual void SetUp() OVERRIDE { | |
33 CocoaTest::SetUp(); | |
34 bridge_.reset(new PermissionBubbleCocoa(nil)); | |
35 controller_ = [[PermissionBubbleController alloc] | |
36 initWithParentWindow:test_window() | |
37 bridge:bridge_.get()]; | |
38 } | |
39 | |
40 virtual void TearDown() OVERRIDE { | |
41 [controller_ close]; | |
42 chrome::testing::NSRunLoopRunAllPending(); | |
43 CocoaTest::TearDown(); | |
44 } | |
45 | |
46 NSButton* FindButtonWithTitle(NSView* parent, | |
47 const base::string16& text) { | |
48 NSString* title = base::SysUTF16ToNSString(text); | |
49 for (NSView* child in [parent subviews]) { | |
50 if ([child isKindOfClass:[NSButton class]]) { | |
51 NSButton* button = (NSButton*)child; | |
groby-ooo-7-16
2014/01/31 22:31:51
base::ObjCCast
leng
2014/02/03 22:38:04
Done.
| |
52 if ([title isEqualToString:[button title]]) { | |
53 return button; | |
54 } | |
55 } | |
56 } | |
57 return nil; | |
58 } | |
59 | |
60 NSTextField* FindTextFieldWithString(NSView* parent, | |
61 const base::string16& text, | |
62 BOOL exactMatch) { | |
63 NSString* title = base::SysUTF16ToNSString(text); | |
64 for (NSView* child in [parent subviews]) { | |
65 if ([child isKindOfClass:[NSTextField class]]) { | |
66 NSTextField* textField = (NSTextField*)child; | |
67 // When multiple requests are made, a bullet point will be inserted | |
68 // at the beginning of every line. So in that case, only a partial | |
69 // 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.
| |
70 if ([title isEqualToString:[textField stringValue]]) { | |
71 return textField; | |
72 } else if (!exactMatch && [[textField stringValue] hasSuffix:title]) { | |
73 return textField; | |
74 } | |
75 } | |
76 } | |
77 return nil; | |
78 } | |
79 | |
80 protected: | |
81 PermissionBubbleController* controller_; // Weak; it deletes itself. | |
82 scoped_ptr<PermissionBubbleCocoa> bridge_; | |
83 }; | |
84 | |
85 TEST_F(PermissionBubbleControllerTest, ShowAndClose) { | |
86 EXPECT_FALSE([[controller_ window] isVisible]); | |
87 [controller_ showWindow:nil]; | |
88 EXPECT_TRUE([[controller_ window] isVisible]); | |
89 } | |
90 | |
91 TEST_F(PermissionBubbleControllerTest, ShowSinglePermission) { | |
92 MockPermissionBubbleDelegate delegate_a; | |
93 base::string16 permission_a = base::UTF8ToUTF16("Permission A"); | |
94 delegate_a.SetText(permission_a); | |
95 EXPECT_CALL(delegate_a, GetMessageTextFragment()).Times(1); | |
96 | |
97 std::vector<PermissionBubbleDelegate*> requests; | |
98 requests.push_back(&delegate_a); | |
99 std::vector<bool> acceptStates; | |
100 | |
101 [controller_ showAtAnchor:NSMakePoint(0, 0) | |
groby-ooo-7-16
2014/01/31 22:31:51
NSZeroPoint
leng
2014/02/03 22:38:04
Done.
| |
102 withDelegate:this | |
103 forRequests:requests | |
104 acceptStates:acceptStates | |
105 customizationMode:NO]; | |
106 | |
107 NSView* bubble = (NSView*)[controller_ bubble]; | |
108 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!
| |
109 EXPECT_TRUE(textField); | |
110 NSButton* allowButton = | |
111 FindButtonWithTitle(bubble, base::UTF8ToUTF16("Allow")); | |
112 EXPECT_TRUE(allowButton); | |
113 NSButton* blockButton = | |
114 FindButtonWithTitle(bubble, base::UTF8ToUTF16("Block")); | |
115 EXPECT_TRUE(blockButton); | |
116 NSButton* okButton = FindButtonWithTitle(bubble, base::UTF8ToUTF16("OK")); | |
117 EXPECT_FALSE(okButton); | |
118 } | |
119 | |
120 TEST_F(PermissionBubbleControllerTest, ShowMultiplePermissions) { | |
121 MockPermissionBubbleDelegate delegate_a; | |
122 MockPermissionBubbleDelegate delegate_b; | |
123 MockPermissionBubbleDelegate delegate_c; | |
124 base::string16 permission_a = base::UTF8ToUTF16("Permission A"); | |
125 base::string16 permission_b = base::UTF8ToUTF16("Permission B"); | |
126 base::string16 permission_c = base::UTF8ToUTF16("Permission C"); | |
127 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
| |
128 delegate_b.SetText(permission_b); | |
129 delegate_c.SetText(permission_c); | |
130 EXPECT_CALL(delegate_a, GetMessageTextFragment()).Times(1); | |
131 EXPECT_CALL(delegate_b, GetMessageTextFragment()).Times(1); | |
132 EXPECT_CALL(delegate_c, GetMessageTextFragment()).Times(1); | |
133 | |
134 std::vector<PermissionBubbleDelegate*> requests; | |
135 requests.push_back(&delegate_a); | |
136 requests.push_back(&delegate_b); | |
137 requests.push_back(&delegate_c); | |
138 std::vector<bool> acceptStates; | |
139 | |
140 [controller_ showAtAnchor:NSMakePoint(0, 0) | |
141 withDelegate:this | |
142 forRequests:requests | |
143 acceptStates:acceptStates | |
144 customizationMode:NO]; | |
145 | |
146 NSView* bubble = (NSView*)[controller_ bubble]; | |
147 NSTextField* textField = FindTextFieldWithString(bubble, permission_a, false); | |
148 EXPECT_TRUE(textField); | |
149 textField = FindTextFieldWithString(bubble, permission_b, false); | |
150 EXPECT_TRUE(textField); | |
151 textField = FindTextFieldWithString(bubble, permission_c, false); | |
152 EXPECT_TRUE(textField); | |
153 | |
154 NSButton* allowButton = FindButtonWithTitle(bubble, | |
155 base::UTF8ToUTF16("Allow")); | |
156 EXPECT_TRUE(allowButton); | |
157 NSButton* blockButton = FindButtonWithTitle(bubble, | |
158 base::UTF8ToUTF16("Block")); | |
159 EXPECT_TRUE(blockButton); | |
160 NSButton* okButton = FindButtonWithTitle(bubble, base::UTF8ToUTF16("OK")); | |
161 EXPECT_FALSE(okButton); | |
162 } | |
163 | |
164 TEST_F(PermissionBubbleControllerTest, ShowCustomizationMode) { | |
165 MockPermissionBubbleDelegate delegate_a; | |
166 MockPermissionBubbleDelegate delegate_b; | |
167 base::string16 permission_a = base::UTF8ToUTF16("Permission A"); | |
168 base::string16 permission_b = base::UTF8ToUTF16("Permission B"); | |
169 delegate_a.SetText(permission_a); | |
170 delegate_b.SetText(permission_b); | |
171 EXPECT_CALL(delegate_a, GetMessageTextFragment()).Times(1); | |
172 EXPECT_CALL(delegate_b, GetMessageTextFragment()).Times(1); | |
173 | |
174 std::vector<PermissionBubbleDelegate*> requests; | |
175 requests.push_back(&delegate_a); | |
176 requests.push_back(&delegate_b); | |
177 | |
178 std::vector<bool> acceptStates; | |
179 acceptStates.push_back(true); | |
180 acceptStates.push_back(false); | |
181 | |
182 [controller_ showAtAnchor:NSMakePoint(0, 0) | |
183 withDelegate:this | |
184 forRequests:requests | |
185 acceptStates:acceptStates | |
186 customizationMode:YES]; | |
187 | |
188 // Test that each checkbox is visible and only the first is checked. | |
189 NSView* bubble = (NSView*)[controller_ bubble]; | |
190 NSButton* checkbox_a = FindButtonWithTitle(bubble, permission_a); | |
191 NSButton* checkbox_b = FindButtonWithTitle(bubble, permission_b); | |
192 EXPECT_TRUE(checkbox_a); | |
193 EXPECT_TRUE(checkbox_b); | |
194 EXPECT_EQ(NSOnState, [checkbox_a state]); | |
195 EXPECT_EQ(NSOffState, [checkbox_b state]); | |
196 | |
197 NSButton* okButton = FindButtonWithTitle(bubble, base::UTF8ToUTF16("OK")); | |
198 EXPECT_TRUE(okButton); | |
199 NSButton* allowButton = | |
200 FindButtonWithTitle(bubble, base::UTF8ToUTF16("Allow")); | |
201 EXPECT_FALSE(allowButton); | |
202 NSButton* blockButton = | |
203 FindButtonWithTitle(bubble, base::UTF8ToUTF16("Block")); | |
204 EXPECT_FALSE(blockButton); | |
205 } | |
206 | |
207 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
| |
208 std::vector<PermissionBubbleDelegate*> requests; | |
209 std::vector<bool> acceptStates; | |
210 [controller_ showAtAnchor:NSMakePoint(0, 0) | |
211 withDelegate:this | |
212 forRequests:requests | |
213 acceptStates:acceptStates | |
214 customizationMode:NO]; | |
215 | |
216 EXPECT_CALL(*this, Closing()).Times(1); | |
217 [controller_ ok]; | |
218 } | |
219 | |
220 TEST_F(PermissionBubbleControllerTest, Allow) { | |
221 std::vector<PermissionBubbleDelegate*> requests; | |
222 std::vector<bool> acceptStates; | |
223 [controller_ showAtAnchor:NSMakePoint(0, 0) | |
224 withDelegate:this | |
225 forRequests:requests | |
226 acceptStates:acceptStates | |
227 customizationMode:NO]; | |
228 | |
229 EXPECT_CALL(*this, Accept()).Times(1); | |
230 [controller_ allow]; | |
231 } | |
232 | |
233 TEST_F(PermissionBubbleControllerTest, Deny) { | |
234 std::vector<PermissionBubbleDelegate*> requests; | |
235 std::vector<bool> acceptStates; | |
236 [controller_ showAtAnchor:NSMakePoint(0, 0) | |
237 withDelegate:this | |
238 forRequests:requests | |
239 acceptStates:acceptStates | |
240 customizationMode:NO]; | |
241 | |
242 EXPECT_CALL(*this, Deny()).Times(1); | |
243 [controller_ block]; | |
244 } | |
245 | |
246 TEST_F(PermissionBubbleControllerTest, ToggleCheckbox) { | |
247 MockPermissionBubbleDelegate delegate_a; | |
248 MockPermissionBubbleDelegate delegate_b; | |
249 base::string16 permission_a = base::UTF8ToUTF16("Permission A"); | |
250 base::string16 permission_b = base::UTF8ToUTF16("Permission B"); | |
251 delegate_a.SetText(permission_a); | |
252 delegate_b.SetText(permission_b); | |
253 EXPECT_CALL(delegate_a, GetMessageTextFragment()).Times(1); | |
254 EXPECT_CALL(delegate_b, GetMessageTextFragment()).Times(1); | |
255 | |
256 std::vector<PermissionBubbleDelegate*> requests; | |
257 requests.push_back(&delegate_a); | |
258 requests.push_back(&delegate_b); | |
259 | |
260 std::vector<bool> acceptStates; | |
261 acceptStates.push_back(true); | |
262 acceptStates.push_back(false); | |
263 | |
264 [controller_ showAtAnchor:NSMakePoint(0, 0) | |
265 withDelegate:this | |
266 forRequests:requests | |
267 acceptStates:acceptStates | |
268 customizationMode:YES]; | |
269 | |
270 NSButton* checkbox_a = | |
271 FindButtonWithTitle((NSView*)[controller_ bubble], permission_a); | |
272 NSButton* checkbox_b = | |
273 FindButtonWithTitle((NSView*)[controller_ bubble], permission_b); | |
274 | |
275 // Because calling -checkboxChanged: directly does not change the state of | |
276 // 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!
| |
277 EXPECT_CALL(*this, ToggleAccept(0, true)).Times(1); | |
278 EXPECT_CALL(*this, ToggleAccept(1, false)).Times(1); | |
279 [controller_ checkboxChanged:checkbox_a]; | |
280 [controller_ checkboxChanged:checkbox_b]; | |
281 } | |
282 | |
283 TEST_F(PermissionBubbleControllerTest, ClickCustomize) { | |
284 std::vector<PermissionBubbleDelegate*> requests; | |
285 std::vector<bool> acceptStates; | |
286 [controller_ showAtAnchor:NSMakePoint(0, 0) | |
287 withDelegate:this | |
288 forRequests:requests | |
289 acceptStates:acceptStates | |
290 customizationMode:NO]; | |
291 | |
292 EXPECT_CALL(*this, SetCustomizationMode()).Times(1); | |
293 [controller_ customize]; | |
294 } | |
OLD | NEW |