Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / extensions / extension_message_bubble_controller_unittest.cc
blob4ec423fd16ea8f59ba5de61e4fdae4783fde0e0e
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"
36 namespace {
38 const char kId1[] = "iccfkkhkfiphcjdakkmcjmkfboccmndk";
39 const char kId2[] = "ajjhifimiemdpmophmkkkcijegphclbl";
40 const char kId3[] = "ioibbbfddncmmabjmpokikkeiofalaek";
42 } // namespace
44 namespace extensions {
46 class TestDelegate {
47 public:
48 TestDelegate()
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_;
69 protected:
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,
78 public TestDelegate {
79 public:
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 {
104 public:
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 {
128 public:
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 {
153 public:
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 {
178 public:
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 {
203 public:
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) {
213 action_ = 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();
228 private:
229 ExtensionBubbleAction action_;
230 ExtensionMessageBubbleController* controller_;
232 DISALLOW_COPY_AND_ASSIGN(FakeExtensionMessageBubble);
235 class ExtensionMessageBubbleTest : public BrowserWithTestWindowTest {
236 public:
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);
248 builder.SetID(id);
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);
269 builder.SetID(id);
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);
290 builder.SetID(id);
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(
309 "startup_pages",
310 ListBuilder().Append(
311 "http://www.google.com"))));
312 builder.SetLocation(location);
313 builder.SetID(id);
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);
335 builder.SetID(id);
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)
352 .Set("permissions",
353 ListBuilder().Append("proxy")));
355 builder.SetLocation(location);
356 builder.SetID(id);
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(
367 base::Time::Now(),
368 true, // is_enabled.
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;
379 void Init() {
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();
386 service_->Init();
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(
395 true);
398 void TearDown() override {
399 ExtensionMessageBubbleController::set_should_ignore_learn_more_for_testing(
400 false);
401 BrowserWithTestWindowTest::TearDown();
404 protected:
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_;
416 private:
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) {
425 Init();
426 // Add three extensions, and control two of them in this test (extension 1
427 // and 2).
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(
455 browser()));
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));
468 // Clear the flag.
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(
478 browser()));
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);
497 Init();
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(
536 browser()));
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(
557 browser()));
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(
575 browser()));
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.
583 #if defined(OS_WIN)
584 #define MAYBE_SettingsApiControllerTest SettingsApiControllerTest
585 #else
586 #define MAYBE_SettingsApiControllerTest DISABLED_SettingsApiControllerTest
587 #endif
589 TEST_F(ExtensionMessageBubbleTest, MAYBE_SettingsApiControllerTest) {
590 Init();
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));
600 ASSERT_TRUE(
601 LoadExtensionOverridingStart("3", kId3, Manifest::UNPACKED));
602 break;
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
608 // others.
609 continue;
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.
614 ASSERT_TRUE(
615 LoadExtensionOverridingStart("1", kId1, Manifest::UNPACKED));
616 ASSERT_TRUE(
617 LoadExtensionOverridingStart("2", kId2, Manifest::UNPACKED));
618 ASSERT_TRUE(LoadExtensionOverridingHome("3", kId3, Manifest::UNPACKED));
619 break;
620 default:
621 NOTREACHED();
622 break;
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),
708 NULL);
709 service_->UninstallExtension(kId2,
710 extensions::UNINSTALL_REASON_FOR_TESTING,
711 base::Bind(&base::DoNothing),
712 NULL);
713 service_->UninstallExtension(kId3,
714 extensions::UNINSTALL_REASON_FOR_TESTING,
715 base::Bind(&base::DoNothing),
716 NULL);
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) {
723 Init();
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),
813 NULL);
814 service_->UninstallExtension(kId2,
815 extensions::UNINSTALL_REASON_FOR_TESTING,
816 base::Bind(&base::DoNothing),
817 NULL);
818 service_->UninstallExtension(kId3,
819 extensions::UNINSTALL_REASON_FOR_TESTING,
820 base::Bind(&base::DoNothing),
821 NULL);
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,
829 "install_time",
830 new base::StringValue(time_str));
833 // The feature this is meant to test is only implemented on Windows.
834 #if defined(OS_WIN)
835 // http://crbug.com/397426
836 #define MAYBE_ProxyOverriddenControllerTest DISABLED_ProxyOverriddenControllerTest
837 #else
838 #define MAYBE_ProxyOverriddenControllerTest DISABLED_ProxyOverriddenControllerTest
839 #endif
841 TEST_F(ExtensionMessageBubbleTest, MAYBE_ProxyOverriddenControllerTest) {
842 Init();
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
853 // testing.
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),
947 NULL);
948 service_->UninstallExtension(kId2,
949 extensions::UNINSTALL_REASON_FOR_TESTING,
950 base::Bind(&base::DoNothing),
951 NULL);
952 service_->UninstallExtension(kId3,
953 extensions::UNINSTALL_REASON_FOR_TESTING,
954 base::Bind(&base::DoNothing),
955 NULL);
958 } // namespace extensions