Home | History | Annotate | Download | only in extensions
      1 // Copyright 2014 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/memory/ref_counted.h"
      6 #include "chrome/browser/extensions/extension_error_controller.h"
      7 #include "chrome/browser/extensions/extension_error_ui.h"
      8 #include "chrome/browser/extensions/extension_service.h"
      9 #include "chrome/browser/extensions/extension_service_test_base.h"
     10 #include "chrome/browser/profiles/profile.h"
     11 #include "chrome/test/base/testing_profile.h"
     12 #include "extensions/browser/extension_prefs.h"
     13 #include "extensions/browser/extension_registry.h"
     14 #include "extensions/common/extension.h"
     15 #include "extensions/common/extension_builder.h"
     16 #include "extensions/common/value_builder.h"
     17 
     18 namespace extensions {
     19 
     20 namespace {
     21 
     22 // Create a mock for the UI component of the error alert that is shown for
     23 // blacklisted extensions. This allows us to test which extensions the alert
     24 // is showing, and also eliminates the UI component (since this is a unit
     25 // test).
     26 class MockExtensionErrorUI : public ExtensionErrorUI {
     27  public:
     28   explicit MockExtensionErrorUI(ExtensionErrorUI::Delegate* delegate);
     29   virtual ~MockExtensionErrorUI();
     30 
     31   // Wrappers around the similar methods in ExtensionErrorUI.
     32   void CloseUI();
     33   void Accept();
     34   void Details();
     35 
     36   ExtensionErrorUI::Delegate* delegate() { return delegate_; }
     37 
     38  private:
     39   // ExtensionErrorUI implementation.
     40   virtual bool ShowErrorInBubbleView() OVERRIDE;
     41   virtual void ShowExtensions() OVERRIDE;
     42   virtual void Close() OVERRIDE;
     43 
     44   // Keep a copy of the delegate around for ourselves.
     45   ExtensionErrorUI::Delegate* delegate_;
     46 };
     47 
     48 // We use this as a slight hack to get the created Error UI, if any. We should
     49 // only ever have one (since this is a single-profile test), and this avoids
     50 // the need for any kind of accessor to the ErrorController from
     51 // ExtensionService.
     52 MockExtensionErrorUI* g_error_ui = NULL;
     53 
     54 MockExtensionErrorUI::MockExtensionErrorUI(
     55     ExtensionErrorUI::Delegate* delegate)
     56     : ExtensionErrorUI(delegate),
     57       delegate_(delegate) {
     58   // We should never make more than one of these in a test.
     59   DCHECK(!g_error_ui);
     60   g_error_ui = this;
     61 }
     62 
     63 MockExtensionErrorUI::~MockExtensionErrorUI() {
     64   g_error_ui = NULL;
     65 }
     66 
     67 void MockExtensionErrorUI::CloseUI() {
     68   BubbleViewDidClose();
     69 }
     70 
     71 void MockExtensionErrorUI::Accept() {
     72   BubbleViewAcceptButtonPressed();
     73 }
     74 
     75 void MockExtensionErrorUI::Details() {
     76   BubbleViewCancelButtonPressed();
     77 }
     78 
     79 bool MockExtensionErrorUI::ShowErrorInBubbleView() {
     80   return true;
     81 }
     82 
     83 void MockExtensionErrorUI::ShowExtensions() {}
     84 
     85 void MockExtensionErrorUI::Close() {
     86   CloseUI();
     87 }
     88 
     89 ExtensionErrorUI* CreateMockUI(ExtensionErrorUI::Delegate* delegate) {
     90   return new MockExtensionErrorUI(delegate);
     91 }
     92 
     93 // Builds and returns a simple extension.
     94 scoped_refptr<const Extension> BuildExtension() {
     95   return ExtensionBuilder()
     96       .SetManifest(DictionaryBuilder().Set("name", "My Wonderful Extension")
     97                                       .Set("version", "0.1.1.0")
     98                                       .Set("manifest_version", 2)
     99                                       .Build())
    100       .Build();
    101 }
    102 
    103 }  // namespace
    104 
    105 class ExtensionErrorControllerUnitTest : public ExtensionServiceTestBase {
    106  protected:
    107   virtual void SetUp() OVERRIDE;
    108 
    109   // Add an extension to chrome, and mark it as blacklisted in the prefs.
    110   testing::AssertionResult AddBlacklistedExtension(const Extension* extension);
    111 
    112   // Return the ExtensionPrefs associated with the test.
    113   ExtensionPrefs* GetPrefs();
    114 
    115   Profile* profile() { return profile_.get(); }
    116 };
    117 
    118 void ExtensionErrorControllerUnitTest::SetUp() {
    119   ExtensionServiceTestBase::SetUp();
    120   // Make sure we use the mock UI instead of the real UI.
    121   ExtensionErrorController::SetUICreateMethodForTesting(CreateMockUI);
    122 
    123   // We don't want a first-run ExtensionService, since we ignore warnings
    124   // for new profiles.
    125   ExtensionServiceInitParams params = CreateDefaultInitParams();
    126   params.is_first_run = false;
    127   InitializeExtensionService(params);
    128 }
    129 
    130 testing::AssertionResult
    131 ExtensionErrorControllerUnitTest::AddBlacklistedExtension(
    132     const Extension* extension) {
    133   GetPrefs()->SetExtensionBlacklisted(extension->id(), true);
    134   service_->AddExtension(extension);
    135 
    136   // Make sure the extension is added to the blacklisted set.
    137   if (!ExtensionRegistry::Get(profile())->blacklisted_extensions()
    138           .Contains(extension->id())) {
    139     return testing::AssertionFailure()
    140         << "Failed to add blacklisted extension.";
    141   }
    142 
    143   return testing::AssertionSuccess();
    144 }
    145 
    146 ExtensionPrefs* ExtensionErrorControllerUnitTest::GetPrefs() {
    147   return ExtensionPrefs::Get(profile());
    148 }
    149 
    150 // Test that closing the extension alert for blacklisted extensions counts
    151 // as acknowledging them in the prefs.
    152 TEST_F(ExtensionErrorControllerUnitTest, ClosingAcknowledgesBlacklisted) {
    153   // Add a blacklisted extension.
    154   scoped_refptr<const Extension> extension = BuildExtension();
    155   ASSERT_TRUE(AddBlacklistedExtension(extension.get()));
    156 
    157   service_->Init();
    158 
    159   // Make sure that we created an error "ui" to warn about the blacklisted
    160   // extension.
    161   ASSERT_TRUE(g_error_ui);
    162   ExtensionErrorUI::Delegate* delegate = g_error_ui->delegate();
    163   ASSERT_TRUE(delegate);
    164 
    165   // Make sure that the blacklisted extension is reported (and that no other
    166   // extensions are).
    167   const ExtensionSet& delegate_blacklisted_extensions =
    168       delegate->GetBlacklistedExtensions();
    169   EXPECT_EQ(1u, delegate_blacklisted_extensions.size());
    170   EXPECT_TRUE(delegate_blacklisted_extensions.Contains(extension->id()));
    171 
    172   // Close, and verify that the extension ids now acknowledged.
    173   g_error_ui->CloseUI();
    174   EXPECT_TRUE(GetPrefs()->IsBlacklistedExtensionAcknowledged(extension->id()));
    175   // Verify we cleaned up after ourselves.
    176   EXPECT_FALSE(g_error_ui);
    177 }
    178 
    179 // Test that clicking "accept" on the extension alert counts as acknowledging
    180 // blacklisted extensions.
    181 TEST_F(ExtensionErrorControllerUnitTest, AcceptingAcknowledgesBlacklisted) {
    182   // Add a blacklisted extension.
    183   scoped_refptr<const Extension> extension = BuildExtension();
    184   ASSERT_TRUE(AddBlacklistedExtension(extension.get()));
    185 
    186   service_->Init();
    187 
    188   // Make sure that we created an error "ui" to warn about the blacklisted
    189   // extension.
    190   ASSERT_TRUE(g_error_ui);
    191 
    192   // Accept, and verify that the extension ids now acknowledged.
    193   g_error_ui->Accept();
    194   EXPECT_TRUE(GetPrefs()->IsBlacklistedExtensionAcknowledged(extension->id()));
    195   // Verify we cleaned up after ourselves.
    196   EXPECT_FALSE(g_error_ui);
    197 }
    198 
    199 // Test that we don't warn for extensions which are blacklisted, but have
    200 // already been acknowledged.
    201 TEST_F(ExtensionErrorControllerUnitTest, DontWarnForAcknowledgedBlacklisted) {
    202   scoped_refptr<const Extension> extension = BuildExtension();
    203   ASSERT_TRUE(AddBlacklistedExtension(extension.get()));
    204 
    205   GetPrefs()->AcknowledgeBlacklistedExtension(extension->id());
    206 
    207   service_->Init();
    208 
    209   // We should never have made an alert, because the extension should already
    210   // be acknowledged.
    211   ASSERT_FALSE(g_error_ui);
    212 }
    213 
    214 }  // namespace extensions
    215