Home | History | Annotate | Download | only in extensions
      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