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.
5 #import <Cocoa/Cocoa.h>
7 #import "base/mac/scoped_nsobject.h"
8 #include "base/strings/sys_string_conversions.h"
9 #include "base/strings/utf_string_conversions.h"
10 #import "chrome/browser/extensions/extension_install_prompt.h"
11 #include "chrome/browser/ui/browser.h"
12 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h"
13 #import "chrome/browser/ui/cocoa/extensions/extension_install_prompt_test_utils.h"
14 #import "chrome/browser/ui/cocoa/extensions/extension_install_view_controller.h"
15 #include "extensions/common/extension.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #import "testing/gtest_mac.h"
19 using extensions::Extension;
21 // Base class for our tests.
22 class ExtensionInstallViewControllerTest : public CocoaProfileTest {
24 ExtensionInstallViewControllerTest() {
25 extension_ = chrome::LoadInstallPromptExtension();
29 scoped_refptr<extensions::Extension> extension_;
32 // Test that we can load the two kinds of prompts correctly, that the outlets
33 // are hooked up, and that the dialog calls cancel when cancel is pressed.
34 TEST_F(ExtensionInstallViewControllerTest, BasicsNormalCancel) {
35 chrome::MockExtensionInstallPromptDelegate delegate;
37 scoped_refptr<ExtensionInstallPrompt::Prompt> prompt =
38 chrome::BuildExtensionInstallPrompt(extension_.get());
39 ExtensionInstallPrompt::PermissionsType type =
40 ExtensionInstallPrompt::PermissionsType::REGULAR_PERMISSIONS;
42 std::vector<base::string16> permissions;
43 permissions.push_back(base::UTF8ToUTF16("warning 1"));
44 prompt->SetPermissions(permissions, type);
45 // No details provided with this permission.
46 std::vector<base::string16> details;
47 details.push_back(base::string16());
48 prompt->SetPermissionsDetails(details, type);
50 base::scoped_nsobject<ExtensionInstallViewController> controller(
51 [[ExtensionInstallViewController alloc] initWithNavigator:browser()
55 [controller view]; // Force nib load.
57 // Test the right nib loaded.
58 EXPECT_NSEQ(@"ExtensionInstallPrompt", [controller nibName]);
60 // Check all the controls.
61 // Make sure everything is non-nil, and that the fields that are
62 // auto-translated don't start with a caret (that would indicate that they
63 // were not translated).
64 EXPECT_TRUE([controller iconView]);
65 EXPECT_TRUE([[controller iconView] image]);
67 EXPECT_TRUE([controller titleField]);
68 EXPECT_NE(0u, [[[controller titleField] stringValue] length]);
70 NSOutlineView* outlineView = [controller outlineView];
71 EXPECT_TRUE(outlineView);
72 EXPECT_EQ(2, [outlineView numberOfRows]);
73 EXPECT_NSEQ(base::SysUTF16ToNSString(prompt->GetPermission(0, type)),
74 [[outlineView dataSource] outlineView:outlineView
75 objectValueForTableColumn:nil
76 byItem:[outlineView itemAtRow:1]]);
78 EXPECT_TRUE([controller cancelButton]);
79 EXPECT_NE(0u, [[[controller cancelButton] stringValue] length]);
80 EXPECT_NE('^', [[[controller cancelButton] stringValue] characterAtIndex:0]);
82 EXPECT_TRUE([controller okButton]);
83 EXPECT_NE(0u, [[[controller okButton] stringValue] length]);
84 EXPECT_NE('^', [[[controller okButton] stringValue] characterAtIndex:0]);
86 // Test that cancel calls our delegate.
87 [controller cancel:nil];
88 EXPECT_EQ(1, delegate.abort_count());
89 EXPECT_EQ(0, delegate.proceed_count());
92 TEST_F(ExtensionInstallViewControllerTest, BasicsNormalOK) {
93 chrome::MockExtensionInstallPromptDelegate delegate;
95 scoped_refptr<ExtensionInstallPrompt::Prompt> prompt =
96 chrome::BuildExtensionInstallPrompt(extension_.get());
97 ExtensionInstallPrompt::PermissionsType type =
98 ExtensionInstallPrompt::PermissionsType::REGULAR_PERMISSIONS;
100 std::vector<base::string16> permissions;
101 permissions.push_back(base::UTF8ToUTF16("warning 1"));
102 prompt->SetPermissions(permissions, type);
103 // No details provided with this permission.
104 std::vector<base::string16> details;
105 details.push_back(base::string16());
106 prompt->SetPermissionsDetails(details, type);
108 base::scoped_nsobject<ExtensionInstallViewController> controller(
109 [[ExtensionInstallViewController alloc] initWithNavigator:browser()
113 [controller view]; // Force nib load.
116 EXPECT_EQ(0, delegate.abort_count());
117 EXPECT_EQ(1, delegate.proceed_count());
120 // Test that controls get repositioned when there are two warnings vs one
122 TEST_F(ExtensionInstallViewControllerTest, MultipleWarnings) {
123 chrome::MockExtensionInstallPromptDelegate delegate1;
124 chrome::MockExtensionInstallPromptDelegate delegate2;
126 scoped_refptr<ExtensionInstallPrompt::Prompt> one_warning_prompt =
127 chrome::BuildExtensionInstallPrompt(extension_.get());
128 ExtensionInstallPrompt::PermissionsType type =
129 ExtensionInstallPrompt::PermissionsType::REGULAR_PERMISSIONS;
131 std::vector<base::string16> permissions;
132 permissions.push_back(base::UTF8ToUTF16("warning 1"));
133 one_warning_prompt->SetPermissions(permissions, type);
134 // No details provided with this permission.
135 std::vector<base::string16> details;
136 details.push_back(base::string16());
137 one_warning_prompt->SetPermissionsDetails(details, type);
139 scoped_refptr<ExtensionInstallPrompt::Prompt> two_warnings_prompt =
140 chrome::BuildExtensionInstallPrompt(extension_.get());
141 permissions.push_back(base::UTF8ToUTF16("warning 2"));
142 two_warnings_prompt->SetPermissions(permissions, type);
143 // No details provided with this permission.
144 details.push_back(base::string16());
145 two_warnings_prompt->SetPermissionsDetails(details, type);
147 base::scoped_nsobject<ExtensionInstallViewController> controller1(
148 [[ExtensionInstallViewController alloc]
149 initWithNavigator:browser()
151 prompt:one_warning_prompt]);
153 [controller1 view]; // Force nib load.
155 base::scoped_nsobject<ExtensionInstallViewController> controller2(
156 [[ExtensionInstallViewController alloc]
157 initWithNavigator:browser()
159 prompt:two_warnings_prompt]);
161 [controller2 view]; // Force nib load.
163 // Test control positioning. We don't test exact positioning because we don't
164 // want this to depend on string details and localization. But we do know the
165 // relative effect that adding a second warning should have on the layout.
166 ASSERT_LT([[controller1 view] frame].size.height,
167 [[controller2 view] frame].size.height);
169 ASSERT_LT([[controller1 view] frame].size.height,
170 [[controller2 view] frame].size.height);
173 // Test that we can load the skinny prompt correctly, and that the outlets are
175 TEST_F(ExtensionInstallViewControllerTest, BasicsSkinny) {
176 chrome::MockExtensionInstallPromptDelegate delegate;
178 // No warnings should trigger skinny prompt.
179 scoped_refptr<ExtensionInstallPrompt::Prompt> no_warnings_prompt =
180 chrome::BuildExtensionInstallPrompt(extension_.get());
182 base::scoped_nsobject<ExtensionInstallViewController> controller(
183 [[ExtensionInstallViewController alloc]
184 initWithNavigator:browser()
186 prompt:no_warnings_prompt]);
188 [controller view]; // Force nib load.
190 // Test the right nib loaded.
191 EXPECT_NSEQ(@"ExtensionInstallPromptNoWarnings", [controller nibName]);
193 // Check all the controls.
194 // In the skinny prompt, only the icon, title and buttons are non-nill.
195 // Everything else is nil.
196 EXPECT_TRUE([controller iconView]);
197 EXPECT_TRUE([[controller iconView] image]);
199 EXPECT_TRUE([controller titleField]);
200 EXPECT_NE(0u, [[[controller titleField] stringValue] length]);
202 EXPECT_TRUE([controller cancelButton]);
203 EXPECT_NE(0u, [[[controller cancelButton] stringValue] length]);
204 EXPECT_NE('^', [[[controller cancelButton] stringValue] characterAtIndex:0]);
206 EXPECT_TRUE([controller okButton]);
207 EXPECT_NE(0u, [[[controller okButton] stringValue] length]);
208 EXPECT_NE('^', [[[controller okButton] stringValue] characterAtIndex:0]);
210 EXPECT_FALSE([controller outlineView]);
214 // Test that we can load the inline prompt correctly, and that the outlets are
216 TEST_F(ExtensionInstallViewControllerTest, BasicsInline) {
217 chrome::MockExtensionInstallPromptDelegate delegate;
219 // No warnings should trigger skinny prompt.
220 scoped_refptr<ExtensionInstallPrompt::Prompt> inline_prompt =
221 new ExtensionInstallPrompt::Prompt(
222 ExtensionInstallPrompt::INLINE_INSTALL_PROMPT);
223 inline_prompt->SetWebstoreData("1,000", true, 3.5, 200);
224 inline_prompt->set_extension(extension_.get());
225 inline_prompt->set_icon(chrome::LoadInstallPromptIcon());
227 base::scoped_nsobject<ExtensionInstallViewController> controller(
228 [[ExtensionInstallViewController alloc] initWithNavigator:browser()
230 prompt:inline_prompt]);
232 [controller view]; // Force nib load.
234 // Test the right nib loaded.
235 EXPECT_NSEQ(@"ExtensionInstallPromptWebstoreData", [controller nibName]);
237 // Check all the controls.
238 EXPECT_TRUE([controller iconView]);
239 EXPECT_TRUE([[controller iconView] image]);
241 EXPECT_TRUE([controller titleField]);
242 EXPECT_NE(0u, [[[controller titleField] stringValue] length]);
244 EXPECT_TRUE([controller cancelButton]);
245 EXPECT_NE(0u, [[[controller cancelButton] stringValue] length]);
246 EXPECT_NE('^', [[[controller cancelButton] stringValue] characterAtIndex:0]);
248 EXPECT_TRUE([controller okButton]);
249 EXPECT_NE(0u, [[[controller okButton] stringValue] length]);
250 EXPECT_NE('^', [[[controller okButton] stringValue] characterAtIndex:0]);
252 EXPECT_TRUE([controller ratingStars]);
253 EXPECT_EQ(5u, [[[controller ratingStars] subviews] count]);
255 EXPECT_TRUE([controller ratingCountField]);
256 EXPECT_NE(0u, [[[controller ratingCountField] stringValue] length]);
258 EXPECT_TRUE([controller userCountField]);
259 EXPECT_NE(0u, [[[controller userCountField] stringValue] length]);
261 EXPECT_TRUE([controller storeLinkButton]);
262 EXPECT_NE(0u, [[[controller storeLinkButton] stringValue] length]);
264 [[[controller storeLinkButton] stringValue] characterAtIndex:0]);
266 // Though we have no permissions warnings, these should still be hooked up,
268 EXPECT_TRUE([controller outlineView]);
269 EXPECT_TRUE([[[controller outlineView] enclosingScrollView] isHidden]);
270 EXPECT_TRUE([controller warningsSeparator]);
271 EXPECT_TRUE([[controller warningsSeparator] isHidden]);
274 TEST_F(ExtensionInstallViewControllerTest, PostInstallPermissionsPrompt) {
275 chrome::MockExtensionInstallPromptDelegate delegate;
277 scoped_refptr<ExtensionInstallPrompt::Prompt> prompt =
278 chrome::BuildExtensionPostInstallPermissionsPrompt(extension_.get());
279 ExtensionInstallPrompt::PermissionsType type =
280 ExtensionInstallPrompt::PermissionsType::REGULAR_PERMISSIONS;
282 std::vector<base::string16> permissions;
283 permissions.push_back(base::UTF8ToUTF16("warning 1"));
284 prompt->SetPermissions(permissions, type);
285 // No details provided with this permission.
286 std::vector<base::string16> details;
287 details.push_back(base::string16());
288 prompt->SetPermissionsDetails(details, type);
290 base::scoped_nsobject<ExtensionInstallViewController> controller(
291 [[ExtensionInstallViewController alloc] initWithNavigator:browser()
295 [controller view]; // Force nib load.
297 EXPECT_TRUE([controller cancelButton]);
298 EXPECT_FALSE([controller okButton]);
300 [controller cancel:nil];
301 EXPECT_EQ(1, delegate.abort_count());
304 // Test that permission details show up.
305 TEST_F(ExtensionInstallViewControllerTest, PermissionsDetails) {
306 chrome::MockExtensionInstallPromptDelegate delegate;
308 scoped_refptr<ExtensionInstallPrompt::Prompt> prompt =
309 chrome::BuildExtensionInstallPrompt(extension_.get());
310 ExtensionInstallPrompt::PermissionsType type =
311 ExtensionInstallPrompt::PermissionsType::REGULAR_PERMISSIONS;
313 std::vector<base::string16> permissions;
314 permissions.push_back(base::UTF8ToUTF16("warning 1"));
315 std::vector<base::string16> permissions_details;
316 permissions_details.push_back(base::UTF8ToUTF16("Detail 1"));
317 prompt->SetPermissions(permissions, type);
318 prompt->SetPermissionsDetails(permissions_details, type);
319 prompt->SetIsShowingDetails(
320 ExtensionInstallPrompt::PERMISSIONS_DETAILS, 0, true);
322 base::scoped_nsobject<ExtensionInstallViewController> controller(
323 [[ExtensionInstallViewController alloc] initWithNavigator:browser()
327 [controller view]; // Force nib load.
329 NSOutlineView* outlineView = [controller outlineView];
330 EXPECT_TRUE(outlineView);
331 EXPECT_EQ(4, [outlineView numberOfRows]);
332 EXPECT_NSEQ(base::SysUTF16ToNSString(prompt->GetPermissionsDetails(0, type)),
333 [[outlineView dataSource] outlineView:outlineView
334 objectValueForTableColumn:nil
335 byItem:[outlineView itemAtRow:2]]);