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_number_conversions.h"
7 #include "base/strings/string_util.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "base/values.h"
10 #include "chrome/browser/extensions/dev_mode_bubble_controller.h"
11 #include "chrome/browser/extensions/extension_function_test_utils.h"
12 #include "chrome/browser/extensions/extension_message_bubble.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/extensions/ntp_overridden_bubble_controller.h"
15 #include "chrome/browser/extensions/proxy_overridden_bubble_controller.h"
16 #include "chrome/browser/extensions/settings_api_bubble_controller.h"
17 #include "chrome/browser/extensions/suspicious_extension_bubble_controller.h"
18 #include "chrome/browser/extensions/test_extension_system.h"
19 #include "chrome/test/base/browser_with_test_window_test.h"
20 #include "chrome/test/base/testing_profile.h"
21 #include "components/proxy_config/proxy_config_pref_names.h"
22 #include "content/public/test/test_browser_thread_bundle.h"
23 #include "extensions/browser/api_test_utils.h"
24 #include "extensions/browser/extension_pref_value_map.h"
25 #include "extensions/browser/extension_pref_value_map_factory.h"
26 #include "extensions/browser/extension_prefs.h"
27 #include "extensions/browser/extension_registry.h"
28 #include "extensions/browser/extension_system.h"
29 #include "extensions/browser/uninstall_reason.h"
30 #include "extensions/common/extension.h"
31 #include "extensions/common/extension_builder.h"
32 #include "extensions/common/feature_switch.h"
33 #include "extensions/common/value_builder.h"
34 #include "testing/gtest/include/gtest/gtest.h"
38 const char kId1
[] = "iccfkkhkfiphcjdakkmcjmkfboccmndk";
39 const char kId2
[] = "ajjhifimiemdpmophmkkkcijegphclbl";
40 const char kId3
[] = "ioibbbfddncmmabjmpokikkeiofalaek";
44 namespace extensions
{
49 : action_button_callback_count_(0),
50 dismiss_button_callback_count_(0),
51 link_click_callback_count_(0) {
54 // Returns how often the dismiss button has been called.
55 size_t action_click_count() {
56 return action_button_callback_count_
;
59 // Returns how often the dismiss button has been called.
60 size_t dismiss_click_count() {
61 return dismiss_button_callback_count_
;
64 // Returns how often the link has been clicked.
65 size_t link_click_count() {
66 return link_click_callback_count_
;
70 size_t action_button_callback_count_
;
71 size_t dismiss_button_callback_count_
;
72 size_t link_click_callback_count_
;
75 // A test class for the SuspiciousExtensionBubbleController.
76 class TestSuspiciousExtensionBubbleController
77 : public SuspiciousExtensionBubbleController
,
80 explicit TestSuspiciousExtensionBubbleController(Browser
* browser
)
81 : SuspiciousExtensionBubbleController(browser
) {
84 void OnBubbleAction() override
{
85 ++action_button_callback_count_
;
86 SuspiciousExtensionBubbleController::OnBubbleAction();
89 void OnBubbleDismiss() override
{
90 ++dismiss_button_callback_count_
;
91 SuspiciousExtensionBubbleController::OnBubbleDismiss();
94 void OnLinkClicked() override
{
95 ++link_click_callback_count_
;
96 SuspiciousExtensionBubbleController::OnLinkClicked();
100 // A test class for the DevModeBubbleController.
101 class TestDevModeBubbleController
102 : public DevModeBubbleController
,
103 public TestDelegate
{
105 explicit TestDevModeBubbleController(Browser
* browser
)
106 : DevModeBubbleController(browser
) {
109 void OnBubbleAction() override
{
110 ++action_button_callback_count_
;
111 DevModeBubbleController::OnBubbleAction();
114 void OnBubbleDismiss() override
{
115 ++dismiss_button_callback_count_
;
116 DevModeBubbleController::OnBubbleDismiss();
119 void OnLinkClicked() override
{
120 ++link_click_callback_count_
;
121 DevModeBubbleController::OnLinkClicked();
125 // A test class for the SettingsApiBubbleController.
126 class TestSettingsApiBubbleController
: public SettingsApiBubbleController
,
127 public TestDelegate
{
129 TestSettingsApiBubbleController(Browser
* browser
,
130 SettingsApiOverrideType type
)
131 : SettingsApiBubbleController(browser
, type
) {}
133 void OnBubbleAction() override
{
134 ++action_button_callback_count_
;
135 SettingsApiBubbleController::OnBubbleAction();
138 void OnBubbleDismiss() override
{
139 ++dismiss_button_callback_count_
;
140 SettingsApiBubbleController::OnBubbleDismiss();
143 void OnLinkClicked() override
{
144 ++link_click_callback_count_
;
145 SettingsApiBubbleController::OnLinkClicked();
149 // A test class for the NtpOverriddenBubbleController.
150 class TestNtpOverriddenBubbleController
151 : public NtpOverriddenBubbleController
,
152 public TestDelegate
{
154 explicit TestNtpOverriddenBubbleController(Browser
* browser
)
155 : NtpOverriddenBubbleController(browser
) {
158 void OnBubbleAction() override
{
159 ++action_button_callback_count_
;
160 NtpOverriddenBubbleController::OnBubbleAction();
163 void OnBubbleDismiss() override
{
164 ++dismiss_button_callback_count_
;
165 NtpOverriddenBubbleController::OnBubbleDismiss();
168 void OnLinkClicked() override
{
169 ++link_click_callback_count_
;
170 NtpOverriddenBubbleController::OnLinkClicked();
174 // A test class for the ProxyOverriddenBubbleController.
175 class TestProxyOverriddenBubbleController
176 : public ProxyOverriddenBubbleController
,
177 public TestDelegate
{
179 explicit TestProxyOverriddenBubbleController(Browser
* browser
)
180 : ProxyOverriddenBubbleController(browser
) {
183 void OnBubbleAction() override
{
184 ++action_button_callback_count_
;
185 ProxyOverriddenBubbleController::OnBubbleAction();
188 void OnBubbleDismiss() override
{
189 ++dismiss_button_callback_count_
;
190 ProxyOverriddenBubbleController::OnBubbleDismiss();
193 void OnLinkClicked() override
{
194 ++link_click_callback_count_
;
195 ProxyOverriddenBubbleController::OnLinkClicked();
199 // A fake bubble used for testing the controller. Takes an action that specifies
200 // what should happen when the bubble is "shown" (the bubble is actually not
201 // shown, the corresponding action is taken immediately).
202 class FakeExtensionMessageBubble
: public ExtensionMessageBubble
{
204 enum ExtensionBubbleAction
{
205 BUBBLE_ACTION_CLICK_ACTION_BUTTON
= 0,
206 BUBBLE_ACTION_CLICK_DISMISS_BUTTON
,
207 BUBBLE_ACTION_CLICK_LINK
,
210 FakeExtensionMessageBubble() : controller_(nullptr) {}
212 void set_action_on_show(ExtensionBubbleAction action
) {
215 void set_controller(ExtensionMessageBubbleController
* controller
) {
216 controller_
= controller
;
219 void Show() override
{
220 if (action_
== BUBBLE_ACTION_CLICK_ACTION_BUTTON
)
221 controller_
->OnBubbleAction();
222 else if (action_
== BUBBLE_ACTION_CLICK_DISMISS_BUTTON
)
223 controller_
->OnBubbleDismiss();
224 else if (action_
== BUBBLE_ACTION_CLICK_LINK
)
225 controller_
->OnLinkClicked();
229 ExtensionBubbleAction action_
;
230 ExtensionMessageBubbleController
* controller_
;
232 DISALLOW_COPY_AND_ASSIGN(FakeExtensionMessageBubble
);
235 class ExtensionMessageBubbleTest
: public BrowserWithTestWindowTest
{
237 ExtensionMessageBubbleTest() {}
239 testing::AssertionResult
LoadGenericExtension(const std::string
& index
,
240 const std::string
& id
,
241 Manifest::Location location
) {
242 ExtensionBuilder builder
;
243 builder
.SetManifest(DictionaryBuilder()
244 .Set("name", std::string("Extension " + index
))
245 .Set("version", "1.0")
246 .Set("manifest_version", 2));
247 builder
.SetLocation(location
);
249 service_
->AddExtension(builder
.Build().get());
251 if (ExtensionRegistry::Get(profile())->enabled_extensions().GetByID(id
))
252 return testing::AssertionSuccess();
253 return testing::AssertionFailure() << "Could not install extension: " << id
;
256 testing::AssertionResult
LoadExtensionWithAction(
257 const std::string
& index
,
258 const std::string
& id
,
259 Manifest::Location location
) {
260 ExtensionBuilder builder
;
261 builder
.SetManifest(DictionaryBuilder()
262 .Set("name", std::string("Extension " + index
))
263 .Set("version", "1.0")
264 .Set("manifest_version", 2)
265 .Set("browser_action",
266 DictionaryBuilder().Set(
267 "default_title", "Default title")));
268 builder
.SetLocation(location
);
270 service_
->AddExtension(builder
.Build().get());
272 if (ExtensionRegistry::Get(profile())->enabled_extensions().GetByID(id
))
273 return testing::AssertionSuccess();
274 return testing::AssertionFailure() << "Could not install extension: " << id
;
277 testing::AssertionResult
LoadExtensionOverridingHome(
278 const std::string
& index
,
279 const std::string
& id
,
280 Manifest::Location location
) {
281 ExtensionBuilder builder
;
282 builder
.SetManifest(DictionaryBuilder()
283 .Set("name", std::string("Extension " + index
))
284 .Set("version", "1.0")
285 .Set("manifest_version", 2)
286 .Set("chrome_settings_overrides",
287 DictionaryBuilder().Set(
288 "homepage", "http://www.google.com")));
289 builder
.SetLocation(location
);
291 service_
->AddExtension(builder
.Build().get());
293 if (ExtensionRegistry::Get(profile())->enabled_extensions().GetByID(id
))
294 return testing::AssertionSuccess();
295 return testing::AssertionFailure() << "Could not install extension: " << id
;
298 testing::AssertionResult
LoadExtensionOverridingStart(
299 const std::string
& index
,
300 const std::string
& id
,
301 Manifest::Location location
) {
302 ExtensionBuilder builder
;
303 builder
.SetManifest(DictionaryBuilder()
304 .Set("name", std::string("Extension " + index
))
305 .Set("version", "1.0")
306 .Set("manifest_version", 2)
307 .Set("chrome_settings_overrides",
308 DictionaryBuilder().Set(
310 ListBuilder().Append(
311 "http://www.google.com"))));
312 builder
.SetLocation(location
);
314 service_
->AddExtension(builder
.Build().get());
316 if (ExtensionRegistry::Get(profile())->enabled_extensions().GetByID(id
))
317 return testing::AssertionSuccess();
318 return testing::AssertionFailure() << "Could not install extension: " << id
;
321 testing::AssertionResult
LoadExtensionOverridingNtp(
322 const std::string
& index
,
323 const std::string
& id
,
324 Manifest::Location location
) {
325 ExtensionBuilder builder
;
326 builder
.SetManifest(DictionaryBuilder()
327 .Set("name", std::string("Extension " + index
))
328 .Set("version", "1.0")
329 .Set("manifest_version", 2)
330 .Set("chrome_url_overrides",
331 DictionaryBuilder().Set(
332 "newtab", "Default.html")));
334 builder
.SetLocation(location
);
336 service_
->AddExtension(builder
.Build().get());
338 if (ExtensionRegistry::Get(profile())->enabled_extensions().GetByID(id
))
339 return testing::AssertionSuccess();
340 return testing::AssertionFailure() << "Could not install extension: " << id
;
343 testing::AssertionResult
LoadExtensionOverridingProxy(
344 const std::string
& index
,
345 const std::string
& id
,
346 Manifest::Location location
) {
347 ExtensionBuilder builder
;
348 builder
.SetManifest(DictionaryBuilder()
349 .Set("name", std::string("Extension " + index
))
350 .Set("version", "1.0")
351 .Set("manifest_version", 2)
353 ListBuilder().Append("proxy")));
355 builder
.SetLocation(location
);
357 service_
->AddExtension(builder
.Build().get());
359 // The proxy check relies on ExtensionPrefValueMap being up to date as to
360 // specifying which extension is controlling the proxy, but unfortunately
361 // that Map is not updated automatically for unit tests, so we simulate the
362 // update here to avoid test failures.
363 ExtensionPrefValueMap
* extension_prefs_value_map
=
364 ExtensionPrefValueMapFactory::GetForBrowserContext(profile());
365 extension_prefs_value_map
->RegisterExtension(
369 false); // is_incognito_enabled.
370 extension_prefs_value_map
->SetExtensionPref(id
, proxy_config::prefs::kProxy
,
371 kExtensionPrefsScopeRegular
,
372 new base::StringValue(id
));
374 if (ExtensionRegistry::Get(profile())->enabled_extensions().GetByID(id
))
375 return testing::AssertionSuccess();
376 return testing::AssertionFailure() << "Could not install extension: " << id
;
380 // The two lines of magical incantation required to get the extension
381 // service to work inside a unit test and access the extension prefs.
382 static_cast<TestExtensionSystem
*>(ExtensionSystem::Get(profile()))
383 ->CreateExtensionService(base::CommandLine::ForCurrentProcess(),
384 base::FilePath(), false);
385 service_
= ExtensionSystem::Get(profile())->extension_service();
389 ~ExtensionMessageBubbleTest() override
{}
391 void SetUp() override
{
392 BrowserWithTestWindowTest::SetUp();
393 command_line_
.reset(new base::CommandLine(base::CommandLine::NO_PROGRAM
));
394 ExtensionMessageBubbleController::set_should_ignore_learn_more_for_testing(
398 void TearDown() override
{
399 ExtensionMessageBubbleController::set_should_ignore_learn_more_for_testing(
401 BrowserWithTestWindowTest::TearDown();
405 scoped_refptr
<Extension
> CreateExtension(
406 Manifest::Location location
,
407 const std::string
& data
,
408 const std::string
& id
) {
409 scoped_ptr
<base::DictionaryValue
> parsed_manifest(
410 api_test_utils::ParseDictionary(data
));
411 return api_test_utils::CreateExtension(location
, parsed_manifest
.get(), id
);
414 ExtensionService
* service_
;
417 scoped_ptr
<base::CommandLine
> command_line_
;
419 DISALLOW_COPY_AND_ASSIGN(ExtensionMessageBubbleTest
);
422 // The feature this is meant to test is only enacted on Windows, but it should
423 // pass on all platforms.
424 TEST_F(ExtensionMessageBubbleTest
, WipeoutControllerTest
) {
426 // Add three extensions, and control two of them in this test (extension 1
428 ASSERT_TRUE(LoadExtensionWithAction("1", kId1
, Manifest::COMMAND_LINE
));
429 ASSERT_TRUE(LoadGenericExtension("2", kId2
, Manifest::UNPACKED
));
430 ASSERT_TRUE(LoadGenericExtension("3", kId3
, Manifest::EXTERNAL_POLICY
));
432 scoped_ptr
<TestSuspiciousExtensionBubbleController
> controller(
433 new TestSuspiciousExtensionBubbleController(browser()));
434 FakeExtensionMessageBubble bubble
;
435 bubble
.set_action_on_show(
436 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON
);
438 // Validate that we don't have a suppress value for the extensions.
439 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
440 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
442 EXPECT_FALSE(controller
->ShouldShow());
443 std::vector
<base::string16
> suspicious_extensions
=
444 controller
->GetExtensionList();
445 EXPECT_EQ(0U, suspicious_extensions
.size());
446 EXPECT_EQ(0U, controller
->link_click_count());
447 EXPECT_EQ(0U, controller
->dismiss_click_count());
449 // Now disable an extension, specifying the wipeout flag.
450 service_
->DisableExtension(kId1
, Extension::DISABLE_NOT_VERIFIED
);
452 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
453 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId2
));
454 controller
.reset(new TestSuspiciousExtensionBubbleController(
456 SuspiciousExtensionBubbleController::ClearProfileListForTesting();
457 EXPECT_TRUE(controller
->ShouldShow());
458 suspicious_extensions
= controller
->GetExtensionList();
459 ASSERT_EQ(1U, suspicious_extensions
.size());
460 EXPECT_TRUE(base::ASCIIToUTF16("Extension 1") == suspicious_extensions
[0]);
461 bubble
.set_controller(controller
.get());
462 controller
->Show(&bubble
); // Simulate showing the bubble.
463 EXPECT_EQ(0U, controller
->link_click_count());
464 EXPECT_EQ(1U, controller
->dismiss_click_count());
465 // Now the acknowledge flag should be set only for the first extension.
466 EXPECT_TRUE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
467 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId2
));
469 controller
->delegate()->SetBubbleInfoBeenAcknowledged(kId1
, false);
470 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
472 // Now disable the other extension and exercise the link click code path.
473 service_
->DisableExtension(kId2
, Extension::DISABLE_NOT_VERIFIED
);
475 bubble
.set_action_on_show(
476 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK
);
477 controller
.reset(new TestSuspiciousExtensionBubbleController(
479 SuspiciousExtensionBubbleController::ClearProfileListForTesting();
480 EXPECT_TRUE(controller
->ShouldShow());
481 suspicious_extensions
= controller
->GetExtensionList();
482 ASSERT_EQ(2U, suspicious_extensions
.size());
483 EXPECT_TRUE(base::ASCIIToUTF16("Extension 1") == suspicious_extensions
[1]);
484 EXPECT_TRUE(base::ASCIIToUTF16("Extension 2") == suspicious_extensions
[0]);
485 bubble
.set_controller(controller
.get());
486 controller
->Show(&bubble
); // Simulate showing the bubble.
487 EXPECT_EQ(1U, controller
->link_click_count());
488 EXPECT_EQ(0U, controller
->dismiss_click_count());
489 EXPECT_TRUE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
492 // The feature this is meant to test is only enacted on Windows, but it should
493 // pass on all platforms.
494 TEST_F(ExtensionMessageBubbleTest
, DevModeControllerTest
) {
495 FeatureSwitch::ScopedOverride
force_dev_mode_highlighting(
496 FeatureSwitch::force_dev_mode_highlighting(), true);
498 // Add three extensions, and control two of them in this test (extension 1
499 // and 2). Extension 1 is a regular extension, Extension 2 is UNPACKED so it
500 // counts as a DevMode extension.
501 ASSERT_TRUE(LoadExtensionWithAction("1", kId1
, Manifest::COMMAND_LINE
));
502 ASSERT_TRUE(LoadGenericExtension("2", kId2
, Manifest::UNPACKED
));
503 ASSERT_TRUE(LoadGenericExtension("3", kId3
, Manifest::EXTERNAL_POLICY
));
505 scoped_ptr
<TestDevModeBubbleController
> controller(
506 new TestDevModeBubbleController(browser()));
508 // The list will contain one enabled unpacked extension.
509 EXPECT_TRUE(controller
->ShouldShow());
510 std::vector
<base::string16
> dev_mode_extensions
=
511 controller
->GetExtensionList();
512 ASSERT_EQ(2U, dev_mode_extensions
.size());
513 EXPECT_TRUE(base::ASCIIToUTF16("Extension 2") == dev_mode_extensions
[0]);
514 EXPECT_TRUE(base::ASCIIToUTF16("Extension 1") == dev_mode_extensions
[1]);
515 EXPECT_EQ(0U, controller
->link_click_count());
516 EXPECT_EQ(0U, controller
->dismiss_click_count());
517 EXPECT_EQ(0U, controller
->action_click_count());
519 // Simulate showing the bubble.
520 FakeExtensionMessageBubble bubble
;
521 bubble
.set_action_on_show(
522 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON
);
523 bubble
.set_controller(controller
.get());
524 controller
->Show(&bubble
);
525 EXPECT_EQ(0U, controller
->link_click_count());
526 EXPECT_EQ(0U, controller
->action_click_count());
527 EXPECT_EQ(1U, controller
->dismiss_click_count());
528 ExtensionRegistry
* registry
= ExtensionRegistry::Get(profile());
529 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId1
) != NULL
);
530 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId2
) != NULL
);
532 // Do it again, but now press different button (Disable).
533 bubble
.set_action_on_show(
534 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_ACTION_BUTTON
);
535 controller
.reset(new TestDevModeBubbleController(
537 DevModeBubbleController::ClearProfileListForTesting();
538 EXPECT_TRUE(controller
->ShouldShow());
539 dev_mode_extensions
= controller
->GetExtensionList();
540 EXPECT_EQ(2U, dev_mode_extensions
.size());
541 bubble
.set_controller(controller
.get());
542 controller
->Show(&bubble
); // Simulate showing the bubble.
543 EXPECT_EQ(0U, controller
->link_click_count());
544 EXPECT_EQ(1U, controller
->action_click_count());
545 EXPECT_EQ(0U, controller
->dismiss_click_count());
546 EXPECT_TRUE(registry
->disabled_extensions().GetByID(kId1
) != NULL
);
547 EXPECT_TRUE(registry
->disabled_extensions().GetByID(kId2
) != NULL
);
549 // Re-enable the extensions (disabled by the action button above).
550 service_
->EnableExtension(kId1
);
551 service_
->EnableExtension(kId2
);
553 // Show the dialog a third time, but now press the learn more link.
554 bubble
.set_action_on_show(
555 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK
);
556 controller
.reset(new TestDevModeBubbleController(
558 DevModeBubbleController::ClearProfileListForTesting();
559 EXPECT_TRUE(controller
->ShouldShow());
560 dev_mode_extensions
= controller
->GetExtensionList();
561 EXPECT_EQ(2U, dev_mode_extensions
.size());
562 bubble
.set_controller(controller
.get());
563 controller
->Show(&bubble
); // Simulate showing the bubble.
564 EXPECT_EQ(1U, controller
->link_click_count());
565 EXPECT_EQ(0U, controller
->action_click_count());
566 EXPECT_EQ(0U, controller
->dismiss_click_count());
567 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId1
) != NULL
);
568 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId2
) != NULL
);
570 // Now disable the unpacked extension.
571 service_
->DisableExtension(kId1
, Extension::DISABLE_USER_ACTION
);
572 service_
->DisableExtension(kId2
, Extension::DISABLE_USER_ACTION
);
574 controller
.reset(new TestDevModeBubbleController(
576 DevModeBubbleController::ClearProfileListForTesting();
577 EXPECT_FALSE(controller
->ShouldShow());
578 dev_mode_extensions
= controller
->GetExtensionList();
579 EXPECT_EQ(0U, dev_mode_extensions
.size());
582 // The feature this is meant to test is only implemented on Windows.
584 #define MAYBE_SettingsApiControllerTest SettingsApiControllerTest
586 #define MAYBE_SettingsApiControllerTest DISABLED_SettingsApiControllerTest
589 TEST_F(ExtensionMessageBubbleTest
, MAYBE_SettingsApiControllerTest
) {
592 for (int i
= 0; i
< 3; ++i
) {
593 switch (static_cast<SettingsApiOverrideType
>(i
)) {
594 case BUBBLE_TYPE_HOME_PAGE
:
595 // Load two extensions overriding home page and one overriding something
596 // unrelated (to check for interference). Extension 2 should still win
597 // on the home page setting.
598 ASSERT_TRUE(LoadExtensionOverridingHome("1", kId1
, Manifest::UNPACKED
));
599 ASSERT_TRUE(LoadExtensionOverridingHome("2", kId2
, Manifest::UNPACKED
));
601 LoadExtensionOverridingStart("3", kId3
, Manifest::UNPACKED
));
603 case BUBBLE_TYPE_SEARCH_ENGINE
:
604 // We deliberately skip testing the search engine since it relies on
605 // TemplateURLServiceFactory that isn't available while unit testing.
606 // This test is only simulating the bubble interaction with the user and
607 // that is more or less the same for the search engine as it is for the
610 case BUBBLE_TYPE_STARTUP_PAGES
:
611 // Load two extensions overriding start page and one overriding
612 // something unrelated (to check for interference). Extension 2 should
613 // still win on the startup page setting.
615 LoadExtensionOverridingStart("1", kId1
, Manifest::UNPACKED
));
617 LoadExtensionOverridingStart("2", kId2
, Manifest::UNPACKED
));
618 ASSERT_TRUE(LoadExtensionOverridingHome("3", kId3
, Manifest::UNPACKED
));
625 scoped_ptr
<TestSettingsApiBubbleController
> controller(
626 new TestSettingsApiBubbleController(
627 browser(), static_cast<SettingsApiOverrideType
>(i
)));
629 // The list will contain one enabled unpacked extension (ext 2).
630 EXPECT_TRUE(controller
->ShouldShow());
631 std::vector
<base::string16
> override_extensions
=
632 controller
->GetExtensionList();
633 ASSERT_EQ(1U, override_extensions
.size());
634 EXPECT_TRUE(base::ASCIIToUTF16("Extension 2") ==
635 override_extensions
[0].c_str());
636 EXPECT_EQ(0U, controller
->link_click_count());
637 EXPECT_EQ(0U, controller
->dismiss_click_count());
638 EXPECT_EQ(0U, controller
->action_click_count());
640 // Simulate showing the bubble and dismissing it.
641 FakeExtensionMessageBubble bubble
;
642 bubble
.set_action_on_show(
643 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON
);
644 bubble
.set_controller(controller
.get());
645 controller
->Show(&bubble
);
646 EXPECT_EQ(0U, controller
->link_click_count());
647 EXPECT_EQ(0U, controller
->action_click_count());
648 EXPECT_EQ(1U, controller
->dismiss_click_count());
649 // No extension should have become disabled.
650 ExtensionRegistry
* registry
= ExtensionRegistry::Get(profile());
651 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId1
) != NULL
);
652 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId2
) != NULL
);
653 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId3
) != NULL
);
654 // Only extension 2 should have been acknowledged.
655 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
656 EXPECT_TRUE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId2
));
657 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId3
));
658 // Clean up after ourselves.
659 controller
->delegate()->SetBubbleInfoBeenAcknowledged(kId2
, false);
661 // Simulate clicking the learn more link to dismiss it.
662 bubble
.set_action_on_show(
663 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK
);
664 controller
.reset(new TestSettingsApiBubbleController(
665 browser(), static_cast<SettingsApiOverrideType
>(i
)));
666 bubble
.set_controller(controller
.get());
667 controller
->Show(&bubble
);
668 EXPECT_EQ(1U, controller
->link_click_count());
669 EXPECT_EQ(0U, controller
->action_click_count());
670 EXPECT_EQ(0U, controller
->dismiss_click_count());
671 // No extension should have become disabled.
672 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId1
) != NULL
);
673 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId2
) != NULL
);
674 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId3
) != NULL
);
675 // Only extension 2 should have been acknowledged.
676 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
677 EXPECT_TRUE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId2
));
678 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId3
));
679 // Clean up after ourselves.
680 controller
->delegate()->SetBubbleInfoBeenAcknowledged(kId2
, false);
682 // Do it again, but now opt to disable the extension.
683 bubble
.set_action_on_show(
684 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_ACTION_BUTTON
);
685 controller
.reset(new TestSettingsApiBubbleController(
686 browser(), static_cast<SettingsApiOverrideType
>(i
)));
687 EXPECT_TRUE(controller
->ShouldShow());
688 override_extensions
= controller
->GetExtensionList();
689 EXPECT_EQ(1U, override_extensions
.size());
690 bubble
.set_controller(controller
.get());
691 controller
->Show(&bubble
); // Simulate showing the bubble.
692 EXPECT_EQ(0U, controller
->link_click_count());
693 EXPECT_EQ(1U, controller
->action_click_count());
694 EXPECT_EQ(0U, controller
->dismiss_click_count());
695 // Only extension 2 should have become disabled.
696 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId1
) != NULL
);
697 EXPECT_TRUE(registry
->disabled_extensions().GetByID(kId2
) != NULL
);
698 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId3
) != NULL
);
699 // No extension should have been acknowledged (it got disabled).
700 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
701 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId2
));
702 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId3
));
704 // Clean up after ourselves.
705 service_
->UninstallExtension(kId1
,
706 extensions::UNINSTALL_REASON_FOR_TESTING
,
707 base::Bind(&base::DoNothing
),
709 service_
->UninstallExtension(kId2
,
710 extensions::UNINSTALL_REASON_FOR_TESTING
,
711 base::Bind(&base::DoNothing
),
713 service_
->UninstallExtension(kId3
,
714 extensions::UNINSTALL_REASON_FOR_TESTING
,
715 base::Bind(&base::DoNothing
),
720 // The feature this is meant to test is only enacted on Windows, but it should
721 // pass on all platforms.
722 TEST_F(ExtensionMessageBubbleTest
, NtpOverriddenControllerTest
) {
724 // Load two extensions overriding new tab page and one overriding something
725 // unrelated (to check for interference). Extension 2 should still win
726 // on the new tab page setting.
727 ASSERT_TRUE(LoadExtensionOverridingNtp("1", kId1
, Manifest::UNPACKED
));
728 ASSERT_TRUE(LoadExtensionOverridingNtp("2", kId2
, Manifest::UNPACKED
));
729 ASSERT_TRUE(LoadExtensionOverridingStart("3", kId3
, Manifest::UNPACKED
));
731 scoped_ptr
<TestNtpOverriddenBubbleController
> controller(
732 new TestNtpOverriddenBubbleController(browser()));
734 // The list will contain one enabled unpacked extension (ext 2).
735 EXPECT_TRUE(controller
->ShouldShow(kId2
));
736 std::vector
<base::string16
> override_extensions
=
737 controller
->GetExtensionList();
738 ASSERT_EQ(1U, override_extensions
.size());
739 EXPECT_TRUE(base::ASCIIToUTF16("Extension 2") ==
740 override_extensions
[0].c_str());
741 EXPECT_EQ(0U, controller
->link_click_count());
742 EXPECT_EQ(0U, controller
->dismiss_click_count());
743 EXPECT_EQ(0U, controller
->action_click_count());
745 // Simulate showing the bubble and dismissing it.
746 FakeExtensionMessageBubble bubble
;
747 bubble
.set_action_on_show(
748 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON
);
749 EXPECT_TRUE(controller
->ShouldShow(kId2
));
750 bubble
.set_controller(controller
.get());
751 controller
->Show(&bubble
);
752 EXPECT_EQ(0U, controller
->link_click_count());
753 EXPECT_EQ(0U, controller
->action_click_count());
754 EXPECT_EQ(1U, controller
->dismiss_click_count());
755 // No extension should have become disabled.
756 ExtensionRegistry
* registry
= ExtensionRegistry::Get(profile());
757 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId1
) != NULL
);
758 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId2
) != NULL
);
759 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId3
) != NULL
);
760 // Only extension 2 should have been acknowledged.
761 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
762 EXPECT_TRUE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId2
));
763 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId3
));
764 // Clean up after ourselves.
765 controller
->delegate()->SetBubbleInfoBeenAcknowledged(kId2
, false);
767 // Simulate clicking the learn more link to dismiss it.
768 bubble
.set_action_on_show(
769 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK
);
770 controller
.reset(new TestNtpOverriddenBubbleController(browser()));
771 EXPECT_TRUE(controller
->ShouldShow(kId2
));
772 bubble
.set_controller(controller
.get());
773 controller
->Show(&bubble
);
774 EXPECT_EQ(1U, controller
->link_click_count());
775 EXPECT_EQ(0U, controller
->action_click_count());
776 EXPECT_EQ(0U, controller
->dismiss_click_count());
777 // No extension should have become disabled.
778 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId1
) != NULL
);
779 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId2
) != NULL
);
780 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId3
) != NULL
);
781 // Only extension 2 should have been acknowledged.
782 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
783 EXPECT_TRUE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId2
));
784 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId3
));
785 // Clean up after ourselves.
786 controller
->delegate()->SetBubbleInfoBeenAcknowledged(kId2
, false);
788 // Do it again, but now opt to disable the extension.
789 bubble
.set_action_on_show(
790 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_ACTION_BUTTON
);
791 controller
.reset(new TestNtpOverriddenBubbleController(browser()));
792 EXPECT_TRUE(controller
->ShouldShow(kId2
));
793 override_extensions
= controller
->GetExtensionList();
794 EXPECT_EQ(1U, override_extensions
.size());
795 bubble
.set_controller(controller
.get());
796 controller
->Show(&bubble
); // Simulate showing the bubble.
797 EXPECT_EQ(0U, controller
->link_click_count());
798 EXPECT_EQ(1U, controller
->action_click_count());
799 EXPECT_EQ(0U, controller
->dismiss_click_count());
800 // Only extension 2 should have become disabled.
801 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId1
) != NULL
);
802 EXPECT_TRUE(registry
->disabled_extensions().GetByID(kId2
) != NULL
);
803 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId3
) != NULL
);
804 // No extension should have been acknowledged (it got disabled).
805 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
806 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId2
));
807 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId3
));
809 // Clean up after ourselves.
810 service_
->UninstallExtension(kId1
,
811 extensions::UNINSTALL_REASON_FOR_TESTING
,
812 base::Bind(&base::DoNothing
),
814 service_
->UninstallExtension(kId2
,
815 extensions::UNINSTALL_REASON_FOR_TESTING
,
816 base::Bind(&base::DoNothing
),
818 service_
->UninstallExtension(kId3
,
819 extensions::UNINSTALL_REASON_FOR_TESTING
,
820 base::Bind(&base::DoNothing
),
824 void SetInstallTime(const std::string
& extension_id
,
825 const base::Time
& time
,
826 ExtensionPrefs
* prefs
) {
827 std::string time_str
= base::Int64ToString(time
.ToInternalValue());
828 prefs
->UpdateExtensionPref(extension_id
,
830 new base::StringValue(time_str
));
833 // The feature this is meant to test is only implemented on Windows.
835 // http://crbug.com/397426
836 #define MAYBE_ProxyOverriddenControllerTest DISABLED_ProxyOverriddenControllerTest
838 #define MAYBE_ProxyOverriddenControllerTest DISABLED_ProxyOverriddenControllerTest
841 TEST_F(ExtensionMessageBubbleTest
, MAYBE_ProxyOverriddenControllerTest
) {
843 ExtensionPrefs
* prefs
= ExtensionPrefs::Get(profile());
844 // Load two extensions overriding proxy and one overriding something
845 // unrelated (to check for interference). Extension 2 should still win
846 // on the proxy setting.
847 ASSERT_TRUE(LoadExtensionOverridingProxy("1", kId1
, Manifest::UNPACKED
));
848 ASSERT_TRUE(LoadExtensionOverridingProxy("2", kId2
, Manifest::UNPACKED
));
849 ASSERT_TRUE(LoadExtensionOverridingStart("3", kId3
, Manifest::UNPACKED
));
851 // The bubble will not show if the extension was installed in the last 7 days
852 // so we artificially set the install time to simulate an old install during
854 base::Time old_enough
= base::Time::Now() - base::TimeDelta::FromDays(8);
855 SetInstallTime(kId1
, old_enough
, prefs
);
856 SetInstallTime(kId2
, base::Time::Now(), prefs
);
857 SetInstallTime(kId3
, old_enough
, prefs
);
859 scoped_ptr
<TestProxyOverriddenBubbleController
> controller(
860 new TestProxyOverriddenBubbleController(browser()));
862 // The second extension is too new to warn about.
863 EXPECT_FALSE(controller
->ShouldShow(kId1
));
864 EXPECT_FALSE(controller
->ShouldShow(kId2
));
865 // Lets make it old enough.
866 SetInstallTime(kId2
, old_enough
, prefs
);
868 // The list will contain one enabled unpacked extension (ext 2).
869 EXPECT_TRUE(controller
->ShouldShow(kId2
));
870 EXPECT_FALSE(controller
->ShouldShow(kId3
));
871 std::vector
<base::string16
> override_extensions
=
872 controller
->GetExtensionList();
873 ASSERT_EQ(1U, override_extensions
.size());
874 EXPECT_EQ(base::ASCIIToUTF16("Extension 2"), override_extensions
[0]);
875 EXPECT_EQ(0U, controller
->link_click_count());
876 EXPECT_EQ(0U, controller
->dismiss_click_count());
877 EXPECT_EQ(0U, controller
->action_click_count());
879 // Simulate showing the bubble and dismissing it.
880 FakeExtensionMessageBubble bubble
;
881 bubble
.set_action_on_show(
882 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON
);
883 bubble
.set_controller(controller
.get());
884 controller
->Show(&bubble
);
885 EXPECT_EQ(0U, controller
->link_click_count());
886 EXPECT_EQ(0U, controller
->action_click_count());
887 EXPECT_EQ(1U, controller
->dismiss_click_count());
888 // No extension should have become disabled.
889 ExtensionRegistry
* registry
= ExtensionRegistry::Get(profile());
890 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId1
) != NULL
);
891 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId2
) != NULL
);
892 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId3
) != NULL
);
893 // Only extension 2 should have been acknowledged.
894 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
895 EXPECT_TRUE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId2
));
896 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId3
));
897 // Clean up after ourselves.
898 controller
->delegate()->SetBubbleInfoBeenAcknowledged(kId2
, false);
900 // Simulate clicking the learn more link to dismiss it.
901 bubble
.set_action_on_show(
902 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK
);
903 controller
.reset(new TestProxyOverriddenBubbleController(browser()));
904 EXPECT_TRUE(controller
->ShouldShow(kId2
));
905 bubble
.set_controller(controller
.get());
906 controller
->Show(&bubble
);
907 EXPECT_EQ(1U, controller
->link_click_count());
908 EXPECT_EQ(0U, controller
->action_click_count());
909 EXPECT_EQ(0U, controller
->dismiss_click_count());
910 // No extension should have become disabled.
911 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId1
) != NULL
);
912 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId2
) != NULL
);
913 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId3
) != NULL
);
914 // Only extension 2 should have been acknowledged.
915 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
916 EXPECT_TRUE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId2
));
917 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId3
));
918 // Clean up after ourselves.
919 controller
->delegate()->SetBubbleInfoBeenAcknowledged(kId2
, false);
921 // Do it again, but now opt to disable the extension.
922 bubble
.set_action_on_show(
923 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_ACTION_BUTTON
);
924 controller
.reset(new TestProxyOverriddenBubbleController(browser()));
925 EXPECT_TRUE(controller
->ShouldShow(kId2
));
926 override_extensions
= controller
->GetExtensionList();
927 EXPECT_EQ(1U, override_extensions
.size());
928 bubble
.set_controller(controller
.get());
929 controller
->Show(&bubble
); // Simulate showing the bubble.
930 EXPECT_EQ(0U, controller
->link_click_count());
931 EXPECT_EQ(1U, controller
->action_click_count());
932 EXPECT_EQ(0U, controller
->dismiss_click_count());
933 // Only extension 2 should have become disabled.
934 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId1
) != NULL
);
935 EXPECT_TRUE(registry
->disabled_extensions().GetByID(kId2
) != NULL
);
936 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId3
) != NULL
);
938 // No extension should have been acknowledged (it got disabled).
939 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
940 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId2
));
941 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId3
));
943 // Clean up after ourselves.
944 service_
->UninstallExtension(kId1
,
945 extensions::UNINSTALL_REASON_FOR_TESTING
,
946 base::Bind(&base::DoNothing
),
948 service_
->UninstallExtension(kId2
,
949 extensions::UNINSTALL_REASON_FOR_TESTING
,
950 base::Bind(&base::DoNothing
),
952 service_
->UninstallExtension(kId3
,
953 extensions::UNINSTALL_REASON_FOR_TESTING
,
954 base::Bind(&base::DoNothing
),
958 } // namespace extensions