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. 4 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/chrome_version_info.h" 20 #include "chrome/common/pref_names.h" 21 #include "chrome/test/base/testing_profile.h" 22 #include "content/public/test/test_browser_thread_bundle.h" 23 #include "extensions/browser/extension_pref_value_map.h" 24 #include "extensions/browser/extension_pref_value_map_factory.h" 25 #include "extensions/browser/extension_prefs.h" 26 #include "extensions/browser/extension_registry.h" 27 #include "extensions/common/extension.h" 28 #include "extensions/common/extension_builder.h" 29 #include "extensions/common/feature_switch.h" 30 #include "extensions/common/value_builder.h" 31 32 namespace { 33 34 const char kId1[] = "iccfkkhkfiphcjdakkmcjmkfboccmndk"; 35 const char kId2[] = "ajjhifimiemdpmophmkkkcijegphclbl"; 36 const char kId3[] = "ioibbbfddncmmabjmpokikkeiofalaek"; 37 38 } // namespace 39 40 namespace extensions { 41 42 class TestDelegate { 43 public: 44 TestDelegate() 45 : action_button_callback_count_(0), 46 dismiss_button_callback_count_(0), 47 link_click_callback_count_(0) { 48 } 49 50 // Returns how often the dismiss button has been called. 51 size_t action_click_count() { 52 return action_button_callback_count_; 53 } 54 55 // Returns how often the dismiss button has been called. 56 size_t dismiss_click_count() { 57 return dismiss_button_callback_count_; 58 } 59 60 // Returns how often the link has been clicked. 61 size_t link_click_count() { 62 return link_click_callback_count_; 63 } 64 65 protected: 66 size_t action_button_callback_count_; 67 size_t dismiss_button_callback_count_; 68 size_t link_click_callback_count_; 69 }; 70 71 // A test class for the SuspiciousExtensionBubbleController. 72 class TestSuspiciousExtensionBubbleController 73 : public SuspiciousExtensionBubbleController, 74 public TestDelegate { 75 public: 76 explicit TestSuspiciousExtensionBubbleController(Profile* profile) 77 : SuspiciousExtensionBubbleController(profile) { 78 } 79 80 virtual void OnBubbleAction() OVERRIDE { 81 ++action_button_callback_count_; 82 SuspiciousExtensionBubbleController::OnBubbleAction(); 83 } 84 85 virtual void OnBubbleDismiss() OVERRIDE { 86 ++dismiss_button_callback_count_; 87 SuspiciousExtensionBubbleController::OnBubbleDismiss(); 88 } 89 90 virtual void OnLinkClicked() OVERRIDE { 91 ++link_click_callback_count_; 92 SuspiciousExtensionBubbleController::OnLinkClicked(); 93 } 94 }; 95 96 // A test class for the DevModeBubbleController. 97 class TestDevModeBubbleController 98 : public DevModeBubbleController, 99 public TestDelegate { 100 public: 101 explicit TestDevModeBubbleController(Profile* profile) 102 : DevModeBubbleController(profile) { 103 } 104 105 virtual void OnBubbleAction() OVERRIDE { 106 ++action_button_callback_count_; 107 DevModeBubbleController::OnBubbleAction(); 108 } 109 110 virtual void OnBubbleDismiss() OVERRIDE { 111 ++dismiss_button_callback_count_; 112 DevModeBubbleController::OnBubbleDismiss(); 113 } 114 115 virtual void OnLinkClicked() OVERRIDE { 116 ++link_click_callback_count_; 117 DevModeBubbleController::OnLinkClicked(); 118 } 119 }; 120 121 // A test class for the SettingsApiBubbleController. 122 class TestSettingsApiBubbleController : public SettingsApiBubbleController, 123 public TestDelegate { 124 public: 125 TestSettingsApiBubbleController(Profile* profile, 126 SettingsApiOverrideType type) 127 : SettingsApiBubbleController(profile, type) {} 128 129 virtual void OnBubbleAction() OVERRIDE { 130 ++action_button_callback_count_; 131 SettingsApiBubbleController::OnBubbleAction(); 132 } 133 134 virtual void OnBubbleDismiss() OVERRIDE { 135 ++dismiss_button_callback_count_; 136 SettingsApiBubbleController::OnBubbleDismiss(); 137 } 138 139 virtual void OnLinkClicked() OVERRIDE { 140 ++link_click_callback_count_; 141 SettingsApiBubbleController::OnLinkClicked(); 142 } 143 }; 144 145 // A test class for the NtpOverriddenBubbleController. 146 class TestNtpOverriddenBubbleController 147 : public NtpOverriddenBubbleController, 148 public TestDelegate { 149 public: 150 explicit TestNtpOverriddenBubbleController(Profile* profile) 151 : NtpOverriddenBubbleController(profile) { 152 } 153 154 virtual void OnBubbleAction() OVERRIDE { 155 ++action_button_callback_count_; 156 NtpOverriddenBubbleController::OnBubbleAction(); 157 } 158 159 virtual void OnBubbleDismiss() OVERRIDE { 160 ++dismiss_button_callback_count_; 161 NtpOverriddenBubbleController::OnBubbleDismiss(); 162 } 163 164 virtual void OnLinkClicked() OVERRIDE { 165 ++link_click_callback_count_; 166 NtpOverriddenBubbleController::OnLinkClicked(); 167 } 168 }; 169 170 // A test class for the ProxyOverriddenBubbleController. 171 class TestProxyOverriddenBubbleController 172 : public ProxyOverriddenBubbleController, 173 public TestDelegate { 174 public: 175 explicit TestProxyOverriddenBubbleController(Profile* profile) 176 : ProxyOverriddenBubbleController(profile) { 177 } 178 179 virtual void OnBubbleAction() OVERRIDE { 180 ++action_button_callback_count_; 181 ProxyOverriddenBubbleController::OnBubbleAction(); 182 } 183 184 virtual void OnBubbleDismiss() OVERRIDE { 185 ++dismiss_button_callback_count_; 186 ProxyOverriddenBubbleController::OnBubbleDismiss(); 187 } 188 189 virtual void OnLinkClicked() OVERRIDE { 190 ++link_click_callback_count_; 191 ProxyOverriddenBubbleController::OnLinkClicked(); 192 } 193 }; 194 195 // A fake bubble used for testing the controller. Takes an action that specifies 196 // what should happen when the bubble is "shown" (the bubble is actually not 197 // shown, the corresponding action is taken immediately). 198 class FakeExtensionMessageBubble : public ExtensionMessageBubble { 199 public: 200 enum ExtensionBubbleAction { 201 BUBBLE_ACTION_CLICK_ACTION_BUTTON = 0, 202 BUBBLE_ACTION_CLICK_DISMISS_BUTTON, 203 BUBBLE_ACTION_CLICK_LINK, 204 }; 205 206 FakeExtensionMessageBubble() {} 207 208 void set_action_on_show(ExtensionBubbleAction action) { 209 action_ = action; 210 } 211 212 virtual void Show() OVERRIDE { 213 if (action_ == BUBBLE_ACTION_CLICK_ACTION_BUTTON) 214 action_callback_.Run(); 215 else if (action_ == BUBBLE_ACTION_CLICK_DISMISS_BUTTON) 216 dismiss_callback_.Run(); 217 else if (action_ == BUBBLE_ACTION_CLICK_LINK) 218 link_callback_.Run(); 219 } 220 221 virtual void OnActionButtonClicked(const base::Closure& callback) OVERRIDE { 222 action_callback_ = callback; 223 } 224 225 virtual void OnDismissButtonClicked(const base::Closure& callback) OVERRIDE { 226 dismiss_callback_ = callback; 227 } 228 229 virtual void OnLinkClicked(const base::Closure& callback) OVERRIDE { 230 link_callback_ = callback; 231 } 232 233 private: 234 ExtensionBubbleAction action_; 235 236 base::Closure action_callback_; 237 base::Closure dismiss_callback_; 238 base::Closure link_callback_; 239 }; 240 241 class ExtensionMessageBubbleTest : public testing::Test { 242 public: 243 ExtensionMessageBubbleTest() {} 244 245 testing::AssertionResult LoadGenericExtension(const std::string& index, 246 const std::string& id, 247 Manifest::Location location) { 248 ExtensionBuilder builder; 249 builder.SetManifest(DictionaryBuilder() 250 .Set("name", std::string("Extension " + index)) 251 .Set("version", "1.0") 252 .Set("manifest_version", 2)); 253 builder.SetLocation(location); 254 builder.SetID(id); 255 service_->AddExtension(builder.Build().get()); 256 257 if (ExtensionRegistry::Get(profile())->enabled_extensions().GetByID(id)) 258 return testing::AssertionSuccess(); 259 return testing::AssertionFailure() << "Could not install extension: " << id; 260 } 261 262 testing::AssertionResult LoadExtensionWithAction( 263 const std::string& index, 264 const std::string& id, 265 Manifest::Location location) { 266 ExtensionBuilder builder; 267 builder.SetManifest(DictionaryBuilder() 268 .Set("name", std::string("Extension " + index)) 269 .Set("version", "1.0") 270 .Set("manifest_version", 2) 271 .Set("browser_action", 272 DictionaryBuilder().Set( 273 "default_title", "Default title"))); 274 builder.SetLocation(location); 275 builder.SetID(id); 276 service_->AddExtension(builder.Build().get()); 277 278 if (ExtensionRegistry::Get(profile())->enabled_extensions().GetByID(id)) 279 return testing::AssertionSuccess(); 280 return testing::AssertionFailure() << "Could not install extension: " << id; 281 } 282 283 testing::AssertionResult LoadExtensionOverridingHome( 284 const std::string& index, 285 const std::string& id, 286 Manifest::Location location) { 287 ExtensionBuilder builder; 288 builder.SetManifest(DictionaryBuilder() 289 .Set("name", std::string("Extension " + index)) 290 .Set("version", "1.0") 291 .Set("manifest_version", 2) 292 .Set("chrome_settings_overrides", 293 DictionaryBuilder().Set( 294 "homepage", "http://www.google.com"))); 295 builder.SetLocation(location); 296 builder.SetID(id); 297 service_->AddExtension(builder.Build().get()); 298 299 if (ExtensionRegistry::Get(profile())->enabled_extensions().GetByID(id)) 300 return testing::AssertionSuccess(); 301 return testing::AssertionFailure() << "Could not install extension: " << id; 302 } 303 304 testing::AssertionResult LoadExtensionOverridingStart( 305 const std::string& index, 306 const std::string& id, 307 Manifest::Location location) { 308 ExtensionBuilder builder; 309 builder.SetManifest(DictionaryBuilder() 310 .Set("name", std::string("Extension " + index)) 311 .Set("version", "1.0") 312 .Set("manifest_version", 2) 313 .Set("chrome_settings_overrides", 314 DictionaryBuilder().Set( 315 "startup_pages", 316 ListBuilder().Append( 317 "http://www.google.com")))); 318 builder.SetLocation(location); 319 builder.SetID(id); 320 service_->AddExtension(builder.Build().get()); 321 322 if (ExtensionRegistry::Get(profile())->enabled_extensions().GetByID(id)) 323 return testing::AssertionSuccess(); 324 return testing::AssertionFailure() << "Could not install extension: " << id; 325 } 326 327 testing::AssertionResult LoadExtensionOverridingNtp( 328 const std::string& index, 329 const std::string& id, 330 Manifest::Location location) { 331 ExtensionBuilder builder; 332 builder.SetManifest(DictionaryBuilder() 333 .Set("name", std::string("Extension " + index)) 334 .Set("version", "1.0") 335 .Set("manifest_version", 2) 336 .Set("chrome_url_overrides", 337 DictionaryBuilder().Set( 338 "newtab", "Default.html"))); 339 340 builder.SetLocation(location); 341 builder.SetID(id); 342 service_->AddExtension(builder.Build().get()); 343 344 if (ExtensionRegistry::Get(profile())->enabled_extensions().GetByID(id)) 345 return testing::AssertionSuccess(); 346 return testing::AssertionFailure() << "Could not install extension: " << id; 347 } 348 349 testing::AssertionResult LoadExtensionOverridingProxy( 350 const std::string& index, 351 const std::string& id, 352 Manifest::Location location) { 353 ExtensionBuilder builder; 354 builder.SetManifest(DictionaryBuilder() 355 .Set("name", std::string("Extension " + index)) 356 .Set("version", "1.0") 357 .Set("manifest_version", 2) 358 .Set("permissions", 359 ListBuilder().Append("proxy"))); 360 361 builder.SetLocation(location); 362 builder.SetID(id); 363 service_->AddExtension(builder.Build().get()); 364 365 // The proxy check relies on ExtensionPrefValueMap being up to date as to 366 // specifying which extension is controlling the proxy, but unfortunately 367 // that Map is not updated automatically for unit tests, so we simulate the 368 // update here to avoid test failures. 369 ExtensionPrefValueMap* extension_prefs_value_map = 370 ExtensionPrefValueMapFactory::GetForBrowserContext(profile()); 371 extension_prefs_value_map->RegisterExtension( 372 id, 373 base::Time::Now(), 374 true, // is_enabled. 375 false); // is_incognito_enabled. 376 extension_prefs_value_map->SetExtensionPref( 377 id, 378 prefs::kProxy, 379 kExtensionPrefsScopeRegular, 380 base::Value::CreateStringValue(id)); 381 382 if (ExtensionRegistry::Get(profile())->enabled_extensions().GetByID(id)) 383 return testing::AssertionSuccess(); 384 return testing::AssertionFailure() << "Could not install extension: " << id; 385 } 386 387 void Init() { 388 // The two lines of magical incantation required to get the extension 389 // service to work inside a unit test and access the extension prefs. 390 thread_bundle_.reset(new content::TestBrowserThreadBundle); 391 profile_.reset(new TestingProfile); 392 static_cast<TestExtensionSystem*>( 393 ExtensionSystem::Get(profile()))->CreateExtensionService( 394 CommandLine::ForCurrentProcess(), 395 base::FilePath(), 396 false); 397 service_ = profile_->GetExtensionService(); 398 service_->Init(); 399 } 400 401 virtual ~ExtensionMessageBubbleTest() { 402 // Make sure the profile is destroyed before the thread bundle. 403 profile_.reset(NULL); 404 } 405 406 virtual void SetUp() { 407 command_line_.reset(new CommandLine(CommandLine::NO_PROGRAM)); 408 } 409 410 protected: 411 Profile* profile() { return profile_.get(); } 412 413 scoped_refptr<Extension> CreateExtension( 414 Manifest::Location location, 415 const std::string& data, 416 const std::string& id) { 417 scoped_ptr<base::DictionaryValue> parsed_manifest( 418 extension_function_test_utils::ParseDictionary(data)); 419 return extension_function_test_utils::CreateExtension( 420 location, 421 parsed_manifest.get(), 422 id); 423 } 424 425 ExtensionService* service_; 426 427 private: 428 scoped_ptr<CommandLine> command_line_; 429 scoped_ptr<content::TestBrowserThreadBundle> thread_bundle_; 430 scoped_ptr<TestingProfile> profile_; 431 432 DISALLOW_COPY_AND_ASSIGN(ExtensionMessageBubbleTest); 433 }; 434 435 // The feature this is meant to test is only implemented on Windows. 436 #if defined(OS_WIN) 437 #define MAYBE_WipeoutControllerTest WipeoutControllerTest 438 #else 439 #define MAYBE_WipeoutControllerTest DISABLED_WipeoutControllerTest 440 #endif 441 442 TEST_F(ExtensionMessageBubbleTest, MAYBE_WipeoutControllerTest) { 443 Init(); 444 // Add three extensions, and control two of them in this test (extension 1 445 // and 2). 446 ASSERT_TRUE(LoadExtensionWithAction("1", kId1, Manifest::COMMAND_LINE)); 447 ASSERT_TRUE(LoadGenericExtension("2", kId2, Manifest::UNPACKED)); 448 ASSERT_TRUE(LoadGenericExtension("3", kId3, Manifest::EXTERNAL_POLICY)); 449 450 scoped_ptr<TestSuspiciousExtensionBubbleController> controller( 451 new TestSuspiciousExtensionBubbleController(profile())); 452 FakeExtensionMessageBubble bubble; 453 bubble.set_action_on_show( 454 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON); 455 456 // Validate that we don't have a suppress value for the extensions. 457 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile()); 458 EXPECT_FALSE(prefs->HasWipeoutBeenAcknowledged(kId1)); 459 EXPECT_FALSE(prefs->HasWipeoutBeenAcknowledged(kId2)); 460 461 EXPECT_FALSE(controller->ShouldShow()); 462 std::vector<base::string16> suspicious_extensions = 463 controller->GetExtensionList(); 464 EXPECT_EQ(0U, suspicious_extensions.size()); 465 EXPECT_EQ(0U, controller->link_click_count()); 466 EXPECT_EQ(0U, controller->dismiss_click_count()); 467 468 // Now disable an extension, specifying the wipeout flag. 469 service_->DisableExtension(kId1, Extension::DISABLE_NOT_VERIFIED); 470 471 EXPECT_FALSE(prefs->HasWipeoutBeenAcknowledged(kId1)); 472 EXPECT_FALSE(prefs->HasWipeoutBeenAcknowledged(kId2)); 473 controller.reset(new TestSuspiciousExtensionBubbleController( 474 profile())); 475 SuspiciousExtensionBubbleController::ClearProfileListForTesting(); 476 EXPECT_TRUE(controller->ShouldShow()); 477 suspicious_extensions = controller->GetExtensionList(); 478 ASSERT_EQ(1U, suspicious_extensions.size()); 479 EXPECT_TRUE(base::ASCIIToUTF16("Extension 1") == suspicious_extensions[0]); 480 controller->Show(&bubble); // Simulate showing the bubble. 481 EXPECT_EQ(0U, controller->link_click_count()); 482 EXPECT_EQ(1U, controller->dismiss_click_count()); 483 // Now the acknowledge flag should be set only for the first extension. 484 EXPECT_TRUE(prefs->HasWipeoutBeenAcknowledged(kId1)); 485 EXPECT_FALSE(prefs->HasWipeoutBeenAcknowledged(kId2)); 486 // Clear the flag. 487 prefs->SetWipeoutAcknowledged(kId1, false); 488 EXPECT_FALSE(prefs->HasWipeoutBeenAcknowledged(kId1)); 489 490 // Now disable the other extension and exercise the link click code path. 491 service_->DisableExtension(kId2, Extension::DISABLE_NOT_VERIFIED); 492 493 bubble.set_action_on_show( 494 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK); 495 controller.reset(new TestSuspiciousExtensionBubbleController( 496 profile())); 497 SuspiciousExtensionBubbleController::ClearProfileListForTesting(); 498 EXPECT_TRUE(controller->ShouldShow()); 499 suspicious_extensions = controller->GetExtensionList(); 500 ASSERT_EQ(2U, suspicious_extensions.size()); 501 EXPECT_TRUE(base::ASCIIToUTF16("Extension 1") == suspicious_extensions[1]); 502 EXPECT_TRUE(base::ASCIIToUTF16("Extension 2") == suspicious_extensions[0]); 503 controller->Show(&bubble); // Simulate showing the bubble. 504 EXPECT_EQ(1U, controller->link_click_count()); 505 EXPECT_EQ(0U, controller->dismiss_click_count()); 506 EXPECT_TRUE(prefs->HasWipeoutBeenAcknowledged(kId1)); 507 } 508 509 // The feature this is meant to test is only implemented on Windows. 510 #if defined(OS_WIN) 511 #define MAYBE_DevModeControllerTest DevModeControllerTest 512 #else 513 #define MAYBE_DevModeControllerTest DISABLED_DevModeControllerTest 514 #endif 515 516 TEST_F(ExtensionMessageBubbleTest, MAYBE_DevModeControllerTest) { 517 FeatureSwitch::ScopedOverride force_dev_mode_highlighting( 518 FeatureSwitch::force_dev_mode_highlighting(), true); 519 Init(); 520 // Add three extensions, and control two of them in this test (extension 1 521 // and 2). Extension 1 is a regular extension, Extension 2 is UNPACKED so it 522 // counts as a DevMode extension. 523 ASSERT_TRUE(LoadExtensionWithAction("1", kId1, Manifest::COMMAND_LINE)); 524 ASSERT_TRUE(LoadGenericExtension("2", kId2, Manifest::UNPACKED)); 525 ASSERT_TRUE(LoadGenericExtension("3", kId3, Manifest::EXTERNAL_POLICY)); 526 527 scoped_ptr<TestDevModeBubbleController> controller( 528 new TestDevModeBubbleController(profile())); 529 530 // The list will contain one enabled unpacked extension. 531 EXPECT_TRUE(controller->ShouldShow()); 532 std::vector<base::string16> dev_mode_extensions = 533 controller->GetExtensionList(); 534 ASSERT_EQ(2U, dev_mode_extensions.size()); 535 EXPECT_TRUE(base::ASCIIToUTF16("Extension 2") == dev_mode_extensions[0]); 536 EXPECT_TRUE(base::ASCIIToUTF16("Extension 1") == dev_mode_extensions[1]); 537 EXPECT_EQ(0U, controller->link_click_count()); 538 EXPECT_EQ(0U, controller->dismiss_click_count()); 539 EXPECT_EQ(0U, controller->action_click_count()); 540 541 // Simulate showing the bubble. 542 FakeExtensionMessageBubble bubble; 543 bubble.set_action_on_show( 544 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON); 545 controller->Show(&bubble); 546 EXPECT_EQ(0U, controller->link_click_count()); 547 EXPECT_EQ(0U, controller->action_click_count()); 548 EXPECT_EQ(1U, controller->dismiss_click_count()); 549 ExtensionRegistry* registry = ExtensionRegistry::Get(profile()); 550 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId1) != NULL); 551 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId2) != NULL); 552 553 // Do it again, but now press different button (Disable). 554 bubble.set_action_on_show( 555 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_ACTION_BUTTON); 556 controller.reset(new TestDevModeBubbleController( 557 profile())); 558 DevModeBubbleController::ClearProfileListForTesting(); 559 EXPECT_TRUE(controller->ShouldShow()); 560 dev_mode_extensions = controller->GetExtensionList(); 561 EXPECT_EQ(2U, dev_mode_extensions.size()); 562 controller->Show(&bubble); // Simulate showing the bubble. 563 EXPECT_EQ(0U, controller->link_click_count()); 564 EXPECT_EQ(1U, controller->action_click_count()); 565 EXPECT_EQ(0U, controller->dismiss_click_count()); 566 EXPECT_TRUE(registry->disabled_extensions().GetByID(kId1) != NULL); 567 EXPECT_TRUE(registry->disabled_extensions().GetByID(kId2) != NULL); 568 569 // Re-enable the extensions (disabled by the action button above). 570 service_->EnableExtension(kId1); 571 service_->EnableExtension(kId2); 572 573 // Show the dialog a third time, but now press the learn more link. 574 bubble.set_action_on_show( 575 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK); 576 controller.reset(new TestDevModeBubbleController( 577 profile())); 578 DevModeBubbleController::ClearProfileListForTesting(); 579 EXPECT_TRUE(controller->ShouldShow()); 580 dev_mode_extensions = controller->GetExtensionList(); 581 EXPECT_EQ(2U, dev_mode_extensions.size()); 582 controller->Show(&bubble); // Simulate showing the bubble. 583 EXPECT_EQ(1U, controller->link_click_count()); 584 EXPECT_EQ(0U, controller->action_click_count()); 585 EXPECT_EQ(0U, controller->dismiss_click_count()); 586 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId1) != NULL); 587 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId2) != NULL); 588 589 // Now disable the unpacked extension. 590 service_->DisableExtension(kId1, Extension::DISABLE_USER_ACTION); 591 service_->DisableExtension(kId2, Extension::DISABLE_USER_ACTION); 592 593 controller.reset(new TestDevModeBubbleController( 594 profile())); 595 DevModeBubbleController::ClearProfileListForTesting(); 596 EXPECT_FALSE(controller->ShouldShow()); 597 dev_mode_extensions = controller->GetExtensionList(); 598 EXPECT_EQ(0U, dev_mode_extensions.size()); 599 } 600 601 // The feature this is meant to test is only implemented on Windows. 602 #if defined(OS_WIN) 603 #define MAYBE_SettingsApiControllerTest SettingsApiControllerTest 604 #else 605 #define MAYBE_SettingsApiControllerTest DISABLED_SettingsApiControllerTest 606 #endif 607 608 TEST_F(ExtensionMessageBubbleTest, MAYBE_SettingsApiControllerTest) { 609 Init(); 610 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile()); 611 612 for (int i = 0; i < 3; ++i) { 613 switch (static_cast<SettingsApiOverrideType>(i)) { 614 case BUBBLE_TYPE_HOME_PAGE: 615 // Load two extensions overriding home page and one overriding something 616 // unrelated (to check for interference). Extension 2 should still win 617 // on the home page setting. 618 ASSERT_TRUE(LoadExtensionOverridingHome("1", kId1, Manifest::UNPACKED)); 619 ASSERT_TRUE(LoadExtensionOverridingHome("2", kId2, Manifest::UNPACKED)); 620 ASSERT_TRUE( 621 LoadExtensionOverridingStart("3", kId3, Manifest::UNPACKED)); 622 break; 623 case BUBBLE_TYPE_SEARCH_ENGINE: 624 // We deliberately skip testing the search engine since it relies on 625 // TemplateURLServiceFactory that isn't available while unit testing. 626 // This test is only simulating the bubble interaction with the user and 627 // that is more or less the same for the search engine as it is for the 628 // others. 629 continue; 630 case BUBBLE_TYPE_STARTUP_PAGES: 631 // Load two extensions overriding start page and one overriding 632 // something unrelated (to check for interference). Extension 2 should 633 // still win on the startup page setting. 634 ASSERT_TRUE( 635 LoadExtensionOverridingStart("1", kId1, Manifest::UNPACKED)); 636 ASSERT_TRUE( 637 LoadExtensionOverridingStart("2", kId2, Manifest::UNPACKED)); 638 ASSERT_TRUE(LoadExtensionOverridingHome("3", kId3, Manifest::UNPACKED)); 639 break; 640 default: 641 NOTREACHED(); 642 break; 643 } 644 645 scoped_ptr<TestSettingsApiBubbleController> controller( 646 new TestSettingsApiBubbleController( 647 profile(), static_cast<SettingsApiOverrideType>(i))); 648 649 // The list will contain one enabled unpacked extension (ext 2). 650 EXPECT_TRUE(controller->ShouldShow(kId2)); 651 std::vector<base::string16> override_extensions = 652 controller->GetExtensionList(); 653 ASSERT_EQ(1U, override_extensions.size()); 654 EXPECT_TRUE(base::ASCIIToUTF16("Extension 2") == 655 override_extensions[0].c_str()); 656 EXPECT_EQ(0U, controller->link_click_count()); 657 EXPECT_EQ(0U, controller->dismiss_click_count()); 658 EXPECT_EQ(0U, controller->action_click_count()); 659 660 // Simulate showing the bubble and dismissing it. 661 FakeExtensionMessageBubble bubble; 662 bubble.set_action_on_show( 663 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON); 664 controller->Show(&bubble); 665 EXPECT_EQ(0U, controller->link_click_count()); 666 EXPECT_EQ(0U, controller->action_click_count()); 667 EXPECT_EQ(1U, controller->dismiss_click_count()); 668 // No extension should have become disabled. 669 ExtensionRegistry* registry = ExtensionRegistry::Get(profile()); 670 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId1) != NULL); 671 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId2) != NULL); 672 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId3) != NULL); 673 // Only extension 2 should have been acknowledged. 674 EXPECT_FALSE(prefs->HasSettingsApiBubbleBeenAcknowledged(kId1)); 675 EXPECT_TRUE(prefs->HasSettingsApiBubbleBeenAcknowledged(kId2)); 676 EXPECT_FALSE(prefs->HasSettingsApiBubbleBeenAcknowledged(kId3)); 677 // Clean up after ourselves. 678 prefs->SetSettingsApiBubbleBeenAcknowledged(kId2, false); 679 680 // Simulate clicking the learn more link to dismiss it. 681 bubble.set_action_on_show( 682 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK); 683 controller.reset(new TestSettingsApiBubbleController( 684 profile(), static_cast<SettingsApiOverrideType>(i))); 685 controller->Show(&bubble); 686 EXPECT_EQ(1U, controller->link_click_count()); 687 EXPECT_EQ(0U, controller->action_click_count()); 688 EXPECT_EQ(0U, controller->dismiss_click_count()); 689 // No extension should have become disabled. 690 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId1) != NULL); 691 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId2) != NULL); 692 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId3) != NULL); 693 // Only extension 2 should have been acknowledged. 694 EXPECT_FALSE(prefs->HasSettingsApiBubbleBeenAcknowledged(kId1)); 695 EXPECT_TRUE(prefs->HasSettingsApiBubbleBeenAcknowledged(kId2)); 696 EXPECT_FALSE(prefs->HasSettingsApiBubbleBeenAcknowledged(kId3)); 697 // Clean up after ourselves. 698 prefs->SetSettingsApiBubbleBeenAcknowledged(kId2, false); 699 700 // Do it again, but now opt to disable the extension. 701 bubble.set_action_on_show( 702 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_ACTION_BUTTON); 703 controller.reset(new TestSettingsApiBubbleController( 704 profile(), static_cast<SettingsApiOverrideType>(i))); 705 EXPECT_TRUE(controller->ShouldShow(kId2)); 706 override_extensions = controller->GetExtensionList(); 707 EXPECT_EQ(1U, override_extensions.size()); 708 controller->Show(&bubble); // Simulate showing the bubble. 709 EXPECT_EQ(0U, controller->link_click_count()); 710 EXPECT_EQ(1U, controller->action_click_count()); 711 EXPECT_EQ(0U, controller->dismiss_click_count()); 712 // Only extension 2 should have become disabled. 713 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId1) != NULL); 714 EXPECT_TRUE(registry->disabled_extensions().GetByID(kId2) != NULL); 715 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId3) != NULL); 716 // No extension should have been acknowledged (it got disabled). 717 EXPECT_FALSE(prefs->HasSettingsApiBubbleBeenAcknowledged(kId1)); 718 EXPECT_FALSE(prefs->HasSettingsApiBubbleBeenAcknowledged(kId2)); 719 EXPECT_FALSE(prefs->HasSettingsApiBubbleBeenAcknowledged(kId3)); 720 721 // Clean up after ourselves. 722 service_->UninstallExtension(kId1, false, NULL); 723 service_->UninstallExtension(kId2, false, NULL); 724 service_->UninstallExtension(kId3, false, NULL); 725 } 726 } 727 728 // The feature this is meant to test is only implemented on Windows. 729 #if defined(OS_WIN) 730 #define MAYBE_NtpOverriddenControllerTest NtpOverriddenControllerTest 731 #else 732 #define MAYBE_NtpOverriddenControllerTest DISABLED_NtpOverriddenControllerTest 733 #endif 734 735 TEST_F(ExtensionMessageBubbleTest, MAYBE_NtpOverriddenControllerTest) { 736 Init(); 737 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile()); 738 // Load two extensions overriding new tab page and one overriding something 739 // unrelated (to check for interference). Extension 2 should still win 740 // on the new tab page setting. 741 ASSERT_TRUE(LoadExtensionOverridingNtp("1", kId1, Manifest::UNPACKED)); 742 ASSERT_TRUE(LoadExtensionOverridingNtp("2", kId2, Manifest::UNPACKED)); 743 ASSERT_TRUE(LoadExtensionOverridingStart("3", kId3, Manifest::UNPACKED)); 744 745 scoped_ptr<TestNtpOverriddenBubbleController> controller( 746 new TestNtpOverriddenBubbleController(profile())); 747 748 // The list will contain one enabled unpacked extension (ext 2). 749 EXPECT_TRUE(controller->ShouldShow(kId2)); 750 std::vector<base::string16> override_extensions = 751 controller->GetExtensionList(); 752 ASSERT_EQ(1U, override_extensions.size()); 753 EXPECT_TRUE(base::ASCIIToUTF16("Extension 2") == 754 override_extensions[0].c_str()); 755 EXPECT_EQ(0U, controller->link_click_count()); 756 EXPECT_EQ(0U, controller->dismiss_click_count()); 757 EXPECT_EQ(0U, controller->action_click_count()); 758 759 // Simulate showing the bubble and dismissing it. 760 FakeExtensionMessageBubble bubble; 761 bubble.set_action_on_show( 762 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON); 763 EXPECT_TRUE(controller->ShouldShow(kId2)); 764 controller->Show(&bubble); 765 EXPECT_EQ(0U, controller->link_click_count()); 766 EXPECT_EQ(0U, controller->action_click_count()); 767 EXPECT_EQ(1U, controller->dismiss_click_count()); 768 // No extension should have become disabled. 769 ExtensionRegistry* registry = ExtensionRegistry::Get(profile()); 770 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId1) != NULL); 771 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId2) != NULL); 772 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId3) != NULL); 773 // Only extension 2 should have been acknowledged. 774 EXPECT_FALSE(prefs->HasNtpOverriddenBubbleBeenAcknowledged(kId1)); 775 EXPECT_TRUE(prefs->HasNtpOverriddenBubbleBeenAcknowledged(kId2)); 776 EXPECT_FALSE(prefs->HasNtpOverriddenBubbleBeenAcknowledged(kId3)); 777 // Clean up after ourselves. 778 prefs->SetNtpOverriddenBubbleBeenAcknowledged(kId2, false); 779 780 // Simulate clicking the learn more link to dismiss it. 781 bubble.set_action_on_show( 782 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK); 783 controller.reset(new TestNtpOverriddenBubbleController(profile())); 784 EXPECT_TRUE(controller->ShouldShow(kId2)); 785 controller->Show(&bubble); 786 EXPECT_EQ(1U, controller->link_click_count()); 787 EXPECT_EQ(0U, controller->action_click_count()); 788 EXPECT_EQ(0U, controller->dismiss_click_count()); 789 // No extension should have become disabled. 790 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId1) != NULL); 791 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId2) != NULL); 792 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId3) != NULL); 793 // Only extension 2 should have been acknowledged. 794 EXPECT_FALSE(prefs->HasNtpOverriddenBubbleBeenAcknowledged(kId1)); 795 EXPECT_TRUE(prefs->HasNtpOverriddenBubbleBeenAcknowledged(kId2)); 796 EXPECT_FALSE(prefs->HasNtpOverriddenBubbleBeenAcknowledged(kId3)); 797 // Clean up after ourselves. 798 prefs->SetNtpOverriddenBubbleBeenAcknowledged(kId2, false); 799 800 // Do it again, but now opt to disable the extension. 801 bubble.set_action_on_show( 802 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_ACTION_BUTTON); 803 controller.reset(new TestNtpOverriddenBubbleController(profile())); 804 EXPECT_TRUE(controller->ShouldShow(kId2)); 805 override_extensions = controller->GetExtensionList(); 806 EXPECT_EQ(1U, override_extensions.size()); 807 controller->Show(&bubble); // Simulate showing the bubble. 808 EXPECT_EQ(0U, controller->link_click_count()); 809 EXPECT_EQ(1U, controller->action_click_count()); 810 EXPECT_EQ(0U, controller->dismiss_click_count()); 811 // Only extension 2 should have become disabled. 812 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId1) != NULL); 813 EXPECT_TRUE(registry->disabled_extensions().GetByID(kId2) != NULL); 814 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId3) != NULL); 815 // No extension should have been acknowledged (it got disabled). 816 EXPECT_FALSE(prefs->HasNtpOverriddenBubbleBeenAcknowledged(kId1)); 817 EXPECT_FALSE(prefs->HasNtpOverriddenBubbleBeenAcknowledged(kId2)); 818 EXPECT_FALSE(prefs->HasNtpOverriddenBubbleBeenAcknowledged(kId3)); 819 820 // Clean up after ourselves. 821 service_->UninstallExtension(kId1, false, NULL); 822 service_->UninstallExtension(kId2, false, NULL); 823 service_->UninstallExtension(kId3, false, NULL); 824 } 825 826 void SetInstallTime(const std::string& extension_id, 827 const base::Time& time, 828 ExtensionPrefs* prefs) { 829 std::string time_str = base::Int64ToString(time.ToInternalValue()); 830 prefs->UpdateExtensionPref(extension_id, 831 "install_time", 832 new base::StringValue(time_str)); 833 } 834 835 // The feature this is meant to test is only implemented on Windows. 836 #if defined(OS_WIN) 837 #define MAYBE_ProxyOverriddenControllerTest ProxyOverriddenControllerTest 838 #else 839 #define MAYBE_ProxyOverriddenControllerTest DISABLED_ProxyOverriddenControllerTest 840 #endif 841 842 TEST_F(ExtensionMessageBubbleTest, MAYBE_ProxyOverriddenControllerTest) { 843 Init(); 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)); 851 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 854 // testing. 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); 859 860 scoped_ptr<TestProxyOverriddenBubbleController> controller( 861 new TestProxyOverriddenBubbleController(profile())); 862 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); 868 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()); 879 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 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(prefs->HasProxyOverriddenBubbleBeenAcknowledged(kId1)); 895 EXPECT_TRUE(prefs->HasProxyOverriddenBubbleBeenAcknowledged(kId2)); 896 EXPECT_FALSE(prefs->HasProxyOverriddenBubbleBeenAcknowledged(kId3)); 897 // Clean up after ourselves. 898 prefs->SetProxyOverriddenBubbleBeenAcknowledged(kId2, false); 899 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(profile())); 904 EXPECT_TRUE(controller->ShouldShow(kId2)); 905 controller->Show(&bubble); 906 EXPECT_EQ(1U, controller->link_click_count()); 907 EXPECT_EQ(0U, controller->action_click_count()); 908 EXPECT_EQ(0U, controller->dismiss_click_count()); 909 // No extension should have become disabled. 910 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId1) != NULL); 911 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId2) != NULL); 912 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId3) != NULL); 913 // Only extension 2 should have been acknowledged. 914 EXPECT_FALSE(prefs->HasProxyOverriddenBubbleBeenAcknowledged(kId1)); 915 EXPECT_TRUE(prefs->HasProxyOverriddenBubbleBeenAcknowledged(kId2)); 916 EXPECT_FALSE(prefs->HasProxyOverriddenBubbleBeenAcknowledged(kId3)); 917 // Clean up after ourselves. 918 prefs->SetProxyOverriddenBubbleBeenAcknowledged(kId2, false); 919 920 // Do it again, but now opt to disable the extension. 921 bubble.set_action_on_show( 922 FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_ACTION_BUTTON); 923 controller.reset(new TestProxyOverriddenBubbleController(profile())); 924 EXPECT_TRUE(controller->ShouldShow(kId2)); 925 override_extensions = controller->GetExtensionList(); 926 EXPECT_EQ(1U, override_extensions.size()); 927 controller->Show(&bubble); // Simulate showing the bubble. 928 EXPECT_EQ(0U, controller->link_click_count()); 929 EXPECT_EQ(1U, controller->action_click_count()); 930 EXPECT_EQ(0U, controller->dismiss_click_count()); 931 // Only extension 2 should have become disabled. 932 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId1) != NULL); 933 EXPECT_TRUE(registry->disabled_extensions().GetByID(kId2) != NULL); 934 EXPECT_TRUE(registry->enabled_extensions().GetByID(kId3) != NULL); 935 // No extension should have been acknowledged (it got disabled). 936 EXPECT_FALSE(prefs->HasProxyOverriddenBubbleBeenAcknowledged(kId1)); 937 EXPECT_FALSE(prefs->HasProxyOverriddenBubbleBeenAcknowledged(kId2)); 938 EXPECT_FALSE(prefs->HasProxyOverriddenBubbleBeenAcknowledged(kId3)); 939 940 // Clean up after ourselves. 941 service_->UninstallExtension(kId1, false, NULL); 942 service_->UninstallExtension(kId2, false, NULL); 943 service_->UninstallExtension(kId3, false, NULL); 944 } 945 946 } // namespace extensions 947