Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2012 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 "chrome/browser/extensions/extension_prefs_unittest.h"
      6 
      7 #include "base/basictypes.h"
      8 #include "base/files/scoped_temp_dir.h"
      9 #include "base/path_service.h"
     10 #include "base/prefs/mock_pref_change_callback.h"
     11 #include "base/prefs/pref_change_registrar.h"
     12 #include "base/stl_util.h"
     13 #include "base/strings/string_number_conversions.h"
     14 #include "base/strings/stringprintf.h"
     15 #include "base/values.h"
     16 #include "chrome/browser/extensions/extension_pref_value_map.h"
     17 #include "chrome/browser/extensions/extension_prefs.h"
     18 #include "chrome/browser/prefs/pref_service_syncable.h"
     19 #include "chrome/browser/prefs/scoped_user_pref_update.h"
     20 #include "chrome/common/chrome_paths.h"
     21 #include "chrome/common/extensions/extension_manifest_constants.h"
     22 #include "chrome/common/extensions/permissions/permission_set.h"
     23 #include "chrome/common/extensions/permissions/permissions_info.h"
     24 #include "components/user_prefs/pref_registry_syncable.h"
     25 #include "content/public/browser/notification_details.h"
     26 #include "content/public/browser/notification_source.h"
     27 #include "content/public/test/mock_notification_observer.h"
     28 #include "sync/api/string_ordinal.h"
     29 
     30 using base::Time;
     31 using base::TimeDelta;
     32 using content::BrowserThread;
     33 
     34 namespace extensions {
     35 
     36 static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
     37   int schemes = URLPattern::SCHEME_ALL;
     38   extent->AddPattern(URLPattern(schemes, pattern));
     39 }
     40 
     41 ExtensionPrefsTest::ExtensionPrefsTest()
     42     : ui_thread_(BrowserThread::UI, &message_loop_),
     43       prefs_(message_loop_.message_loop_proxy().get()) {}
     44 
     45 ExtensionPrefsTest::~ExtensionPrefsTest() {
     46 }
     47 
     48 void ExtensionPrefsTest::RegisterPreferences(
     49     user_prefs::PrefRegistrySyncable* registry) {}
     50 
     51 void ExtensionPrefsTest::SetUp() {
     52   RegisterPreferences(prefs_.pref_registry().get());
     53   Initialize();
     54 }
     55 
     56 void ExtensionPrefsTest::TearDown() {
     57   Verify();
     58 
     59   // Reset ExtensionPrefs, and re-verify.
     60   prefs_.ResetPrefRegistry();
     61   RegisterPreferences(prefs_.pref_registry().get());
     62   prefs_.RecreateExtensionPrefs();
     63   Verify();
     64   prefs_.pref_service()->CommitPendingWrite();
     65   message_loop_.RunUntilIdle();
     66 }
     67 
     68 // Tests the LastPingDay/SetLastPingDay functions.
     69 class ExtensionPrefsLastPingDay : public ExtensionPrefsTest {
     70  public:
     71   ExtensionPrefsLastPingDay()
     72       : extension_time_(Time::Now() - TimeDelta::FromHours(4)),
     73         blacklist_time_(Time::Now() - TimeDelta::FromHours(2)) {}
     74 
     75   virtual void Initialize() OVERRIDE {
     76     extension_id_ = prefs_.AddExtensionAndReturnId("last_ping_day");
     77     EXPECT_TRUE(prefs()->LastPingDay(extension_id_).is_null());
     78     prefs()->SetLastPingDay(extension_id_, extension_time_);
     79     prefs()->SetBlacklistLastPingDay(blacklist_time_);
     80   }
     81 
     82   virtual void Verify() OVERRIDE {
     83     Time result = prefs()->LastPingDay(extension_id_);
     84     EXPECT_FALSE(result.is_null());
     85     EXPECT_TRUE(result == extension_time_);
     86     result = prefs()->BlacklistLastPingDay();
     87     EXPECT_FALSE(result.is_null());
     88     EXPECT_TRUE(result == blacklist_time_);
     89   }
     90 
     91  private:
     92   Time extension_time_;
     93   Time blacklist_time_;
     94   std::string extension_id_;
     95 };
     96 TEST_F(ExtensionPrefsLastPingDay, LastPingDay) {}
     97 
     98 // Tests the GetToolbarOrder/SetToolbarOrder functions.
     99 class ExtensionPrefsToolbarOrder : public ExtensionPrefsTest {
    100  public:
    101   virtual void Initialize() OVERRIDE {
    102     list_.push_back(prefs_.AddExtensionAndReturnId("1"));
    103     list_.push_back(prefs_.AddExtensionAndReturnId("2"));
    104     list_.push_back(prefs_.AddExtensionAndReturnId("3"));
    105     std::vector<std::string> before_list = prefs()->GetToolbarOrder();
    106     EXPECT_TRUE(before_list.empty());
    107     prefs()->SetToolbarOrder(list_);
    108   }
    109 
    110   virtual void Verify() OVERRIDE {
    111     std::vector<std::string> result = prefs()->GetToolbarOrder();
    112     ASSERT_EQ(list_.size(), result.size());
    113     for (size_t i = 0; i < list_.size(); i++) {
    114       EXPECT_EQ(list_[i], result[i]);
    115     }
    116   }
    117 
    118  private:
    119   std::vector<std::string> list_;
    120 };
    121 TEST_F(ExtensionPrefsToolbarOrder, ToolbarOrder) {}
    122 
    123 
    124 // Tests the IsExtensionDisabled/SetExtensionState functions.
    125 class ExtensionPrefsExtensionState : public ExtensionPrefsTest {
    126  public:
    127   virtual void Initialize() OVERRIDE {
    128     extension = prefs_.AddExtension("test");
    129     prefs()->SetExtensionState(extension->id(), Extension::DISABLED);
    130   }
    131 
    132   virtual void Verify() OVERRIDE {
    133     EXPECT_TRUE(prefs()->IsExtensionDisabled(extension->id()));
    134   }
    135 
    136  private:
    137   scoped_refptr<Extension> extension;
    138 };
    139 TEST_F(ExtensionPrefsExtensionState, ExtensionState) {}
    140 
    141 class ExtensionPrefsEscalatePermissions : public ExtensionPrefsTest {
    142  public:
    143   virtual void Initialize() OVERRIDE {
    144     extension = prefs_.AddExtension("test");
    145     prefs()->SetDidExtensionEscalatePermissions(extension.get(), true);
    146   }
    147 
    148   virtual void Verify() OVERRIDE {
    149     EXPECT_TRUE(prefs()->DidExtensionEscalatePermissions(extension->id()));
    150   }
    151 
    152  private:
    153   scoped_refptr<Extension> extension;
    154 };
    155 TEST_F(ExtensionPrefsEscalatePermissions, EscalatePermissions) {}
    156 
    157 // Tests the AddGrantedPermissions / GetGrantedPermissions functions.
    158 class ExtensionPrefsGrantedPermissions : public ExtensionPrefsTest {
    159  public:
    160   virtual void Initialize() OVERRIDE {
    161     const APIPermissionInfo* permission_info =
    162       PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket);
    163 
    164     extension_id_ = prefs_.AddExtensionAndReturnId("test");
    165 
    166     api_perm_set1_.insert(APIPermission::kTab);
    167     api_perm_set1_.insert(APIPermission::kBookmark);
    168     scoped_ptr<APIPermission> permission(
    169         permission_info->CreateAPIPermission());
    170     {
    171       scoped_ptr<base::ListValue> value(new base::ListValue());
    172       value->Append(Value::CreateStringValue("tcp-connect:*.example.com:80"));
    173       value->Append(Value::CreateStringValue("udp-bind::8080"));
    174       value->Append(Value::CreateStringValue("udp-send-to::8888"));
    175       if (!permission->FromValue(value.get()))
    176         NOTREACHED();
    177     }
    178     api_perm_set1_.insert(permission.release());
    179 
    180     api_perm_set2_.insert(APIPermission::kHistory);
    181 
    182     AddPattern(&ehost_perm_set1_, "http://*.google.com/*");
    183     AddPattern(&ehost_perm_set1_, "http://example.com/*");
    184     AddPattern(&ehost_perm_set1_, "chrome://favicon/*");
    185 
    186     AddPattern(&ehost_perm_set2_, "https://*.google.com/*");
    187     // with duplicate:
    188     AddPattern(&ehost_perm_set2_, "http://*.google.com/*");
    189 
    190     AddPattern(&shost_perm_set1_, "http://reddit.com/r/test/*");
    191     AddPattern(&shost_perm_set2_, "http://reddit.com/r/test/*");
    192     AddPattern(&shost_perm_set2_, "http://somesite.com/*");
    193     AddPattern(&shost_perm_set2_, "http://example.com/*");
    194 
    195     APIPermissionSet expected_apis = api_perm_set1_;
    196 
    197     AddPattern(&ehost_permissions_, "http://*.google.com/*");
    198     AddPattern(&ehost_permissions_, "http://example.com/*");
    199     AddPattern(&ehost_permissions_, "chrome://favicon/*");
    200     AddPattern(&ehost_permissions_, "https://*.google.com/*");
    201 
    202     AddPattern(&shost_permissions_, "http://reddit.com/r/test/*");
    203     AddPattern(&shost_permissions_, "http://somesite.com/*");
    204     AddPattern(&shost_permissions_, "http://example.com/*");
    205 
    206     APIPermissionSet empty_set;
    207     URLPatternSet empty_extent;
    208     scoped_refptr<PermissionSet> permissions;
    209     scoped_refptr<PermissionSet> granted_permissions;
    210 
    211     // Make sure both granted api and host permissions start empty.
    212     granted_permissions =
    213         prefs()->GetGrantedPermissions(extension_id_);
    214     EXPECT_TRUE(granted_permissions->IsEmpty());
    215 
    216     permissions = new PermissionSet(
    217         api_perm_set1_, empty_extent, empty_extent);
    218 
    219     // Add part of the api permissions.
    220     prefs()->AddGrantedPermissions(extension_id_, permissions.get());
    221     granted_permissions = prefs()->GetGrantedPermissions(extension_id_);
    222     EXPECT_TRUE(granted_permissions.get());
    223     EXPECT_FALSE(granted_permissions->IsEmpty());
    224     EXPECT_EQ(expected_apis, granted_permissions->apis());
    225     EXPECT_TRUE(granted_permissions->effective_hosts().is_empty());
    226     EXPECT_FALSE(granted_permissions->HasEffectiveFullAccess());
    227     granted_permissions = NULL;
    228 
    229     // Add part of the explicit host permissions.
    230     permissions = new PermissionSet(
    231         empty_set, ehost_perm_set1_, empty_extent);
    232     prefs()->AddGrantedPermissions(extension_id_, permissions.get());
    233     granted_permissions = prefs()->GetGrantedPermissions(extension_id_);
    234     EXPECT_FALSE(granted_permissions->IsEmpty());
    235     EXPECT_FALSE(granted_permissions->HasEffectiveFullAccess());
    236     EXPECT_EQ(expected_apis, granted_permissions->apis());
    237     EXPECT_EQ(ehost_perm_set1_,
    238               granted_permissions->explicit_hosts());
    239     EXPECT_EQ(ehost_perm_set1_,
    240               granted_permissions->effective_hosts());
    241 
    242     // Add part of the scriptable host permissions.
    243     permissions = new PermissionSet(
    244         empty_set, empty_extent, shost_perm_set1_);
    245     prefs()->AddGrantedPermissions(extension_id_, permissions.get());
    246     granted_permissions = prefs()->GetGrantedPermissions(extension_id_);
    247     EXPECT_FALSE(granted_permissions->IsEmpty());
    248     EXPECT_FALSE(granted_permissions->HasEffectiveFullAccess());
    249     EXPECT_EQ(expected_apis, granted_permissions->apis());
    250     EXPECT_EQ(ehost_perm_set1_,
    251               granted_permissions->explicit_hosts());
    252     EXPECT_EQ(shost_perm_set1_,
    253               granted_permissions->scriptable_hosts());
    254 
    255     URLPatternSet::CreateUnion(ehost_perm_set1_, shost_perm_set1_,
    256                                &effective_permissions_);
    257     EXPECT_EQ(effective_permissions_, granted_permissions->effective_hosts());
    258 
    259     // Add the rest of the permissions.
    260     permissions = new PermissionSet(
    261         api_perm_set2_, ehost_perm_set2_, shost_perm_set2_);
    262 
    263     APIPermissionSet::Union(expected_apis, api_perm_set2_, &api_permissions_);
    264 
    265     prefs()->AddGrantedPermissions(extension_id_, permissions.get());
    266     granted_permissions = prefs()->GetGrantedPermissions(extension_id_);
    267     EXPECT_TRUE(granted_permissions.get());
    268     EXPECT_FALSE(granted_permissions->IsEmpty());
    269     EXPECT_EQ(api_permissions_, granted_permissions->apis());
    270     EXPECT_EQ(ehost_permissions_,
    271               granted_permissions->explicit_hosts());
    272     EXPECT_EQ(shost_permissions_,
    273               granted_permissions->scriptable_hosts());
    274     effective_permissions_.ClearPatterns();
    275     URLPatternSet::CreateUnion(ehost_permissions_, shost_permissions_,
    276                                &effective_permissions_);
    277     EXPECT_EQ(effective_permissions_, granted_permissions->effective_hosts());
    278   }
    279 
    280   virtual void Verify() OVERRIDE {
    281     scoped_refptr<PermissionSet> permissions(
    282         prefs()->GetGrantedPermissions(extension_id_));
    283     EXPECT_TRUE(permissions.get());
    284     EXPECT_FALSE(permissions->HasEffectiveFullAccess());
    285     EXPECT_EQ(api_permissions_, permissions->apis());
    286     EXPECT_EQ(ehost_permissions_,
    287               permissions->explicit_hosts());
    288     EXPECT_EQ(shost_permissions_,
    289               permissions->scriptable_hosts());
    290   }
    291 
    292  private:
    293   std::string extension_id_;
    294   APIPermissionSet api_perm_set1_;
    295   APIPermissionSet api_perm_set2_;
    296   URLPatternSet ehost_perm_set1_;
    297   URLPatternSet ehost_perm_set2_;
    298   URLPatternSet shost_perm_set1_;
    299   URLPatternSet shost_perm_set2_;
    300 
    301   APIPermissionSet api_permissions_;
    302   URLPatternSet ehost_permissions_;
    303   URLPatternSet shost_permissions_;
    304   URLPatternSet effective_permissions_;
    305 };
    306 TEST_F(ExtensionPrefsGrantedPermissions, GrantedPermissions) {}
    307 
    308 // Tests the SetActivePermissions / GetActivePermissions functions.
    309 class ExtensionPrefsActivePermissions : public ExtensionPrefsTest {
    310  public:
    311   virtual void Initialize() OVERRIDE {
    312     extension_id_ = prefs_.AddExtensionAndReturnId("test");
    313 
    314     APIPermissionSet api_perms;
    315     api_perms.insert(APIPermission::kTab);
    316     api_perms.insert(APIPermission::kBookmark);
    317     api_perms.insert(APIPermission::kHistory);
    318 
    319     URLPatternSet ehosts;
    320     AddPattern(&ehosts, "http://*.google.com/*");
    321     AddPattern(&ehosts, "http://example.com/*");
    322     AddPattern(&ehosts, "chrome://favicon/*");
    323 
    324     URLPatternSet shosts;
    325     AddPattern(&shosts, "https://*.google.com/*");
    326     AddPattern(&shosts, "http://reddit.com/r/test/*");
    327 
    328     active_perms_ = new PermissionSet(api_perms, ehosts, shosts);
    329 
    330     // Make sure the active permissions start empty.
    331     scoped_refptr<PermissionSet> active(
    332         prefs()->GetActivePermissions(extension_id_));
    333     EXPECT_TRUE(active->IsEmpty());
    334 
    335     // Set the active permissions.
    336     prefs()->SetActivePermissions(extension_id_, active_perms_.get());
    337     active = prefs()->GetActivePermissions(extension_id_);
    338     EXPECT_EQ(active_perms_->apis(), active->apis());
    339     EXPECT_EQ(active_perms_->explicit_hosts(), active->explicit_hosts());
    340     EXPECT_EQ(active_perms_->scriptable_hosts(), active->scriptable_hosts());
    341     EXPECT_EQ(*active_perms_.get(), *active.get());
    342   }
    343 
    344   virtual void Verify() OVERRIDE {
    345     scoped_refptr<PermissionSet> permissions(
    346         prefs()->GetActivePermissions(extension_id_));
    347     EXPECT_EQ(*active_perms_.get(), *permissions.get());
    348   }
    349 
    350  private:
    351   std::string extension_id_;
    352   scoped_refptr<PermissionSet> active_perms_;
    353 };
    354 TEST_F(ExtensionPrefsActivePermissions, SetAndGetActivePermissions) {}
    355 
    356 // Tests the GetVersionString function.
    357 class ExtensionPrefsVersionString : public ExtensionPrefsTest {
    358  public:
    359   virtual void Initialize() OVERRIDE {
    360     extension = prefs_.AddExtension("test");
    361     EXPECT_EQ("0.1", prefs()->GetVersionString(extension->id()));
    362     prefs()->OnExtensionUninstalled(extension->id(),
    363                                     Manifest::INTERNAL, false);
    364   }
    365 
    366   virtual void Verify() OVERRIDE {
    367     EXPECT_EQ("", prefs()->GetVersionString(extension->id()));
    368   }
    369 
    370  private:
    371   scoped_refptr<Extension> extension;
    372 };
    373 TEST_F(ExtensionPrefsVersionString, VersionString) {}
    374 
    375 class ExtensionPrefsAcknowledgment : public ExtensionPrefsTest {
    376  public:
    377   virtual void Initialize() OVERRIDE {
    378     not_installed_id_ = "pghjnghklobnfoidcldiidjjjhkeeaoi";
    379 
    380     // Install some extensions.
    381     for (int i = 0; i < 5; i++) {
    382       std::string name = "test" + base::IntToString(i);
    383       extensions_.push_back(prefs_.AddExtension(name));
    384     }
    385     EXPECT_EQ(NULL,
    386               prefs()->GetInstalledExtensionInfo(not_installed_id_).get());
    387 
    388     ExtensionList::const_iterator iter;
    389     for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
    390       std::string id = (*iter)->id();
    391       EXPECT_FALSE(prefs()->IsExternalExtensionAcknowledged(id));
    392       EXPECT_FALSE(prefs()->IsBlacklistedExtensionAcknowledged(id));
    393       if (external_id_.empty()) {
    394         external_id_ = id;
    395         continue;
    396       }
    397       if (blacklisted_id_.empty()) {
    398         blacklisted_id_ = id;
    399         continue;
    400       }
    401     }
    402     // For each type of acknowledgment, acknowledge one installed and one
    403     // not-installed extension id.
    404     prefs()->AcknowledgeExternalExtension(external_id_);
    405     prefs()->AcknowledgeBlacklistedExtension(blacklisted_id_);
    406     prefs()->AcknowledgeExternalExtension(not_installed_id_);
    407     prefs()->AcknowledgeBlacklistedExtension(not_installed_id_);
    408   }
    409 
    410   virtual void Verify() OVERRIDE {
    411     ExtensionList::const_iterator iter;
    412     for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
    413       std::string id = (*iter)->id();
    414       if (id == external_id_) {
    415         EXPECT_TRUE(prefs()->IsExternalExtensionAcknowledged(id));
    416       } else {
    417         EXPECT_FALSE(prefs()->IsExternalExtensionAcknowledged(id));
    418       }
    419       if (id == blacklisted_id_) {
    420         EXPECT_TRUE(prefs()->IsBlacklistedExtensionAcknowledged(id));
    421       } else {
    422         EXPECT_FALSE(prefs()->IsBlacklistedExtensionAcknowledged(id));
    423       }
    424     }
    425     EXPECT_TRUE(prefs()->IsExternalExtensionAcknowledged(not_installed_id_));
    426     EXPECT_TRUE(prefs()->IsBlacklistedExtensionAcknowledged(not_installed_id_));
    427   }
    428 
    429  private:
    430   ExtensionList extensions_;
    431 
    432   std::string not_installed_id_;
    433   std::string external_id_;
    434   std::string blacklisted_id_;
    435 };
    436 TEST_F(ExtensionPrefsAcknowledgment, Acknowledgment) {}
    437 
    438 // Tests the idle install information functions.
    439 class ExtensionPrefsDelayedInstallInfo : public ExtensionPrefsTest {
    440  public:
    441   // Sets idle install information for one test extension.
    442   void SetIdleInfo(std::string id, int num) {
    443     DictionaryValue manifest;
    444     manifest.SetString(extension_manifest_keys::kName, "test");
    445     manifest.SetString(extension_manifest_keys::kVersion,
    446                        "1." + base::IntToString(num));
    447     base::FilePath path =
    448         prefs_.extensions_dir().AppendASCII(base::IntToString(num));
    449     std::string errors;
    450     scoped_refptr<Extension> extension = Extension::Create(
    451         path, Manifest::INTERNAL, manifest, Extension::NO_FLAGS, id, &errors);
    452     ASSERT_TRUE(extension.get()) << errors;
    453     ASSERT_EQ(id, extension->id());
    454     prefs()->SetDelayedInstallInfo(extension.get(),
    455                                    Extension::ENABLED,
    456                                    Blacklist::NOT_BLACKLISTED,
    457                                    ExtensionPrefs::DELAY_REASON_WAIT_FOR_IDLE,
    458                                    syncer::StringOrdinal());
    459   }
    460 
    461   // Verifies that we get back expected idle install information previously
    462   // set by SetIdleInfo.
    463   void VerifyIdleInfo(std::string id, int num) {
    464     scoped_ptr<ExtensionInfo> info(prefs()->GetDelayedInstallInfo(id));
    465     ASSERT_TRUE(info);
    466     std::string version;
    467     ASSERT_TRUE(info->extension_manifest->GetString("version", &version));
    468     ASSERT_EQ("1." + base::IntToString(num), version);
    469     ASSERT_EQ(base::IntToString(num),
    470               info->extension_path.BaseName().MaybeAsASCII());
    471   }
    472 
    473   bool HasInfoForId(extensions::ExtensionPrefs::ExtensionsInfo* info,
    474                     const std::string& id) {
    475     for (size_t i = 0; i < info->size(); ++i) {
    476       if (info->at(i)->extension_id == id)
    477         return true;
    478     }
    479     return false;
    480   }
    481 
    482   virtual void Initialize() OVERRIDE {
    483     PathService::Get(chrome::DIR_TEST_DATA, &basedir_);
    484     now_ = Time::Now();
    485     id1_ = prefs_.AddExtensionAndReturnId("1");
    486     id2_ = prefs_.AddExtensionAndReturnId("2");
    487     id3_ = prefs_.AddExtensionAndReturnId("3");
    488     id4_ = prefs_.AddExtensionAndReturnId("4");
    489 
    490     // Set info for two extensions, then remove it.
    491     SetIdleInfo(id1_, 1);
    492     SetIdleInfo(id2_, 2);
    493     VerifyIdleInfo(id1_, 1);
    494     VerifyIdleInfo(id2_, 2);
    495     scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> info(
    496         prefs()->GetAllDelayedInstallInfo());
    497     EXPECT_EQ(2u, info->size());
    498     EXPECT_TRUE(HasInfoForId(info.get(), id1_));
    499     EXPECT_TRUE(HasInfoForId(info.get(), id2_));
    500     prefs()->RemoveDelayedInstallInfo(id1_);
    501     prefs()->RemoveDelayedInstallInfo(id2_);
    502     info = prefs()->GetAllDelayedInstallInfo();
    503     EXPECT_TRUE(info->empty());
    504 
    505     // Try getting/removing info for an id that used to have info set.
    506     EXPECT_FALSE(prefs()->GetDelayedInstallInfo(id1_));
    507     EXPECT_FALSE(prefs()->RemoveDelayedInstallInfo(id1_));
    508 
    509     // Try getting/removing info for an id that has not yet had any info set.
    510     EXPECT_FALSE(prefs()->GetDelayedInstallInfo(id3_));
    511     EXPECT_FALSE(prefs()->RemoveDelayedInstallInfo(id3_));
    512 
    513     // Set info for 4 extensions, then remove for one of them.
    514     SetIdleInfo(id1_, 1);
    515     SetIdleInfo(id2_, 2);
    516     SetIdleInfo(id3_, 3);
    517     SetIdleInfo(id4_, 4);
    518     VerifyIdleInfo(id1_, 1);
    519     VerifyIdleInfo(id2_, 2);
    520     VerifyIdleInfo(id3_, 3);
    521     VerifyIdleInfo(id4_, 4);
    522     prefs()->RemoveDelayedInstallInfo(id3_);
    523   }
    524 
    525   virtual void Verify() OVERRIDE {
    526     // Make sure the info for the 3 extensions we expect is present.
    527     scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> info(
    528         prefs()->GetAllDelayedInstallInfo());
    529     EXPECT_EQ(3u, info->size());
    530     EXPECT_TRUE(HasInfoForId(info.get(), id1_));
    531     EXPECT_TRUE(HasInfoForId(info.get(), id2_));
    532     EXPECT_TRUE(HasInfoForId(info.get(), id4_));
    533     VerifyIdleInfo(id1_, 1);
    534     VerifyIdleInfo(id2_, 2);
    535     VerifyIdleInfo(id4_, 4);
    536 
    537     // Make sure there isn't info the for the one extension id we removed.
    538     EXPECT_FALSE(prefs()->GetDelayedInstallInfo(id3_));
    539   }
    540 
    541  protected:
    542   Time now_;
    543   base::FilePath basedir_;
    544   std::string id1_;
    545   std::string id2_;
    546   std::string id3_;
    547   std::string id4_;
    548 };
    549 TEST_F(ExtensionPrefsDelayedInstallInfo, DelayedInstallInfo) {}
    550 
    551 // Tests the FinishDelayedInstallInfo function.
    552 class ExtensionPrefsFinishDelayedInstallInfo : public ExtensionPrefsTest {
    553  public:
    554   virtual void Initialize() OVERRIDE {
    555     DictionaryValue dictionary;
    556     dictionary.SetString(extension_manifest_keys::kName, "test");
    557     dictionary.SetString(extension_manifest_keys::kVersion, "0.1");
    558     dictionary.SetString(extension_manifest_keys::kBackgroundPage,
    559         "background.html");
    560     scoped_refptr<Extension> extension =
    561         prefs_.AddExtensionWithManifest(dictionary, Manifest::INTERNAL);
    562     id_ = extension->id();
    563 
    564 
    565     // Set idle info
    566     DictionaryValue manifest;
    567     manifest.SetString(extension_manifest_keys::kName, "test");
    568     manifest.SetString(extension_manifest_keys::kVersion, "0.2");
    569     scoped_ptr<ListValue> scripts(new ListValue);
    570     scripts->AppendString("test.js");
    571     manifest.Set(extension_manifest_keys::kBackgroundScripts,
    572         scripts.release());
    573     base::FilePath path =
    574         prefs_.extensions_dir().AppendASCII("test_0.2");
    575     std::string errors;
    576     scoped_refptr<Extension> new_extension = Extension::Create(
    577         path, Manifest::INTERNAL, manifest, Extension::NO_FLAGS, id_, &errors);
    578     ASSERT_TRUE(new_extension.get()) << errors;
    579     ASSERT_EQ(id_, new_extension->id());
    580     prefs()->SetDelayedInstallInfo(new_extension.get(),
    581                                    Extension::ENABLED,
    582                                    Blacklist::NOT_BLACKLISTED,
    583                                    ExtensionPrefs::DELAY_REASON_WAIT_FOR_IDLE,
    584                                    syncer::StringOrdinal());
    585 
    586     // Finish idle installation
    587     ASSERT_TRUE(prefs()->FinishDelayedInstallInfo(id_));
    588   }
    589 
    590   virtual void Verify() OVERRIDE {
    591     EXPECT_FALSE(prefs()->GetDelayedInstallInfo(id_));
    592 
    593     const DictionaryValue* manifest;
    594     ASSERT_TRUE(prefs()->ReadPrefAsDictionary(id_, "manifest", &manifest));
    595     ASSERT_TRUE(manifest);
    596     std::string value;
    597     EXPECT_TRUE(manifest->GetString(extension_manifest_keys::kName, &value));
    598     EXPECT_EQ("test", value);
    599     EXPECT_TRUE(manifest->GetString(extension_manifest_keys::kVersion, &value));
    600     EXPECT_EQ("0.2", value);
    601     EXPECT_FALSE(manifest->GetString(extension_manifest_keys::kBackgroundPage,
    602                                      &value));
    603     const ListValue* scripts;
    604     ASSERT_TRUE(manifest->GetList(extension_manifest_keys::kBackgroundScripts,
    605                                   &scripts));
    606     EXPECT_EQ(1u, scripts->GetSize());
    607   }
    608 
    609  protected:
    610   std::string id_;
    611 };
    612 TEST_F(ExtensionPrefsFinishDelayedInstallInfo, FinishDelayedInstallInfo) {}
    613 
    614 class ExtensionPrefsOnExtensionInstalled : public ExtensionPrefsTest {
    615  public:
    616   virtual void Initialize() OVERRIDE {
    617     extension_ = prefs_.AddExtension("on_extension_installed");
    618     EXPECT_FALSE(prefs()->IsExtensionDisabled(extension_->id()));
    619     prefs()->OnExtensionInstalled(extension_.get(),
    620                                   Extension::DISABLED,
    621                                   Blacklist::NOT_BLACKLISTED,
    622                                   syncer::StringOrdinal());
    623   }
    624 
    625   virtual void Verify() OVERRIDE {
    626     EXPECT_TRUE(prefs()->IsExtensionDisabled(extension_->id()));
    627   }
    628 
    629  private:
    630   scoped_refptr<Extension> extension_;
    631 };
    632 TEST_F(ExtensionPrefsOnExtensionInstalled,
    633        ExtensionPrefsOnExtensionInstalled) {}
    634 
    635 class ExtensionPrefsAppDraggedByUser : public ExtensionPrefsTest {
    636  public:
    637   virtual void Initialize() OVERRIDE {
    638     extension_ = prefs_.AddExtension("on_extension_installed");
    639     EXPECT_FALSE(prefs()->WasAppDraggedByUser(extension_->id()));
    640     prefs()->OnExtensionInstalled(extension_.get(),
    641                                   Extension::ENABLED,
    642                                   Blacklist::NOT_BLACKLISTED,
    643                                   syncer::StringOrdinal());
    644   }
    645 
    646   virtual void Verify() OVERRIDE {
    647     // Set the flag and see if it persisted.
    648     prefs()->SetAppDraggedByUser(extension_->id());
    649     EXPECT_TRUE(prefs()->WasAppDraggedByUser(extension_->id()));
    650 
    651     // Make sure it doesn't change on consecutive calls.
    652     prefs()->SetAppDraggedByUser(extension_->id());
    653     EXPECT_TRUE(prefs()->WasAppDraggedByUser(extension_->id()));
    654   }
    655 
    656  private:
    657   scoped_refptr<Extension> extension_;
    658 };
    659 TEST_F(ExtensionPrefsAppDraggedByUser, ExtensionPrefsAppDraggedByUser) {}
    660 
    661 class ExtensionPrefsFlags : public ExtensionPrefsTest {
    662  public:
    663   virtual void Initialize() OVERRIDE {
    664     {
    665       base::DictionaryValue dictionary;
    666       dictionary.SetString(extension_manifest_keys::kName, "from_webstore");
    667       dictionary.SetString(extension_manifest_keys::kVersion, "0.1");
    668       webstore_extension_ = prefs_.AddExtensionWithManifestAndFlags(
    669           dictionary, Manifest::INTERNAL, Extension::FROM_WEBSTORE);
    670     }
    671 
    672     {
    673       base::DictionaryValue dictionary;
    674       dictionary.SetString(extension_manifest_keys::kName, "from_bookmark");
    675       dictionary.SetString(extension_manifest_keys::kVersion, "0.1");
    676       bookmark_extension_ = prefs_.AddExtensionWithManifestAndFlags(
    677           dictionary, Manifest::INTERNAL, Extension::FROM_BOOKMARK);
    678     }
    679 
    680     {
    681       base::DictionaryValue dictionary;
    682       dictionary.SetString(extension_manifest_keys::kName,
    683                            "was_installed_by_default");
    684       dictionary.SetString(extension_manifest_keys::kVersion, "0.1");
    685       default_extension_ = prefs_.AddExtensionWithManifestAndFlags(
    686           dictionary,
    687           Manifest::INTERNAL,
    688           Extension::WAS_INSTALLED_BY_DEFAULT);
    689     }
    690   }
    691 
    692   virtual void Verify() OVERRIDE {
    693     EXPECT_TRUE(prefs()->IsFromWebStore(webstore_extension_->id()));
    694     EXPECT_FALSE(prefs()->IsFromBookmark(webstore_extension_->id()));
    695 
    696     EXPECT_TRUE(prefs()->IsFromBookmark(bookmark_extension_->id()));
    697     EXPECT_FALSE(prefs()->IsFromWebStore(bookmark_extension_->id()));
    698 
    699     EXPECT_TRUE(prefs()->WasInstalledByDefault(default_extension_->id()));
    700   }
    701 
    702  private:
    703   scoped_refptr<Extension> webstore_extension_;
    704   scoped_refptr<Extension> bookmark_extension_;
    705   scoped_refptr<Extension> default_extension_;
    706 };
    707 TEST_F(ExtensionPrefsFlags, ExtensionPrefsFlags) {}
    708 
    709 PrefsPrepopulatedTestBase::PrefsPrepopulatedTestBase()
    710     : ExtensionPrefsTest() {
    711   DictionaryValue simple_dict;
    712   std::string error;
    713 
    714   simple_dict.SetString(extension_manifest_keys::kVersion, "1.0.0.0");
    715   simple_dict.SetString(extension_manifest_keys::kName, "unused");
    716 
    717   extension1_ = Extension::Create(
    718       prefs_.temp_dir().AppendASCII("ext1_"),
    719       Manifest::EXTERNAL_PREF,
    720       simple_dict,
    721       Extension::NO_FLAGS,
    722       &error);
    723   extension2_ = Extension::Create(
    724       prefs_.temp_dir().AppendASCII("ext2_"),
    725       Manifest::EXTERNAL_PREF,
    726       simple_dict,
    727       Extension::NO_FLAGS,
    728       &error);
    729   extension3_ = Extension::Create(
    730       prefs_.temp_dir().AppendASCII("ext3_"),
    731       Manifest::EXTERNAL_PREF,
    732       simple_dict,
    733       Extension::NO_FLAGS,
    734       &error);
    735   extension4_ = Extension::Create(
    736       prefs_.temp_dir().AppendASCII("ext4_"),
    737       Manifest::EXTERNAL_PREF,
    738       simple_dict,
    739       Extension::NO_FLAGS,
    740       &error);
    741 
    742   for (size_t i = 0; i < kNumInstalledExtensions; ++i)
    743     installed_[i] = false;
    744 }
    745 
    746 PrefsPrepopulatedTestBase::~PrefsPrepopulatedTestBase() {
    747 }
    748 
    749 // Tests that blacklist state can be queried.
    750 class ExtensionPrefsBlacklistedExtensions : public ExtensionPrefsTest {
    751  public:
    752   virtual ~ExtensionPrefsBlacklistedExtensions() {}
    753 
    754   virtual void Initialize() OVERRIDE {
    755     extension_a_ = prefs_.AddExtension("a");
    756     extension_b_ = prefs_.AddExtension("b");
    757     extension_c_ = prefs_.AddExtension("c");
    758   }
    759 
    760   virtual void Verify() OVERRIDE {
    761     {
    762       std::set<std::string> ids;
    763       EXPECT_EQ(ids, prefs()->GetBlacklistedExtensions());
    764     }
    765     prefs()->SetExtensionBlacklisted(extension_a_->id(), true);
    766     {
    767       std::set<std::string> ids;
    768       ids.insert(extension_a_->id());
    769       EXPECT_EQ(ids, prefs()->GetBlacklistedExtensions());
    770     }
    771     prefs()->SetExtensionBlacklisted(extension_b_->id(), true);
    772     prefs()->SetExtensionBlacklisted(extension_c_->id(), true);
    773     {
    774       std::set<std::string> ids;
    775       ids.insert(extension_a_->id());
    776       ids.insert(extension_b_->id());
    777       ids.insert(extension_c_->id());
    778       EXPECT_EQ(ids, prefs()->GetBlacklistedExtensions());
    779     }
    780     prefs()->SetExtensionBlacklisted(extension_a_->id(), false);
    781     {
    782       std::set<std::string> ids;
    783       ids.insert(extension_b_->id());
    784       ids.insert(extension_c_->id());
    785       EXPECT_EQ(ids, prefs()->GetBlacklistedExtensions());
    786     }
    787     prefs()->SetExtensionBlacklisted(extension_b_->id(), false);
    788     prefs()->SetExtensionBlacklisted(extension_c_->id(), false);
    789     {
    790       std::set<std::string> ids;
    791       EXPECT_EQ(ids, prefs()->GetBlacklistedExtensions());
    792     }
    793 
    794     // The interesting part: make sure that we're cleaning up after ourselves
    795     // when we're storing *just* the fact that the extension is blacklisted.
    796     std::string arbitrary_id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    797 
    798     prefs()->SetExtensionBlacklisted(arbitrary_id, true);
    799     prefs()->SetExtensionBlacklisted(extension_a_->id(), true);
    800 
    801     // (And make sure that the acknowledged bit is also cleared).
    802     prefs()->AcknowledgeBlacklistedExtension(arbitrary_id);
    803 
    804     EXPECT_TRUE(prefs()->GetExtensionPref(arbitrary_id));
    805     {
    806       std::set<std::string> ids;
    807       ids.insert(arbitrary_id);
    808       ids.insert(extension_a_->id());
    809       EXPECT_EQ(ids, prefs()->GetBlacklistedExtensions());
    810     }
    811     prefs()->SetExtensionBlacklisted(arbitrary_id, false);
    812     prefs()->SetExtensionBlacklisted(extension_a_->id(), false);
    813     EXPECT_FALSE(prefs()->GetExtensionPref(arbitrary_id));
    814     {
    815       std::set<std::string> ids;
    816       EXPECT_EQ(ids, prefs()->GetBlacklistedExtensions());
    817     }
    818   }
    819 
    820  private:
    821   scoped_refptr<const Extension> extension_a_;
    822   scoped_refptr<const Extension> extension_b_;
    823   scoped_refptr<const Extension> extension_c_;
    824 };
    825 TEST_F(ExtensionPrefsBlacklistedExtensions,
    826        ExtensionPrefsBlacklistedExtensions) {}
    827 
    828 }  // namespace extensions
    829