OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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/web_intent_sheet_controller.h" | |
6 | |
7 #include "base/memory/scoped_nsobject.h" | |
8 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" | |
9 #import "chrome/browser/ui/cocoa/hover_close_button.h" | |
10 #import "chrome/browser/ui/cocoa/hyperlink_button_cell.h" | |
11 #include "chrome/browser/ui/intents/web_intent_picker_model.h" | |
12 #include "content/public/test/test_browser_thread.h" | |
13 #include "testing/gmock/include/gmock/gmock.h" | |
14 #include "testing/platform_test.h" | |
15 | |
16 @class HeaderView; | |
17 | |
18 class WebIntentPickerSheetControllerTest : public CocoaTest { | |
19 public: | |
20 | |
21 virtual void SetUp() { | |
22 CocoaTest::SetUp(); | |
23 controller_ = [[WebIntentPickerSheetController alloc] initWithPicker:nil]; | |
24 window_ = [controller_ window]; | |
25 } | |
26 | |
27 virtual void TearDown() { | |
28 // Since we're not actually running the sheet, we must manually release. | |
29 [controller_ release]; | |
30 | |
31 CocoaTest::TearDown(); | |
32 } | |
33 | |
34 void CheckHeader(NSView* header_view) { | |
35 ASSERT_TRUE([header_view isKindOfClass:[NSView class]]); | |
36 NSArray* views = [header_view subviews]; | |
37 | |
38 ASSERT_EQ(3U, [views count]); | |
39 ASSERT_TRUE([[views objectAtIndex:0] isKindOfClass:[NSTextField class]]); | |
40 ASSERT_TRUE([[views objectAtIndex:1] isKindOfClass:[NSTextField class]]); | |
41 ASSERT_TRUE([[views objectAtIndex:2] isKindOfClass:[NSBox class]]); | |
42 } | |
43 | |
44 // Checks the controller's window for the requisite subviews and icons. | |
45 void CheckWindow(size_t row_count) { | |
46 NSArray* flip_views = [[window_ contentView] subviews]; | |
47 | |
48 // Expect 1 subview - the flip view. | |
49 ASSERT_EQ(1U, [flip_views count]); | |
50 | |
51 NSArray* views = [[flip_views objectAtIndex:0] subviews]; | |
52 | |
53 // 5 subviews - header view, intents list, CWS link, CWS icon, close button. | |
54 // intents list is not added if there are no rows. | |
55 NSUInteger view_offset = row_count ? 1U : 0U; | |
56 ASSERT_EQ(4U + view_offset, [views count]); | |
57 | |
58 ASSERT_TRUE([[views objectAtIndex:0] isKindOfClass:[NSView class]]); | |
59 CheckHeader([views objectAtIndex:0]); | |
60 if (view_offset) { | |
61 ASSERT_TRUE([[views objectAtIndex:1] isKindOfClass:[NSView class]]); | |
62 } | |
63 ASSERT_TRUE([[views objectAtIndex:1 + view_offset] isKindOfClass: | |
64 [NSImageView class]]); | |
65 ASSERT_TRUE([[views objectAtIndex:2 + view_offset] isKindOfClass: | |
66 [NSButton class]]); | |
67 ASSERT_TRUE([[views objectAtIndex:3 + view_offset] isKindOfClass: | |
68 [HoverCloseButton class]]); | |
69 | |
70 // Verify the close button | |
71 NSButton* close_button = static_cast<NSButton*>([views lastObject]); | |
72 CheckButton(close_button, @selector(cancelOperation:)); | |
73 | |
74 // Verify the Chrome Web Store button. | |
75 NSButton* button = static_cast<NSButton*>( | |
76 [views objectAtIndex:2 + view_offset]); | |
77 EXPECT_TRUE([[button cell] isKindOfClass:[HyperlinkButtonCell class]]); | |
78 CheckButton(button, @selector(showChromeWebStore:)); | |
79 } | |
80 | |
81 void CheckSuggestionView(NSView* item_view, NSUInteger suggestion_index) { | |
82 // 5 subobjects - Icon, title, star rating, add button, and throbber. | |
83 ASSERT_EQ(5U, [[item_view subviews] count]); | |
84 | |
85 // Verify title button is hooked up properly | |
86 ASSERT_TRUE([[[item_view subviews] objectAtIndex:1] | |
87 isKindOfClass:[NSButton class]]); | |
88 NSButton* title_button = [[item_view subviews] objectAtIndex:1]; | |
89 CheckButton(title_button, @selector(openExtensionLink:)); | |
90 | |
91 // Verify "Add to Chromium" button is hooked up properly | |
92 ASSERT_TRUE([[[item_view subviews] objectAtIndex:3] | |
93 isKindOfClass:[NSButton class]]); | |
94 NSButton* add_button = [[item_view subviews] objectAtIndex:3]; | |
95 CheckButton(add_button, @selector(installExtension:)); | |
96 EXPECT_EQ(NSInteger(suggestion_index), [add_button tag]); | |
97 | |
98 // Verify we have a throbber. | |
99 ASSERT_TRUE([[[item_view subviews] objectAtIndex:4] | |
100 isKindOfClass:[NSProgressIndicator class]]); | |
101 } | |
102 | |
103 void CheckServiceView(NSView* item_view, NSUInteger service_index) { | |
104 // 3 subobjects - Icon, title, select button. | |
105 ASSERT_EQ(3U, [[item_view subviews] count]); | |
106 | |
107 // Verify title is a text field. | |
108 ASSERT_TRUE([[[item_view subviews] objectAtIndex:1] | |
109 isKindOfClass:[NSTextField class]]); | |
110 | |
111 // Verify "Select" button is hooked up properly. | |
112 ASSERT_TRUE([[[item_view subviews] objectAtIndex:2] | |
113 isKindOfClass:[NSButton class]]); | |
114 NSButton* select_button = [[item_view subviews] objectAtIndex:2]; | |
115 CheckButton(select_button, @selector(invokeService:)); | |
116 EXPECT_EQ(NSInteger(service_index), [select_button tag]); | |
117 } | |
118 | |
119 // Checks that a button is hooked up correctly. | |
120 void CheckButton(id button, SEL action) { | |
121 EXPECT_TRUE([button isKindOfClass:[NSButton class]] || | |
122 [button isKindOfClass:[NSButtonCell class]]); | |
123 EXPECT_EQ(action, [button action]); | |
124 EXPECT_EQ(controller_, [button target]); | |
125 EXPECT_TRUE([button stringValue]); | |
126 } | |
127 | |
128 // Controller under test. | |
129 WebIntentPickerSheetController* controller_; | |
130 | |
131 NSWindow* window_; // Weak, owned by |controller_|. | |
132 }; | |
133 | |
134 TEST_F(WebIntentPickerSheetControllerTest, NoRows) { | |
135 CheckWindow(/*row_count=*/0); | |
136 } | |
137 | |
138 TEST_F(WebIntentPickerSheetControllerTest, IntentRows) { | |
139 WebIntentPickerModel model; | |
140 model.AddInstalledService(string16(), GURL("http://example.org/intent.html"), | |
141 webkit_glue::WebIntentServiceData::DISPOSITION_WINDOW); | |
142 model.AddInstalledService(string16(), GURL("http://example.com/intent.html"), | |
143 webkit_glue::WebIntentServiceData::DISPOSITION_WINDOW); | |
144 model.SetWaitingForSuggestions(false); | |
145 [controller_ performLayoutWithModel:&model]; | |
146 | |
147 CheckWindow(/*row_count=*/2); | |
148 | |
149 NSArray* flip_views = [[window_ contentView] subviews]; | |
150 NSArray* main_views = [[flip_views objectAtIndex:0] subviews]; | |
151 | |
152 // 2nd object should be the suggestion view, 3rd one is close button. | |
153 ASSERT_TRUE([main_views count] > 2); | |
154 ASSERT_TRUE([[main_views objectAtIndex:1] isKindOfClass:[NSView class]]); | |
155 NSView* intent_view = [main_views objectAtIndex:1]; | |
156 | |
157 // 2 subviews - the two installed services item. Tags are assigned reverse. | |
158 ASSERT_EQ(2U, [[intent_view subviews] count]); | |
159 NSView* item_view = [[intent_view subviews] objectAtIndex:0]; | |
160 CheckServiceView(item_view, 1); | |
161 item_view = [[intent_view subviews] objectAtIndex:1]; | |
162 CheckServiceView(item_view, 0); | |
163 } | |
164 | |
165 TEST_F(WebIntentPickerSheetControllerTest, SuggestionRow) { | |
166 WebIntentPickerModel model; | |
167 std::vector<WebIntentPickerModel::SuggestedExtension> suggestions; | |
168 suggestions.push_back(WebIntentPickerModel::SuggestedExtension( | |
169 string16(), std::string(), 2.5)); | |
170 model.AddSuggestedExtensions(suggestions); | |
171 model.SetWaitingForSuggestions(false); | |
172 | |
173 [controller_ performLayoutWithModel:&model]; | |
174 | |
175 CheckWindow(/*row_count=*/1); | |
176 | |
177 // Get subviews. | |
178 NSArray* flip_views = [[window_ contentView] subviews]; | |
179 NSArray* main_views = [[flip_views objectAtIndex:0] subviews]; | |
180 | |
181 // 2nd object should be the suggestion view, 3rd one is close button. | |
182 ASSERT_TRUE([main_views count] > 2); | |
183 ASSERT_TRUE([[main_views objectAtIndex:1] isKindOfClass:[NSView class]]); | |
184 NSView* intent_view = [main_views objectAtIndex:1]; | |
185 | |
186 // One subview - the suggested item. | |
187 ASSERT_EQ(1U, [[intent_view subviews] count]); | |
188 ASSERT_TRUE([[[intent_view subviews] objectAtIndex:0] | |
189 isKindOfClass:[NSView class]]); | |
190 NSView* item_view = [[intent_view subviews] objectAtIndex:0]; | |
191 CheckSuggestionView(item_view, 0); | |
192 } | |
193 | |
194 TEST_F(WebIntentPickerSheetControllerTest, MixedIntentView) { | |
195 WebIntentPickerModel model; | |
196 std::vector<WebIntentPickerModel::SuggestedExtension> suggestions; | |
197 suggestions.push_back(WebIntentPickerModel::SuggestedExtension( | |
198 string16(), std::string(), 2.5)); | |
199 model.AddSuggestedExtensions(suggestions); | |
200 model.AddInstalledService(string16(), GURL("http://example.org/intent.html"), | |
201 webkit_glue::WebIntentServiceData::DISPOSITION_WINDOW); | |
202 model.AddInstalledService(string16(), GURL("http://example.com/intent.html"), | |
203 webkit_glue::WebIntentServiceData::DISPOSITION_WINDOW); | |
204 model.SetWaitingForSuggestions(false); | |
205 | |
206 [controller_ performLayoutWithModel:&model]; | |
207 | |
208 CheckWindow(/*row_count=*/3); | |
209 | |
210 NSArray* flip_views = [[window_ contentView] subviews]; | |
211 NSArray* main_views = [[flip_views objectAtIndex:0] subviews]; | |
212 | |
213 // 2nd object should be the suggestion view, 3rd one is close button. | |
214 ASSERT_TRUE([main_views count] > 2); | |
215 ASSERT_TRUE([[main_views objectAtIndex:1] isKindOfClass:[NSView class]]); | |
216 NSView* intent_view = [main_views objectAtIndex:1]; | |
217 | |
218 // 3 subviews - 2 installed services, 1 suggestion. | |
219 ASSERT_EQ(3U, [[intent_view subviews] count]); | |
220 NSView* item_view = [[intent_view subviews] objectAtIndex:0]; | |
221 CheckSuggestionView(item_view, 0); | |
222 item_view = [[intent_view subviews] objectAtIndex:1]; | |
223 CheckServiceView(item_view, 1); | |
224 item_view = [[intent_view subviews] objectAtIndex:2]; | |
225 CheckServiceView(item_view, 0); | |
226 } | |
227 | |
228 TEST_F(WebIntentPickerSheetControllerTest, EmptyView) { | |
229 WebIntentPickerModel model; | |
230 model.SetWaitingForSuggestions(false); | |
231 [controller_ performLayoutWithModel:&model]; | |
232 | |
233 ASSERT_TRUE(window_); | |
234 | |
235 // Get subviews. | |
236 NSArray* flip_views = [[window_ contentView] subviews]; | |
237 ASSERT_TRUE(flip_views); | |
238 | |
239 NSArray* main_views = [[flip_views objectAtIndex:0] subviews]; | |
240 ASSERT_TRUE(main_views); | |
241 | |
242 // Should have two subviews - the empty picker dialog and the close button. | |
243 ASSERT_EQ(2U, [main_views count]); | |
244 | |
245 // Extract empty picker dialog. | |
246 ASSERT_TRUE([[main_views objectAtIndex:0] isKindOfClass:[NSView class]]); | |
247 NSView* empty_dialog = [main_views objectAtIndex:0]; | |
248 | |
249 // Empty picker dialog has two elements, title and body. | |
250 ASSERT_EQ(2U, [[empty_dialog subviews] count]); | |
251 | |
252 // Both title and body are NSTextFields. | |
253 ASSERT_TRUE([[[empty_dialog subviews] objectAtIndex:0] | |
254 isKindOfClass:[NSTextField class]]); | |
255 ASSERT_TRUE([[[empty_dialog subviews] objectAtIndex:1] | |
256 isKindOfClass:[NSTextField class]]); | |
257 } | |
OLD | NEW |