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/common/pref_names.h"
20 #include "chrome/test/base/browser_with_test_window_test.h"
21 #include "chrome/test/base/testing_profile.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
,
372 kExtensionPrefsScopeRegular
,
373 new base::StringValue(id
));
375 if (ExtensionRegistry::Get(profile())->enabled_extensions().GetByID(id
))
376 return testing::AssertionSuccess();
377 return testing::AssertionFailure() << "Could not install extension: " << id
;
381 // The two lines of magical incantation required to get the extension
382 // service to work inside a unit test and access the extension prefs.
383 static_cast<TestExtensionSystem
*>(ExtensionSystem::Get(profile()))
384 ->CreateExtensionService(base::CommandLine::ForCurrentProcess(),
385 base::FilePath(), false);
386 service_
= ExtensionSystem::Get(profile())->extension_service();
390 ~ExtensionMessageBubbleTest() override
{}
392 void SetUp() override
{
393 BrowserWithTestWindowTest::SetUp();
394 command_line_
.reset(new base::CommandLine(base::CommandLine::NO_PROGRAM
));
395 ExtensionMessageBubbleController::set_should_ignore_learn_more_for_testing(
399 void TearDown() override
{
400 ExtensionMessageBubbleController::set_should_ignore_learn_more_for_testing(
402 BrowserWithTestWindowTest::TearDown();
406 scoped_refptr
<Extension
> CreateExtension(
407 Manifest::Location location
,
408 const std::string
& data
,
409 const std::string
& id
) {
410 scoped_ptr
<base::DictionaryValue
> parsed_manifest(
411 api_test_utils::ParseDictionary(data
));
412 return api_test_utils::CreateExtension(location
, parsed_manifest
.get(), id
);
415 ExtensionService
* service_
;
418 scoped_ptr
<base::CommandLine
> command_line_
;
420 DISALLOW_COPY_AND_ASSIGN(ExtensionMessageBubbleTest
);
423 // The feature this is meant to test is only enacted on Windows, but it should
424 // pass on all platforms.
425 TEST_F(ExtensionMessageBubbleTest
, WipeoutControllerTest
) {
427 // Add three extensions, and control two of them in this test (extension 1
429 ASSERT_TRUE(LoadExtensionWithAction("1", kId1
, Manifest::COMMAND_LINE
));
430 ASSERT_TRUE(LoadGenericExtension("2", kId2
, Manifest::UNPACKED
));
431 ASSERT_TRUE(LoadGenericExtension("3", kId3
, Manifest::EXTERNAL_POLICY
));
433 scoped_ptr
<TestSuspiciousExtensionBubbleController
> controller(
434 new TestSuspiciousExtensionBubbleController(browser()));
435 FakeExtensionMessageBubble bubble
;
436 bubble
.set_action_on_show(
437 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON
);
439 // Validate that we don't have a suppress value for the extensions.
440 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
441 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
443 EXPECT_FALSE(controller
->ShouldShow());
444 std::vector
<base::string16
> suspicious_extensions
=
445 controller
->GetExtensionList();
446 EXPECT_EQ(0U, suspicious_extensions
.size());
447 EXPECT_EQ(0U, controller
->link_click_count());
448 EXPECT_EQ(0U, controller
->dismiss_click_count());
450 // Now disable an extension, specifying the wipeout flag.
451 service_
->DisableExtension(kId1
, Extension::DISABLE_NOT_VERIFIED
);
453 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
454 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId2
));
455 controller
.reset(new TestSuspiciousExtensionBubbleController(
457 SuspiciousExtensionBubbleController::ClearProfileListForTesting();
458 EXPECT_TRUE(controller
->ShouldShow());
459 suspicious_extensions
= controller
->GetExtensionList();
460 ASSERT_EQ(1U, suspicious_extensions
.size());
461 EXPECT_TRUE(base::ASCIIToUTF16("Extension 1") == suspicious_extensions
[0]);
462 bubble
.set_controller(controller
.get());
463 controller
->Show(&bubble
); // Simulate showing the bubble.
464 EXPECT_EQ(0U, controller
->link_click_count());
465 EXPECT_EQ(1U, controller
->dismiss_click_count());
466 // Now the acknowledge flag should be set only for the first extension.
467 EXPECT_TRUE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
468 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId2
));
470 controller
->delegate()->SetBubbleInfoBeenAcknowledged(kId1
, false);
471 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
473 // Now disable the other extension and exercise the link click code path.
474 service_
->DisableExtension(kId2
, Extension::DISABLE_NOT_VERIFIED
);
476 bubble
.set_action_on_show(
477 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK
);
478 controller
.reset(new TestSuspiciousExtensionBubbleController(
480 SuspiciousExtensionBubbleController::ClearProfileListForTesting();
481 EXPECT_TRUE(controller
->ShouldShow());
482 suspicious_extensions
= controller
->GetExtensionList();
483 ASSERT_EQ(2U, suspicious_extensions
.size());
484 EXPECT_TRUE(base::ASCIIToUTF16("Extension 1") == suspicious_extensions
[1]);
485 EXPECT_TRUE(base::ASCIIToUTF16("Extension 2") == suspicious_extensions
[0]);
486 bubble
.set_controller(controller
.get());
487 controller
->Show(&bubble
); // Simulate showing the bubble.
488 EXPECT_EQ(1U, controller
->link_click_count());
489 EXPECT_EQ(0U, controller
->dismiss_click_count());
490 EXPECT_TRUE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
493 // The feature this is meant to test is only enacted on Windows, but it should
494 // pass on all platforms.
495 TEST_F(ExtensionMessageBubbleTest
, DevModeControllerTest
) {
496 FeatureSwitch::ScopedOverride
force_dev_mode_highlighting(
497 FeatureSwitch::force_dev_mode_highlighting(), true);
499 // Add three extensions, and control two of them in this test (extension 1
500 // and 2). Extension 1 is a regular extension, Extension 2 is UNPACKED so it
501 // counts as a DevMode extension.
502 ASSERT_TRUE(LoadExtensionWithAction("1", kId1
, Manifest::COMMAND_LINE
));
503 ASSERT_TRUE(LoadGenericExtension("2", kId2
, Manifest::UNPACKED
));
504 ASSERT_TRUE(LoadGenericExtension("3", kId3
, Manifest::EXTERNAL_POLICY
));
506 scoped_ptr
<TestDevModeBubbleController
> controller(
507 new TestDevModeBubbleController(browser()));
509 // The list will contain one enabled unpacked extension.
510 EXPECT_TRUE(controller
->ShouldShow());
511 std::vector
<base::string16
> dev_mode_extensions
=
512 controller
->GetExtensionList();
513 ASSERT_EQ(2U, dev_mode_extensions
.size());
514 EXPECT_TRUE(base::ASCIIToUTF16("Extension 2") == dev_mode_extensions
[0]);
515 EXPECT_TRUE(base::ASCIIToUTF16("Extension 1") == dev_mode_extensions
[1]);
516 EXPECT_EQ(0U, controller
->link_click_count());
517 EXPECT_EQ(0U, controller
->dismiss_click_count());
518 EXPECT_EQ(0U, controller
->action_click_count());
520 // Simulate showing the bubble.
521 FakeExtensionMessageBubble bubble
;
522 bubble
.set_action_on_show(
523 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON
);
524 bubble
.set_controller(controller
.get());
525 controller
->Show(&bubble
);
526 EXPECT_EQ(0U, controller
->link_click_count());
527 EXPECT_EQ(0U, controller
->action_click_count());
528 EXPECT_EQ(1U, controller
->dismiss_click_count());
529 ExtensionRegistry
* registry
= ExtensionRegistry::Get(profile());
530 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId1
) != NULL
);
531 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId2
) != NULL
);
533 // Do it again, but now press different button (Disable).
534 bubble
.set_action_on_show(
535 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_ACTION_BUTTON
);
536 controller
.reset(new TestDevModeBubbleController(
538 DevModeBubbleController::ClearProfileListForTesting();
539 EXPECT_TRUE(controller
->ShouldShow());
540 dev_mode_extensions
= controller
->GetExtensionList();
541 EXPECT_EQ(2U, dev_mode_extensions
.size());
542 bubble
.set_controller(controller
.get());
543 controller
->Show(&bubble
); // Simulate showing the bubble.
544 EXPECT_EQ(0U, controller
->link_click_count());
545 EXPECT_EQ(1U, controller
->action_click_count());
546 EXPECT_EQ(0U, controller
->dismiss_click_count());
547 EXPECT_TRUE(registry
->disabled_extensions().GetByID(kId1
) != NULL
);
548 EXPECT_TRUE(registry
->disabled_extensions().GetByID(kId2
) != NULL
);
550 // Re-enable the extensions (disabled by the action button above).
551 service_
->EnableExtension(kId1
);
552 service_
->EnableExtension(kId2
);
554 // Show the dialog a third time, but now press the learn more link.
555 bubble
.set_action_on_show(
556 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK
);
557 controller
.reset(new TestDevModeBubbleController(
559 DevModeBubbleController::ClearProfileListForTesting();
560 EXPECT_TRUE(controller
->ShouldShow());
561 dev_mode_extensions
= controller
->GetExtensionList();
562 EXPECT_EQ(2U, dev_mode_extensions
.size());
563 bubble
.set_controller(controller
.get());
564 controller
->Show(&bubble
); // Simulate showing the bubble.
565 EXPECT_EQ(1U, controller
->link_click_count());
566 EXPECT_EQ(0U, controller
->action_click_count());
567 EXPECT_EQ(0U, controller
->dismiss_click_count());
568 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId1
) != NULL
);
569 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId2
) != NULL
);
571 // Now disable the unpacked extension.
572 service_
->DisableExtension(kId1
, Extension::DISABLE_USER_ACTION
);
573 service_
->DisableExtension(kId2
, Extension::DISABLE_USER_ACTION
);
575 controller
.reset(new TestDevModeBubbleController(
577 DevModeBubbleController::ClearProfileListForTesting();
578 EXPECT_FALSE(controller
->ShouldShow());
579 dev_mode_extensions
= controller
->GetExtensionList();
580 EXPECT_EQ(0U, dev_mode_extensions
.size());
583 // The feature this is meant to test is only implemented on Windows.
585 #define MAYBE_SettingsApiControllerTest SettingsApiControllerTest
587 #define MAYBE_SettingsApiControllerTest DISABLED_SettingsApiControllerTest
590 TEST_F(ExtensionMessageBubbleTest
, MAYBE_SettingsApiControllerTest
) {
593 for (int i
= 0; i
< 3; ++i
) {
594 switch (static_cast<SettingsApiOverrideType
>(i
)) {
595 case BUBBLE_TYPE_HOME_PAGE
:
596 // Load two extensions overriding home page and one overriding something
597 // unrelated (to check for interference). Extension 2 should still win
598 // on the home page setting.
599 ASSERT_TRUE(LoadExtensionOverridingHome("1", kId1
, Manifest::UNPACKED
));
600 ASSERT_TRUE(LoadExtensionOverridingHome("2", kId2
, Manifest::UNPACKED
));
602 LoadExtensionOverridingStart("3", kId3
, Manifest::UNPACKED
));
604 case BUBBLE_TYPE_SEARCH_ENGINE
:
605 // We deliberately skip testing the search engine since it relies on
606 // TemplateURLServiceFactory that isn't available while unit testing.
607 // This test is only simulating the bubble interaction with the user and
608 // that is more or less the same for the search engine as it is for the
611 case BUBBLE_TYPE_STARTUP_PAGES
:
612 // Load two extensions overriding start page and one overriding
613 // something unrelated (to check for interference). Extension 2 should
614 // still win on the startup page setting.
616 LoadExtensionOverridingStart("1", kId1
, Manifest::UNPACKED
));
618 LoadExtensionOverridingStart("2", kId2
, Manifest::UNPACKED
));
619 ASSERT_TRUE(LoadExtensionOverridingHome("3", kId3
, Manifest::UNPACKED
));
626 scoped_ptr
<TestSettingsApiBubbleController
> controller(
627 new TestSettingsApiBubbleController(
628 browser(), static_cast<SettingsApiOverrideType
>(i
)));
630 // The list will contain one enabled unpacked extension (ext 2).
631 EXPECT_TRUE(controller
->ShouldShow());
632 std::vector
<base::string16
> override_extensions
=
633 controller
->GetExtensionList();
634 ASSERT_EQ(1U, override_extensions
.size());
635 EXPECT_TRUE(base::ASCIIToUTF16("Extension 2") ==
636 override_extensions
[0].c_str());
637 EXPECT_EQ(0U, controller
->link_click_count());
638 EXPECT_EQ(0U, controller
->dismiss_click_count());
639 EXPECT_EQ(0U, controller
->action_click_count());
641 // Simulate showing the bubble and dismissing it.
642 FakeExtensionMessageBubble bubble
;
643 bubble
.set_action_on_show(
644 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON
);
645 bubble
.set_controller(controller
.get());
646 controller
->Show(&bubble
);
647 EXPECT_EQ(0U, controller
->link_click_count());
648 EXPECT_EQ(0U, controller
->action_click_count());
649 EXPECT_EQ(1U, controller
->dismiss_click_count());
650 // No extension should have become disabled.
651 ExtensionRegistry
* registry
= ExtensionRegistry::Get(profile());
652 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId1
) != NULL
);
653 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId2
) != NULL
);
654 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId3
) != NULL
);
655 // Only extension 2 should have been acknowledged.
656 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
657 EXPECT_TRUE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId2
));
658 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId3
));
659 // Clean up after ourselves.
660 controller
->delegate()->SetBubbleInfoBeenAcknowledged(kId2
, false);
662 // Simulate clicking the learn more link to dismiss it.
663 bubble
.set_action_on_show(
664 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK
);
665 controller
.reset(new TestSettingsApiBubbleController(
666 browser(), static_cast<SettingsApiOverrideType
>(i
)));
667 bubble
.set_controller(controller
.get());
668 controller
->Show(&bubble
);
669 EXPECT_EQ(1U, controller
->link_click_count());
670 EXPECT_EQ(0U, controller
->action_click_count());
671 EXPECT_EQ(0U, controller
->dismiss_click_count());
672 // No extension should have become disabled.
673 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId1
) != NULL
);
674 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId2
) != NULL
);
675 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId3
) != NULL
);
676 // Only extension 2 should have been acknowledged.
677 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
678 EXPECT_TRUE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId2
));
679 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId3
));
680 // Clean up after ourselves.
681 controller
->delegate()->SetBubbleInfoBeenAcknowledged(kId2
, false);
683 // Do it again, but now opt to disable the extension.
684 bubble
.set_action_on_show(
685 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_ACTION_BUTTON
);
686 controller
.reset(new TestSettingsApiBubbleController(
687 browser(), static_cast<SettingsApiOverrideType
>(i
)));
688 EXPECT_TRUE(controller
->ShouldShow());
689 override_extensions
= controller
->GetExtensionList();
690 EXPECT_EQ(1U, override_extensions
.size());
691 bubble
.set_controller(controller
.get());
692 controller
->Show(&bubble
); // Simulate showing the bubble.
693 EXPECT_EQ(0U, controller
->link_click_count());
694 EXPECT_EQ(1U, controller
->action_click_count());
695 EXPECT_EQ(0U, controller
->dismiss_click_count());
696 // Only extension 2 should have become disabled.
697 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId1
) != NULL
);
698 EXPECT_TRUE(registry
->disabled_extensions().GetByID(kId2
) != NULL
);
699 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId3
) != NULL
);
700 // No extension should have been acknowledged (it got disabled).
701 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
702 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId2
));
703 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId3
));
705 // Clean up after ourselves.
706 service_
->UninstallExtension(kId1
,
707 extensions::UNINSTALL_REASON_FOR_TESTING
,
708 base::Bind(&base::DoNothing
),
710 service_
->UninstallExtension(kId2
,
711 extensions::UNINSTALL_REASON_FOR_TESTING
,
712 base::Bind(&base::DoNothing
),
714 service_
->UninstallExtension(kId3
,
715 extensions::UNINSTALL_REASON_FOR_TESTING
,
716 base::Bind(&base::DoNothing
),
721 // The feature this is meant to test is only enacted on Windows, but it should
722 // pass on all platforms.
723 TEST_F(ExtensionMessageBubbleTest
, NtpOverriddenControllerTest
) {
725 // Load two extensions overriding new tab page and one overriding something
726 // unrelated (to check for interference). Extension 2 should still win
727 // on the new tab page setting.
728 ASSERT_TRUE(LoadExtensionOverridingNtp("1", kId1
, Manifest::UNPACKED
));
729 ASSERT_TRUE(LoadExtensionOverridingNtp("2", kId2
, Manifest::UNPACKED
));
730 ASSERT_TRUE(LoadExtensionOverridingStart("3", kId3
, Manifest::UNPACKED
));
732 scoped_ptr
<TestNtpOverriddenBubbleController
> controller(
733 new TestNtpOverriddenBubbleController(browser()));
735 // The list will contain one enabled unpacked extension (ext 2).
736 EXPECT_TRUE(controller
->ShouldShow(kId2
));
737 std::vector
<base::string16
> override_extensions
=
738 controller
->GetExtensionList();
739 ASSERT_EQ(1U, override_extensions
.size());
740 EXPECT_TRUE(base::ASCIIToUTF16("Extension 2") ==
741 override_extensions
[0].c_str());
742 EXPECT_EQ(0U, controller
->link_click_count());
743 EXPECT_EQ(0U, controller
->dismiss_click_count());
744 EXPECT_EQ(0U, controller
->action_click_count());
746 // Simulate showing the bubble and dismissing it.
747 FakeExtensionMessageBubble bubble
;
748 bubble
.set_action_on_show(
749 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON
);
750 EXPECT_TRUE(controller
->ShouldShow(kId2
));
751 bubble
.set_controller(controller
.get());
752 controller
->Show(&bubble
);
753 EXPECT_EQ(0U, controller
->link_click_count());
754 EXPECT_EQ(0U, controller
->action_click_count());
755 EXPECT_EQ(1U, controller
->dismiss_click_count());
756 // No extension should have become disabled.
757 ExtensionRegistry
* registry
= ExtensionRegistry::Get(profile());
758 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId1
) != NULL
);
759 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId2
) != NULL
);
760 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId3
) != NULL
);
761 // Only extension 2 should have been acknowledged.
762 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
763 EXPECT_TRUE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId2
));
764 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId3
));
765 // Clean up after ourselves.
766 controller
->delegate()->SetBubbleInfoBeenAcknowledged(kId2
, false);
768 // Simulate clicking the learn more link to dismiss it.
769 bubble
.set_action_on_show(
770 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK
);
771 controller
.reset(new TestNtpOverriddenBubbleController(browser()));
772 EXPECT_TRUE(controller
->ShouldShow(kId2
));
773 bubble
.set_controller(controller
.get());
774 controller
->Show(&bubble
);
775 EXPECT_EQ(1U, controller
->link_click_count());
776 EXPECT_EQ(0U, controller
->action_click_count());
777 EXPECT_EQ(0U, controller
->dismiss_click_count());
778 // No extension should have become disabled.
779 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId1
) != NULL
);
780 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId2
) != NULL
);
781 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId3
) != NULL
);
782 // Only extension 2 should have been acknowledged.
783 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
784 EXPECT_TRUE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId2
));
785 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId3
));
786 // Clean up after ourselves.
787 controller
->delegate()->SetBubbleInfoBeenAcknowledged(kId2
, false);
789 // Do it again, but now opt to disable the extension.
790 bubble
.set_action_on_show(
791 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_ACTION_BUTTON
);
792 controller
.reset(new TestNtpOverriddenBubbleController(browser()));
793 EXPECT_TRUE(controller
->ShouldShow(kId2
));
794 override_extensions
= controller
->GetExtensionList();
795 EXPECT_EQ(1U, override_extensions
.size());
796 bubble
.set_controller(controller
.get());
797 controller
->Show(&bubble
); // Simulate showing the bubble.
798 EXPECT_EQ(0U, controller
->link_click_count());
799 EXPECT_EQ(1U, controller
->action_click_count());
800 EXPECT_EQ(0U, controller
->dismiss_click_count());
801 // Only extension 2 should have become disabled.
802 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId1
) != NULL
);
803 EXPECT_TRUE(registry
->disabled_extensions().GetByID(kId2
) != NULL
);
804 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId3
) != NULL
);
805 // No extension should have been acknowledged (it got disabled).
806 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
807 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId2
));
808 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId3
));
810 // Clean up after ourselves.
811 service_
->UninstallExtension(kId1
,
812 extensions::UNINSTALL_REASON_FOR_TESTING
,
813 base::Bind(&base::DoNothing
),
815 service_
->UninstallExtension(kId2
,
816 extensions::UNINSTALL_REASON_FOR_TESTING
,
817 base::Bind(&base::DoNothing
),
819 service_
->UninstallExtension(kId3
,
820 extensions::UNINSTALL_REASON_FOR_TESTING
,
821 base::Bind(&base::DoNothing
),
825 void SetInstallTime(const std::string
& extension_id
,
826 const base::Time
& time
,
827 ExtensionPrefs
* prefs
) {
828 std::string time_str
= base::Int64ToString(time
.ToInternalValue());
829 prefs
->UpdateExtensionPref(extension_id
,
831 new base::StringValue(time_str
));
834 // The feature this is meant to test is only implemented on Windows.
836 // http://crbug.com/397426
837 #define MAYBE_ProxyOverriddenControllerTest DISABLED_ProxyOverriddenControllerTest
839 #define MAYBE_ProxyOverriddenControllerTest DISABLED_ProxyOverriddenControllerTest
842 TEST_F(ExtensionMessageBubbleTest
, MAYBE_ProxyOverriddenControllerTest
) {
844 ExtensionPrefs
* prefs
= ExtensionPrefs::Get(profile());
845 // Load two extensions overriding proxy and one overriding something
846 // unrelated (to check for interference). Extension 2 should still win
847 // on the proxy setting.
848 ASSERT_TRUE(LoadExtensionOverridingProxy("1", kId1
, Manifest::UNPACKED
));
849 ASSERT_TRUE(LoadExtensionOverridingProxy("2", kId2
, Manifest::UNPACKED
));
850 ASSERT_TRUE(LoadExtensionOverridingStart("3", kId3
, Manifest::UNPACKED
));
852 // The bubble will not show if the extension was installed in the last 7 days
853 // so we artificially set the install time to simulate an old install during
855 base::Time old_enough
= base::Time::Now() - base::TimeDelta::FromDays(8);
856 SetInstallTime(kId1
, old_enough
, prefs
);
857 SetInstallTime(kId2
, base::Time::Now(), prefs
);
858 SetInstallTime(kId3
, old_enough
, prefs
);
860 scoped_ptr
<TestProxyOverriddenBubbleController
> controller(
861 new TestProxyOverriddenBubbleController(browser()));
863 // The second extension is too new to warn about.
864 EXPECT_FALSE(controller
->ShouldShow(kId1
));
865 EXPECT_FALSE(controller
->ShouldShow(kId2
));
866 // Lets make it old enough.
867 SetInstallTime(kId2
, old_enough
, prefs
);
869 // The list will contain one enabled unpacked extension (ext 2).
870 EXPECT_TRUE(controller
->ShouldShow(kId2
));
871 EXPECT_FALSE(controller
->ShouldShow(kId3
));
872 std::vector
<base::string16
> override_extensions
=
873 controller
->GetExtensionList();
874 ASSERT_EQ(1U, override_extensions
.size());
875 EXPECT_EQ(base::ASCIIToUTF16("Extension 2"), override_extensions
[0]);
876 EXPECT_EQ(0U, controller
->link_click_count());
877 EXPECT_EQ(0U, controller
->dismiss_click_count());
878 EXPECT_EQ(0U, controller
->action_click_count());
880 // Simulate showing the bubble and dismissing it.
881 FakeExtensionMessageBubble bubble
;
882 bubble
.set_action_on_show(
883 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON
);
884 bubble
.set_controller(controller
.get());
885 controller
->Show(&bubble
);
886 EXPECT_EQ(0U, controller
->link_click_count());
887 EXPECT_EQ(0U, controller
->action_click_count());
888 EXPECT_EQ(1U, controller
->dismiss_click_count());
889 // No extension should have become disabled.
890 ExtensionRegistry
* registry
= ExtensionRegistry::Get(profile());
891 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId1
) != NULL
);
892 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId2
) != NULL
);
893 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId3
) != NULL
);
894 // Only extension 2 should have been acknowledged.
895 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
896 EXPECT_TRUE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId2
));
897 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId3
));
898 // Clean up after ourselves.
899 controller
->delegate()->SetBubbleInfoBeenAcknowledged(kId2
, false);
901 // Simulate clicking the learn more link to dismiss it.
902 bubble
.set_action_on_show(
903 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK
);
904 controller
.reset(new TestProxyOverriddenBubbleController(browser()));
905 EXPECT_TRUE(controller
->ShouldShow(kId2
));
906 bubble
.set_controller(controller
.get());
907 controller
->Show(&bubble
);
908 EXPECT_EQ(1U, controller
->link_click_count());
909 EXPECT_EQ(0U, controller
->action_click_count());
910 EXPECT_EQ(0U, controller
->dismiss_click_count());
911 // No extension should have become disabled.
912 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId1
) != NULL
);
913 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId2
) != NULL
);
914 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId3
) != NULL
);
915 // Only extension 2 should have been acknowledged.
916 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
917 EXPECT_TRUE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId2
));
918 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId3
));
919 // Clean up after ourselves.
920 controller
->delegate()->SetBubbleInfoBeenAcknowledged(kId2
, false);
922 // Do it again, but now opt to disable the extension.
923 bubble
.set_action_on_show(
924 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_ACTION_BUTTON
);
925 controller
.reset(new TestProxyOverriddenBubbleController(browser()));
926 EXPECT_TRUE(controller
->ShouldShow(kId2
));
927 override_extensions
= controller
->GetExtensionList();
928 EXPECT_EQ(1U, override_extensions
.size());
929 bubble
.set_controller(controller
.get());
930 controller
->Show(&bubble
); // Simulate showing the bubble.
931 EXPECT_EQ(0U, controller
->link_click_count());
932 EXPECT_EQ(1U, controller
->action_click_count());
933 EXPECT_EQ(0U, controller
->dismiss_click_count());
934 // Only extension 2 should have become disabled.
935 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId1
) != NULL
);
936 EXPECT_TRUE(registry
->disabled_extensions().GetByID(kId2
) != NULL
);
937 EXPECT_TRUE(registry
->enabled_extensions().GetByID(kId3
) != NULL
);
939 // No extension should have been acknowledged (it got disabled).
940 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId1
));
941 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId2
));
942 EXPECT_FALSE(controller
->delegate()->HasBubbleInfoBeenAcknowledged(kId3
));
944 // Clean up after ourselves.
945 service_
->UninstallExtension(kId1
,
946 extensions::UNINSTALL_REASON_FOR_TESTING
,
947 base::Bind(&base::DoNothing
),
949 service_
->UninstallExtension(kId2
,
950 extensions::UNINSTALL_REASON_FOR_TESTING
,
951 base::Bind(&base::DoNothing
),
953 service_
->UninstallExtension(kId3
,
954 extensions::UNINSTALL_REASON_FOR_TESTING
,
955 base::Bind(&base::DoNothing
),
959 } // namespace extensions