1 // Copyright (c) 2013 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 #include "base/command_line.h"
6 #include "base/strings/string_util.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/extensions/dev_mode_bubble_controller.h"
9 #include "chrome/browser/extensions/extension_function_test_utils.h"
10 #include "chrome/browser/extensions/extension_message_bubble.h"
11 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/extensions/ntp_overridden_bubble_controller.h"
13 #include "chrome/browser/extensions/settings_api_bubble_controller.h"
14 #include "chrome/browser/extensions/suspicious_extension_bubble_controller.h"
15 #include "chrome/browser/extensions/test_extension_system.h"
16 #include "chrome/common/chrome_version_info.h"
17 #include "chrome/test/base/testing_profile.h"
18 #include "content/public/test/test_browser_thread_bundle.h"
19 #include "extensions/common/extension.h"
20 #include "extensions/common/extension_builder.h"
21 #include "extensions/common/feature_switch.h"
25 const char kId1
[] = "iccfkkhkfiphcjdakkmcjmkfboccmndk";
26 const char kId2
[] = "ajjhifimiemdpmophmkkkcijegphclbl";
27 const char kId3
[] = "ioibbbfddncmmabjmpokikkeiofalaek";
31 namespace extensions
{
36 : action_button_callback_count_(0),
37 dismiss_button_callback_count_(0),
38 link_click_callback_count_(0) {
41 // Returns how often the dismiss button has been called.
42 size_t action_click_count() {
43 return action_button_callback_count_
;
46 // Returns how often the dismiss button has been called.
47 size_t dismiss_click_count() {
48 return dismiss_button_callback_count_
;
51 // Returns how often the link has been clicked.
52 size_t link_click_count() {
53 return link_click_callback_count_
;
57 size_t action_button_callback_count_
;
58 size_t dismiss_button_callback_count_
;
59 size_t link_click_callback_count_
;
62 // A test class for the SuspiciousExtensionBubbleController.
63 class TestSuspiciousExtensionBubbleController
64 : public SuspiciousExtensionBubbleController
,
67 explicit TestSuspiciousExtensionBubbleController(Profile
* profile
)
68 : SuspiciousExtensionBubbleController(profile
) {
71 virtual void OnBubbleAction() OVERRIDE
{
72 ++action_button_callback_count_
;
73 SuspiciousExtensionBubbleController::OnBubbleAction();
76 virtual void OnBubbleDismiss() OVERRIDE
{
77 ++dismiss_button_callback_count_
;
78 SuspiciousExtensionBubbleController::OnBubbleDismiss();
81 virtual void OnLinkClicked() OVERRIDE
{
82 ++link_click_callback_count_
;
83 SuspiciousExtensionBubbleController::OnLinkClicked();
87 // A test class for the DevModeBubbleController.
88 class TestDevModeBubbleController
89 : public DevModeBubbleController
,
92 explicit TestDevModeBubbleController(Profile
* profile
)
93 : DevModeBubbleController(profile
) {
96 virtual void OnBubbleAction() OVERRIDE
{
97 ++action_button_callback_count_
;
98 DevModeBubbleController::OnBubbleAction();
101 virtual void OnBubbleDismiss() OVERRIDE
{
102 ++dismiss_button_callback_count_
;
103 DevModeBubbleController::OnBubbleDismiss();
106 virtual void OnLinkClicked() OVERRIDE
{
107 ++link_click_callback_count_
;
108 DevModeBubbleController::OnLinkClicked();
112 // A test class for the SettingsApiBubbleController.
113 class TestSettingsApiBubbleController
: public SettingsApiBubbleController
,
114 public TestDelegate
{
116 TestSettingsApiBubbleController(Profile
* profile
,
117 SettingsApiOverrideType type
)
118 : SettingsApiBubbleController(profile
, type
) {}
120 virtual void OnBubbleAction() OVERRIDE
{
121 ++action_button_callback_count_
;
122 SettingsApiBubbleController::OnBubbleAction();
125 virtual void OnBubbleDismiss() OVERRIDE
{
126 ++dismiss_button_callback_count_
;
127 SettingsApiBubbleController::OnBubbleDismiss();
130 virtual void OnLinkClicked() OVERRIDE
{
131 ++link_click_callback_count_
;
132 SettingsApiBubbleController::OnLinkClicked();
136 // A test class for the NtpOverriddenBubbleController.
137 class TestNtpOverriddenBubbleController
138 : public NtpOverriddenBubbleController
,
139 public TestDelegate
{
141 explicit TestNtpOverriddenBubbleController(Profile
* profile
)
142 : NtpOverriddenBubbleController(profile
) {
145 virtual void OnBubbleAction() OVERRIDE
{
146 ++action_button_callback_count_
;
147 NtpOverriddenBubbleController::OnBubbleAction();
150 virtual void OnBubbleDismiss() OVERRIDE
{
151 ++dismiss_button_callback_count_
;
152 NtpOverriddenBubbleController::OnBubbleDismiss();
155 virtual void OnLinkClicked() OVERRIDE
{
156 ++link_click_callback_count_
;
157 NtpOverriddenBubbleController::OnLinkClicked();
161 // A fake bubble used for testing the controller. Takes an action that specifies
162 // what should happen when the bubble is "shown" (the bubble is actually not
163 // shown, the corresponding action is taken immediately).
164 class FakeExtensionMessageBubble
: public ExtensionMessageBubble
{
166 enum ExtensionBubbleAction
{
167 BUBBLE_ACTION_CLICK_ACTION_BUTTON
= 0,
168 BUBBLE_ACTION_CLICK_DISMISS_BUTTON
,
169 BUBBLE_ACTION_CLICK_LINK
,
172 FakeExtensionMessageBubble() {}
174 void set_action_on_show(ExtensionBubbleAction action
) {
178 virtual void Show() OVERRIDE
{
179 if (action_
== BUBBLE_ACTION_CLICK_ACTION_BUTTON
)
180 action_callback_
.Run();
181 else if (action_
== BUBBLE_ACTION_CLICK_DISMISS_BUTTON
)
182 dismiss_callback_
.Run();
183 else if (action_
== BUBBLE_ACTION_CLICK_LINK
)
184 link_callback_
.Run();
187 virtual void OnActionButtonClicked(const base::Closure
& callback
) OVERRIDE
{
188 action_callback_
= callback
;
191 virtual void OnDismissButtonClicked(const base::Closure
& callback
) OVERRIDE
{
192 dismiss_callback_
= callback
;
195 virtual void OnLinkClicked(const base::Closure
& callback
) OVERRIDE
{
196 link_callback_
= callback
;
200 ExtensionBubbleAction action_
;
202 base::Closure action_callback_
;
203 base::Closure dismiss_callback_
;
204 base::Closure link_callback_
;
207 class ExtensionMessageBubbleTest
: public testing::Test
{
209 ExtensionMessageBubbleTest() {}
211 void LoadGenericExtension(const std::string
& index
,
212 const std::string
& id
,
213 Manifest::Location location
) {
214 extensions::ExtensionBuilder builder
;
215 builder
.SetManifest(extensions::DictionaryBuilder()
216 .Set("name", std::string("Extension " + index
))
217 .Set("version", "1.0")
218 .Set("manifest_version", 2));
219 builder
.SetLocation(location
);
221 service_
->AddExtension(builder
.Build().get());
224 void LoadExtensionWithAction(const std::string
& index
,
225 const std::string
& id
,
226 Manifest::Location location
) {
227 extensions::ExtensionBuilder builder
;
228 builder
.SetManifest(extensions::DictionaryBuilder()
229 .Set("name", std::string("Extension " + index
))
230 .Set("version", "1.0")
231 .Set("manifest_version", 2)
232 .Set("browser_action",
233 extensions::DictionaryBuilder().Set(
234 "default_title", "Default title")));
235 builder
.SetLocation(location
);
237 service_
->AddExtension(builder
.Build().get());
240 void LoadExtensionOverridingHome(const std::string
& index
,
241 const std::string
& id
,
242 Manifest::Location location
) {
243 extensions::ExtensionBuilder builder
;
244 builder
.SetManifest(extensions::DictionaryBuilder()
245 .Set("name", std::string("Extension " + index
))
246 .Set("version", "1.0")
247 .Set("manifest_version", 2)
248 .Set("chrome_settings_overrides",
249 extensions::DictionaryBuilder().Set(
250 "homepage", "http://www.google.com")));
251 builder
.SetLocation(location
);
253 service_
->AddExtension(builder
.Build().get());
256 void LoadExtensionOverridingStart(const std::string
& index
,
257 const std::string
& id
,
258 Manifest::Location location
) {
259 extensions::ExtensionBuilder builder
;
260 builder
.SetManifest(extensions::DictionaryBuilder()
261 .Set("name", std::string("Extension " + index
))
262 .Set("version", "1.0")
263 .Set("manifest_version", 2)
264 .Set("chrome_settings_overrides",
265 extensions::DictionaryBuilder().Set(
267 extensions::ListBuilder().Append(
268 "http://www.google.com"))));
269 builder
.SetLocation(location
);
271 service_
->AddExtension(builder
.Build().get());
274 void LoadExtensionOverridingNtp(const std::string
& index
,
275 const std::string
& id
,
276 Manifest::Location location
) {
277 extensions::ExtensionBuilder builder
;
278 builder
.SetManifest(extensions::DictionaryBuilder()
279 .Set("name", std::string("Extension " + index
))
280 .Set("version", "1.0")
281 .Set("manifest_version", 2)
282 .Set("chrome_url_overrides",
283 extensions::DictionaryBuilder().Set(
284 "newtab", "Default.html")));
286 builder
.SetLocation(location
);
288 service_
->AddExtension(builder
.Build().get());
292 // The two lines of magical incantation required to get the extension
293 // service to work inside a unit test and access the extension prefs.
294 thread_bundle_
.reset(new content::TestBrowserThreadBundle
);
295 profile_
.reset(new TestingProfile
);
296 static_cast<TestExtensionSystem
*>(
297 ExtensionSystem::Get(profile()))->CreateExtensionService(
298 CommandLine::ForCurrentProcess(),
301 service_
= profile_
->GetExtensionService();
305 virtual ~ExtensionMessageBubbleTest() {
306 // Make sure the profile is destroyed before the thread bundle.
307 profile_
.reset(NULL
);
310 virtual void SetUp() {
311 command_line_
.reset(new CommandLine(CommandLine::NO_PROGRAM
));
315 Profile
* profile() { return profile_
.get(); }
317 scoped_refptr
<Extension
> CreateExtension(
318 Manifest::Location location
,
319 const std::string
& data
,
320 const std::string
& id
) {
321 scoped_ptr
<base::DictionaryValue
> parsed_manifest(
322 extension_function_test_utils::ParseDictionary(data
));
323 return extension_function_test_utils::CreateExtension(
325 parsed_manifest
.get(),
329 ExtensionService
* service_
;
332 scoped_ptr
<CommandLine
> command_line_
;
333 scoped_ptr
<content::TestBrowserThreadBundle
> thread_bundle_
;
334 scoped_ptr
<TestingProfile
> profile_
;
336 DISALLOW_COPY_AND_ASSIGN(ExtensionMessageBubbleTest
);
339 // The feature this is meant to test is only implemented on Windows.
341 #define MAYBE_WipeoutControllerTest WipeoutControllerTest
343 #define MAYBE_WipeoutControllerTest DISABLED_WipeoutControllerTest
346 TEST_F(ExtensionMessageBubbleTest
, MAYBE_WipeoutControllerTest
) {
348 // Add three extensions, and control two of them in this test (extension 1
350 LoadExtensionWithAction("1", kId1
, Manifest::COMMAND_LINE
);
351 LoadGenericExtension("2", kId2
, Manifest::UNPACKED
);
352 LoadGenericExtension("3", kId3
, Manifest::EXTERNAL_POLICY
);
354 scoped_ptr
<TestSuspiciousExtensionBubbleController
> controller(
355 new TestSuspiciousExtensionBubbleController(profile()));
356 FakeExtensionMessageBubble bubble
;
357 bubble
.set_action_on_show(
358 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON
);
360 // Validate that we don't have a suppress value for the extensions.
361 ExtensionPrefs
* prefs
= ExtensionPrefs::Get(profile());
362 EXPECT_FALSE(prefs
->HasWipeoutBeenAcknowledged(kId1
));
363 EXPECT_FALSE(prefs
->HasWipeoutBeenAcknowledged(kId2
));
365 EXPECT_FALSE(controller
->ShouldShow());
366 std::vector
<base::string16
> suspicious_extensions
=
367 controller
->GetExtensionList();
368 EXPECT_EQ(0U, suspicious_extensions
.size());
369 EXPECT_EQ(0U, controller
->link_click_count());
370 EXPECT_EQ(0U, controller
->dismiss_click_count());
372 // Now disable an extension, specifying the wipeout flag.
373 service_
->DisableExtension(kId1
, Extension::DISABLE_NOT_VERIFIED
);
375 EXPECT_FALSE(prefs
->HasWipeoutBeenAcknowledged(kId1
));
376 EXPECT_FALSE(prefs
->HasWipeoutBeenAcknowledged(kId2
));
377 controller
.reset(new TestSuspiciousExtensionBubbleController(
379 SuspiciousExtensionBubbleController::ClearProfileListForTesting();
380 EXPECT_TRUE(controller
->ShouldShow());
381 suspicious_extensions
= controller
->GetExtensionList();
382 ASSERT_EQ(1U, suspicious_extensions
.size());
383 EXPECT_TRUE(base::ASCIIToUTF16("Extension 1") == suspicious_extensions
[0]);
384 controller
->Show(&bubble
); // Simulate showing the bubble.
385 EXPECT_EQ(0U, controller
->link_click_count());
386 EXPECT_EQ(1U, controller
->dismiss_click_count());
387 // Now the acknowledge flag should be set only for the first extension.
388 EXPECT_TRUE(prefs
->HasWipeoutBeenAcknowledged(kId1
));
389 EXPECT_FALSE(prefs
->HasWipeoutBeenAcknowledged(kId2
));
391 prefs
->SetWipeoutAcknowledged(kId1
, false);
392 EXPECT_FALSE(prefs
->HasWipeoutBeenAcknowledged(kId1
));
394 // Now disable the other extension and exercise the link click code path.
395 service_
->DisableExtension(kId2
, Extension::DISABLE_NOT_VERIFIED
);
397 bubble
.set_action_on_show(
398 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK
);
399 controller
.reset(new TestSuspiciousExtensionBubbleController(
401 SuspiciousExtensionBubbleController::ClearProfileListForTesting();
402 EXPECT_TRUE(controller
->ShouldShow());
403 suspicious_extensions
= controller
->GetExtensionList();
404 ASSERT_EQ(2U, suspicious_extensions
.size());
405 EXPECT_TRUE(base::ASCIIToUTF16("Extension 1") == suspicious_extensions
[1]);
406 EXPECT_TRUE(base::ASCIIToUTF16("Extension 2") == suspicious_extensions
[0]);
407 controller
->Show(&bubble
); // Simulate showing the bubble.
408 EXPECT_EQ(1U, controller
->link_click_count());
409 EXPECT_EQ(0U, controller
->dismiss_click_count());
410 EXPECT_TRUE(prefs
->HasWipeoutBeenAcknowledged(kId1
));
413 // The feature this is meant to test is only implemented on Windows.
415 #define MAYBE_DevModeControllerTest DevModeControllerTest
417 #define MAYBE_DevModeControllerTest DISABLED_DevModeControllerTest
420 TEST_F(ExtensionMessageBubbleTest
, MAYBE_DevModeControllerTest
) {
421 FeatureSwitch::ScopedOverride
force_dev_mode_highlighting(
422 FeatureSwitch::force_dev_mode_highlighting(), true);
424 // Add three extensions, and control two of them in this test (extension 1
425 // and 2). Extension 1 is a regular extension, Extension 2 is UNPACKED so it
426 // counts as a DevMode extension.
427 LoadExtensionWithAction("1", kId1
, Manifest::COMMAND_LINE
);
428 LoadGenericExtension("2", kId2
, Manifest::UNPACKED
);
429 LoadGenericExtension("3", kId3
, Manifest::EXTERNAL_POLICY
);
431 scoped_ptr
<TestDevModeBubbleController
> controller(
432 new TestDevModeBubbleController(profile()));
434 // The list will contain one enabled unpacked extension.
435 EXPECT_TRUE(controller
->ShouldShow());
436 std::vector
<base::string16
> dev_mode_extensions
=
437 controller
->GetExtensionList();
438 ASSERT_EQ(2U, dev_mode_extensions
.size());
439 EXPECT_TRUE(base::ASCIIToUTF16("Extension 2") == dev_mode_extensions
[0]);
440 EXPECT_TRUE(base::ASCIIToUTF16("Extension 1") == dev_mode_extensions
[1]);
441 EXPECT_EQ(0U, controller
->link_click_count());
442 EXPECT_EQ(0U, controller
->dismiss_click_count());
443 EXPECT_EQ(0U, controller
->action_click_count());
445 // Simulate showing the bubble.
446 FakeExtensionMessageBubble bubble
;
447 bubble
.set_action_on_show(
448 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON
);
449 controller
->Show(&bubble
);
450 EXPECT_EQ(0U, controller
->link_click_count());
451 EXPECT_EQ(0U, controller
->action_click_count());
452 EXPECT_EQ(1U, controller
->dismiss_click_count());
453 EXPECT_TRUE(service_
->GetExtensionById(kId1
, false) != NULL
);
454 EXPECT_TRUE(service_
->GetExtensionById(kId2
, false) != NULL
);
456 // Do it again, but now press different button (Disable).
457 bubble
.set_action_on_show(
458 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_ACTION_BUTTON
);
459 controller
.reset(new TestDevModeBubbleController(
461 DevModeBubbleController::ClearProfileListForTesting();
462 EXPECT_TRUE(controller
->ShouldShow());
463 dev_mode_extensions
= controller
->GetExtensionList();
464 EXPECT_EQ(2U, dev_mode_extensions
.size());
465 controller
->Show(&bubble
); // Simulate showing the bubble.
466 EXPECT_EQ(0U, controller
->link_click_count());
467 EXPECT_EQ(1U, controller
->action_click_count());
468 EXPECT_EQ(0U, controller
->dismiss_click_count());
469 EXPECT_TRUE(service_
->GetExtensionById(kId1
, false) == NULL
);
470 EXPECT_TRUE(service_
->GetExtensionById(kId2
, false) == NULL
);
472 // Re-enable the extensions (disabled by the action button above).
473 service_
->EnableExtension(kId1
);
474 service_
->EnableExtension(kId2
);
476 // Show the dialog a third time, but now press the learn more link.
477 bubble
.set_action_on_show(
478 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK
);
479 controller
.reset(new TestDevModeBubbleController(
481 DevModeBubbleController::ClearProfileListForTesting();
482 EXPECT_TRUE(controller
->ShouldShow());
483 dev_mode_extensions
= controller
->GetExtensionList();
484 EXPECT_EQ(2U, dev_mode_extensions
.size());
485 controller
->Show(&bubble
); // Simulate showing the bubble.
486 EXPECT_EQ(1U, controller
->link_click_count());
487 EXPECT_EQ(0U, controller
->action_click_count());
488 EXPECT_EQ(0U, controller
->dismiss_click_count());
489 EXPECT_TRUE(service_
->GetExtensionById(kId1
, false) != NULL
);
490 EXPECT_TRUE(service_
->GetExtensionById(kId2
, false) != NULL
);
492 // Now disable the unpacked extension.
493 service_
->DisableExtension(kId1
, Extension::DISABLE_USER_ACTION
);
494 service_
->DisableExtension(kId2
, Extension::DISABLE_USER_ACTION
);
496 controller
.reset(new TestDevModeBubbleController(
498 DevModeBubbleController::ClearProfileListForTesting();
499 EXPECT_FALSE(controller
->ShouldShow());
500 dev_mode_extensions
= controller
->GetExtensionList();
501 EXPECT_EQ(0U, dev_mode_extensions
.size());
504 // The feature this is meant to test is only implemented on Windows.
506 #define MAYBE_SettingsApiControllerTest SettingsApiControllerTest
508 #define MAYBE_SettingsApiControllerTest DISABLED_SettingsApiControllerTest
511 TEST_F(ExtensionMessageBubbleTest
, MAYBE_SettingsApiControllerTest
) {
513 extensions::ExtensionPrefs
* prefs
=
514 extensions::ExtensionPrefs::Get(profile());
516 for (int i
= 0; i
< 3; ++i
) {
517 switch (static_cast<SettingsApiOverrideType
>(i
)) {
518 case BUBBLE_TYPE_HOME_PAGE
:
519 // Load two extensions overriding home page and one overriding something
520 // unrelated (to check for interference). Extension 2 should still win
521 // on the home page setting.
522 LoadExtensionOverridingHome("1", kId1
, Manifest::UNPACKED
);
523 LoadExtensionOverridingHome("2", kId2
, Manifest::UNPACKED
);
524 LoadExtensionOverridingStart("3", kId3
, Manifest::UNPACKED
);
526 case BUBBLE_TYPE_SEARCH_ENGINE
:
527 // We deliberately skip testing the search engine since it relies on
528 // TemplateURLServiceFactory that isn't available while unit testing.
529 // This test is only simulating the bubble interaction with the user and
530 // that is more or less the same for the search engine as it is for the
533 case BUBBLE_TYPE_STARTUP_PAGES
:
534 // Load two extensions overriding start page and one overriding
535 // something unrelated (to check for interference). Extension 2 should
536 // still win on the startup page setting.
537 LoadExtensionOverridingStart("1", kId1
, Manifest::UNPACKED
);
538 LoadExtensionOverridingStart("2", kId2
, Manifest::UNPACKED
);
539 LoadExtensionOverridingHome("3", kId3
, Manifest::UNPACKED
);
546 scoped_ptr
<TestSettingsApiBubbleController
> controller(
547 new TestSettingsApiBubbleController(
548 profile(), static_cast<SettingsApiOverrideType
>(i
)));
550 // The list will contain one enabled unpacked extension (ext 2).
551 EXPECT_TRUE(controller
->ShouldShow(kId2
));
552 std::vector
<base::string16
> override_extensions
=
553 controller
->GetExtensionList();
554 ASSERT_EQ(1U, override_extensions
.size());
555 EXPECT_TRUE(base::ASCIIToUTF16("Extension 2") ==
556 override_extensions
[0].c_str());
557 EXPECT_EQ(0U, controller
->link_click_count());
558 EXPECT_EQ(0U, controller
->dismiss_click_count());
559 EXPECT_EQ(0U, controller
->action_click_count());
561 // Simulate showing the bubble and dismissing it.
562 FakeExtensionMessageBubble bubble
;
563 bubble
.set_action_on_show(
564 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON
);
565 controller
->Show(&bubble
);
566 EXPECT_EQ(0U, controller
->link_click_count());
567 EXPECT_EQ(0U, controller
->action_click_count());
568 EXPECT_EQ(1U, controller
->dismiss_click_count());
569 // No extension should have become disabled.
570 EXPECT_TRUE(service_
->GetExtensionById(kId1
, false) != NULL
);
571 EXPECT_TRUE(service_
->GetExtensionById(kId2
, false) != NULL
);
572 EXPECT_TRUE(service_
->GetExtensionById(kId3
, false) != NULL
);
573 // Only extension 2 should have been acknowledged.
574 EXPECT_FALSE(prefs
->HasSettingsApiBubbleBeenAcknowledged(kId1
));
575 EXPECT_TRUE(prefs
->HasSettingsApiBubbleBeenAcknowledged(kId2
));
576 EXPECT_FALSE(prefs
->HasSettingsApiBubbleBeenAcknowledged(kId3
));
577 // Clean up after ourselves.
578 prefs
->SetSettingsApiBubbleBeenAcknowledged(kId2
, false);
580 // Simulate clicking the learn more link to dismiss it.
581 bubble
.set_action_on_show(
582 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK
);
583 controller
.reset(new TestSettingsApiBubbleController(
584 profile(), static_cast<SettingsApiOverrideType
>(i
)));
585 controller
->Show(&bubble
);
586 EXPECT_EQ(1U, controller
->link_click_count());
587 EXPECT_EQ(0U, controller
->action_click_count());
588 EXPECT_EQ(0U, controller
->dismiss_click_count());
589 // No extension should have become disabled.
590 EXPECT_TRUE(service_
->GetExtensionById(kId1
, false) != NULL
);
591 EXPECT_TRUE(service_
->GetExtensionById(kId2
, false) != NULL
);
592 EXPECT_TRUE(service_
->GetExtensionById(kId3
, false) != NULL
);
593 // Only extension 2 should have been acknowledged.
594 EXPECT_FALSE(prefs
->HasSettingsApiBubbleBeenAcknowledged(kId1
));
595 EXPECT_TRUE(prefs
->HasSettingsApiBubbleBeenAcknowledged(kId2
));
596 EXPECT_FALSE(prefs
->HasSettingsApiBubbleBeenAcknowledged(kId3
));
597 // Clean up after ourselves.
598 prefs
->SetSettingsApiBubbleBeenAcknowledged(kId2
, false);
600 // Do it again, but now opt to disable the extension.
601 bubble
.set_action_on_show(
602 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_ACTION_BUTTON
);
603 controller
.reset(new TestSettingsApiBubbleController(
604 profile(), static_cast<SettingsApiOverrideType
>(i
)));
605 EXPECT_TRUE(controller
->ShouldShow(kId2
));
606 override_extensions
= controller
->GetExtensionList();
607 EXPECT_EQ(1U, override_extensions
.size());
608 controller
->Show(&bubble
); // Simulate showing the bubble.
609 EXPECT_EQ(0U, controller
->link_click_count());
610 EXPECT_EQ(1U, controller
->action_click_count());
611 EXPECT_EQ(0U, controller
->dismiss_click_count());
612 // Only extension 2 should have become disabled.
613 EXPECT_TRUE(service_
->GetExtensionById(kId1
, false) != NULL
);
614 EXPECT_TRUE(service_
->GetExtensionById(kId2
, false) == NULL
);
615 EXPECT_TRUE(service_
->GetExtensionById(kId3
, false) != NULL
);
616 // No extension should have been acknowledged (it got disabled).
617 EXPECT_FALSE(prefs
->HasSettingsApiBubbleBeenAcknowledged(kId1
));
618 EXPECT_FALSE(prefs
->HasSettingsApiBubbleBeenAcknowledged(kId2
));
619 EXPECT_FALSE(prefs
->HasSettingsApiBubbleBeenAcknowledged(kId3
));
621 // Clean up after ourselves.
622 service_
->UninstallExtension(kId1
, false, NULL
);
623 service_
->UninstallExtension(kId2
, false, NULL
);
624 service_
->UninstallExtension(kId3
, false, NULL
);
628 // The feature this is meant to test is only implemented on Windows.
630 #define MAYBE_NtpOverriddenControllerTest NtpOverriddenControllerTest
632 #define MAYBE_NtpOverriddenControllerTest DISABLED_NtpOverriddenControllerTest
635 TEST_F(ExtensionMessageBubbleTest
, MAYBE_NtpOverriddenControllerTest
) {
637 extensions::ExtensionPrefs
* prefs
=
638 extensions::ExtensionPrefs::Get(profile());
639 // Load two extensions overriding new tab page and one overriding something
640 // unrelated (to check for interference). Extension 2 should still win
641 // on the new tab page setting.
642 LoadExtensionOverridingNtp("1", kId1
, Manifest::UNPACKED
);
643 LoadExtensionOverridingNtp("2", kId2
, Manifest::UNPACKED
);
644 LoadExtensionOverridingStart("3", kId3
, Manifest::UNPACKED
);
646 scoped_ptr
<TestNtpOverriddenBubbleController
> controller(
647 new TestNtpOverriddenBubbleController(profile()));
649 // The list will contain one enabled unpacked extension (ext 2).
650 EXPECT_TRUE(controller
->ShouldShow(kId2
));
651 std::vector
<base::string16
> override_extensions
=
652 controller
->GetExtensionList();
653 ASSERT_EQ(1U, override_extensions
.size());
654 EXPECT_TRUE(base::ASCIIToUTF16("Extension 2") ==
655 override_extensions
[0].c_str());
656 EXPECT_EQ(0U, controller
->link_click_count());
657 EXPECT_EQ(0U, controller
->dismiss_click_count());
658 EXPECT_EQ(0U, controller
->action_click_count());
660 // Simulate showing the bubble and dismissing it.
661 FakeExtensionMessageBubble bubble
;
662 bubble
.set_action_on_show(
663 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON
);
664 EXPECT_TRUE(controller
->ShouldShow(kId2
));
665 controller
->Show(&bubble
);
666 EXPECT_EQ(0U, controller
->link_click_count());
667 EXPECT_EQ(0U, controller
->action_click_count());
668 EXPECT_EQ(1U, controller
->dismiss_click_count());
669 // No extension should have become disabled.
670 EXPECT_TRUE(service_
->GetExtensionById(kId1
, false) != NULL
);
671 EXPECT_TRUE(service_
->GetExtensionById(kId2
, false) != NULL
);
672 EXPECT_TRUE(service_
->GetExtensionById(kId3
, false) != NULL
);
673 // Only extension 2 should have been acknowledged.
674 EXPECT_FALSE(prefs
->HasNtpOverriddenBubbleBeenAcknowledged(kId1
));
675 EXPECT_TRUE(prefs
->HasNtpOverriddenBubbleBeenAcknowledged(kId2
));
676 EXPECT_FALSE(prefs
->HasNtpOverriddenBubbleBeenAcknowledged(kId3
));
677 // Clean up after ourselves.
678 prefs
->SetNtpOverriddenBubbleBeenAcknowledged(kId2
, false);
680 // Simulate clicking the learn more link to dismiss it.
681 bubble
.set_action_on_show(
682 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK
);
683 controller
.reset(new TestNtpOverriddenBubbleController(profile()));
684 EXPECT_TRUE(controller
->ShouldShow(kId2
));
685 controller
->Show(&bubble
);
686 EXPECT_EQ(1U, controller
->link_click_count());
687 EXPECT_EQ(0U, controller
->action_click_count());
688 EXPECT_EQ(0U, controller
->dismiss_click_count());
689 // No extension should have become disabled.
690 EXPECT_TRUE(service_
->GetExtensionById(kId1
, false) != NULL
);
691 EXPECT_TRUE(service_
->GetExtensionById(kId2
, false) != NULL
);
692 EXPECT_TRUE(service_
->GetExtensionById(kId3
, false) != NULL
);
693 // Only extension 2 should have been acknowledged.
694 EXPECT_FALSE(prefs
->HasNtpOverriddenBubbleBeenAcknowledged(kId1
));
695 EXPECT_TRUE(prefs
->HasNtpOverriddenBubbleBeenAcknowledged(kId2
));
696 EXPECT_FALSE(prefs
->HasNtpOverriddenBubbleBeenAcknowledged(kId3
));
697 // Clean up after ourselves.
698 prefs
->SetNtpOverriddenBubbleBeenAcknowledged(kId2
, false);
700 // Do it again, but now opt to disable the extension.
701 bubble
.set_action_on_show(
702 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_ACTION_BUTTON
);
703 controller
.reset(new TestNtpOverriddenBubbleController(profile()));
704 EXPECT_TRUE(controller
->ShouldShow(kId2
));
705 override_extensions
= controller
->GetExtensionList();
706 EXPECT_EQ(1U, override_extensions
.size());
707 controller
->Show(&bubble
); // Simulate showing the bubble.
708 EXPECT_EQ(0U, controller
->link_click_count());
709 EXPECT_EQ(1U, controller
->action_click_count());
710 EXPECT_EQ(0U, controller
->dismiss_click_count());
711 // Only extension 2 should have become disabled.
712 EXPECT_TRUE(service_
->GetExtensionById(kId1
, false) != NULL
);
713 EXPECT_TRUE(service_
->GetExtensionById(kId2
, false) == NULL
);
714 EXPECT_TRUE(service_
->GetExtensionById(kId3
, false) != NULL
);
715 // No extension should have been acknowledged (it got disabled).
716 EXPECT_FALSE(prefs
->HasNtpOverriddenBubbleBeenAcknowledged(kId1
));
717 EXPECT_FALSE(prefs
->HasNtpOverriddenBubbleBeenAcknowledged(kId2
));
718 EXPECT_FALSE(prefs
->HasNtpOverriddenBubbleBeenAcknowledged(kId3
));
720 // Clean up after ourselves.
721 service_
->UninstallExtension(kId1
, false, NULL
);
722 service_
->UninstallExtension(kId2
, false, NULL
);
723 service_
->UninstallExtension(kId3
, false, NULL
);
726 } // namespace extensions