Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2011 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/scoped_temp_dir.h"
      6 #include "base/message_loop.h"
      7 #include "base/path_service.h"
      8 #include "base/stl_util-inl.h"
      9 #include "base/string_number_conversions.h"
     10 #include "base/stringprintf.h"
     11 #include "chrome/browser/extensions/extension_prefs.h"
     12 #include "chrome/browser/extensions/test_extension_prefs.h"
     13 #include "chrome/browser/prefs/pref_change_registrar.h"
     14 #include "chrome/browser/prefs/scoped_user_pref_update.h"
     15 #include "chrome/common/chrome_paths.h"
     16 #include "chrome/common/extensions/extension_constants.h"
     17 #include "content/common/notification_details.h"
     18 #include "content/common/notification_observer_mock.h"
     19 #include "content/common/notification_source.h"
     20 #include "content/browser/browser_thread.h"
     21 #include "testing/gtest/include/gtest/gtest.h"
     22 
     23 using base::Time;
     24 using base::TimeDelta;
     25 
     26 namespace {
     27 
     28 const char kPref1[] = "path1.subpath";
     29 const char kPref2[] = "path2";
     30 const char kPref3[] = "path3";
     31 const char kPref4[] = "path4";
     32 
     33 // Default values in case an extension pref value is not overridden.
     34 const char kDefaultPref1[] = "default pref 1";
     35 const char kDefaultPref2[] = "default pref 2";
     36 const char kDefaultPref3[] = "default pref 3";
     37 const char kDefaultPref4[] = "default pref 4";
     38 
     39 }  // namespace
     40 
     41 static void AddPattern(ExtensionExtent* extent, const std::string& pattern) {
     42   int schemes = URLPattern::SCHEME_ALL;
     43   extent->AddPattern(URLPattern(schemes, pattern));
     44 }
     45 
     46 static void AssertEqualExtents(ExtensionExtent* extent1,
     47                                ExtensionExtent* extent2) {
     48   std::vector<URLPattern> patterns1 = extent1->patterns();
     49   std::vector<URLPattern> patterns2 = extent2->patterns();
     50   std::set<std::string> strings1;
     51   EXPECT_EQ(patterns1.size(), patterns2.size());
     52 
     53   for (size_t i = 0; i < patterns1.size(); ++i)
     54     strings1.insert(patterns1.at(i).GetAsString());
     55 
     56   std::set<std::string> strings2;
     57   for (size_t i = 0; i < patterns2.size(); ++i)
     58     strings2.insert(patterns2.at(i).GetAsString());
     59 
     60   EXPECT_EQ(strings1, strings2);
     61 }
     62 
     63 // Base class for tests.
     64 class ExtensionPrefsTest : public testing::Test {
     65  public:
     66   ExtensionPrefsTest()
     67       : ui_thread_(BrowserThread::UI, &message_loop_),
     68         file_thread_(BrowserThread::FILE, &message_loop_) {
     69   }
     70 
     71   // This function will get called once, and is the right place to do operations
     72   // on ExtensionPrefs that write data.
     73   virtual void Initialize() = 0;
     74 
     75   // This function will be called twice - once while the original ExtensionPrefs
     76   // object is still alive, and once after recreation. Thus, it tests that
     77   // things don't break after any ExtensionPrefs startup work.
     78   virtual void Verify() = 0;
     79 
     80   // This function is called to Register preference default values.
     81   virtual void RegisterPreferences() {}
     82 
     83   virtual void SetUp() {
     84     RegisterPreferences();
     85     Initialize();
     86   }
     87 
     88   virtual void TearDown() {
     89     Verify();
     90 
     91     // Reset ExtensionPrefs, and re-verify.
     92     prefs_.RecreateExtensionPrefs();
     93     RegisterPreferences();
     94     Verify();
     95   }
     96 
     97  protected:
     98   ExtensionPrefs* prefs() { return prefs_.prefs(); }
     99 
    100   MessageLoop message_loop_;
    101   BrowserThread ui_thread_;
    102   BrowserThread file_thread_;
    103 
    104   TestExtensionPrefs prefs_;
    105 
    106  private:
    107   DISALLOW_COPY_AND_ASSIGN(ExtensionPrefsTest);
    108 };
    109 
    110 // Tests the LastPingDay/SetLastPingDay functions.
    111 class ExtensionPrefsLastPingDay : public ExtensionPrefsTest {
    112  public:
    113   ExtensionPrefsLastPingDay()
    114       : extension_time_(Time::Now() - TimeDelta::FromHours(4)),
    115         blacklist_time_(Time::Now() - TimeDelta::FromHours(2)) {}
    116 
    117   virtual void Initialize() {
    118     extension_id_ = prefs_.AddExtensionAndReturnId("last_ping_day");
    119     EXPECT_TRUE(prefs()->LastPingDay(extension_id_).is_null());
    120     prefs()->SetLastPingDay(extension_id_, extension_time_);
    121     prefs()->SetBlacklistLastPingDay(blacklist_time_);
    122   }
    123 
    124   virtual void Verify() {
    125     Time result = prefs()->LastPingDay(extension_id_);
    126     EXPECT_FALSE(result.is_null());
    127     EXPECT_TRUE(result == extension_time_);
    128     result = prefs()->BlacklistLastPingDay();
    129     EXPECT_FALSE(result.is_null());
    130     EXPECT_TRUE(result == blacklist_time_);
    131   }
    132 
    133  private:
    134   Time extension_time_;
    135   Time blacklist_time_;
    136   std::string extension_id_;
    137 };
    138 TEST_F(ExtensionPrefsLastPingDay, LastPingDay) {}
    139 
    140 
    141 // Tests the GetToolbarOrder/SetToolbarOrder functions.
    142 class ExtensionPrefsToolbarOrder : public ExtensionPrefsTest {
    143  public:
    144   virtual void Initialize() {
    145     list_.push_back(prefs_.AddExtensionAndReturnId("1"));
    146     list_.push_back(prefs_.AddExtensionAndReturnId("2"));
    147     list_.push_back(prefs_.AddExtensionAndReturnId("3"));
    148     std::vector<std::string> before_list = prefs()->GetToolbarOrder();
    149     EXPECT_TRUE(before_list.empty());
    150     prefs()->SetToolbarOrder(list_);
    151   }
    152 
    153   virtual void Verify() {
    154     std::vector<std::string> result = prefs()->GetToolbarOrder();
    155     ASSERT_EQ(list_.size(), result.size());
    156     for (size_t i = 0; i < list_.size(); i++) {
    157       EXPECT_EQ(list_[i], result[i]);
    158     }
    159   }
    160 
    161  private:
    162   std::vector<std::string> list_;
    163 };
    164 TEST_F(ExtensionPrefsToolbarOrder, ToolbarOrder) {}
    165 
    166 
    167 // Tests the GetExtensionState/SetExtensionState functions.
    168 class ExtensionPrefsExtensionState : public ExtensionPrefsTest {
    169  public:
    170   virtual void Initialize() {
    171     extension = prefs_.AddExtension("test");
    172     prefs()->SetExtensionState(extension.get(), Extension::DISABLED);
    173   }
    174 
    175   virtual void Verify() {
    176     EXPECT_EQ(Extension::DISABLED, prefs()->GetExtensionState(extension->id()));
    177   }
    178 
    179  private:
    180   scoped_refptr<Extension> extension;
    181 };
    182 TEST_F(ExtensionPrefsExtensionState, ExtensionState) {}
    183 
    184 
    185 class ExtensionPrefsEscalatePermissions : public ExtensionPrefsTest {
    186  public:
    187   virtual void Initialize() {
    188     extension = prefs_.AddExtension("test");
    189     prefs()->SetDidExtensionEscalatePermissions(extension.get(), true);
    190   }
    191 
    192   virtual void Verify() {
    193     EXPECT_TRUE(prefs()->DidExtensionEscalatePermissions(extension->id()));
    194   }
    195 
    196  private:
    197   scoped_refptr<Extension> extension;
    198 };
    199 TEST_F(ExtensionPrefsEscalatePermissions, EscalatePermissions) {}
    200 
    201 // Tests the AddGrantedPermissions / GetGrantedPermissions functions.
    202 class ExtensionPrefsGrantedPermissions : public ExtensionPrefsTest {
    203  public:
    204   virtual void Initialize() {
    205     extension_id_ = prefs_.AddExtensionAndReturnId("test");
    206 
    207     api_perm_set1_.insert("tabs");
    208     api_perm_set1_.insert("bookmarks");
    209     api_perm_set1_.insert("something_random");
    210 
    211     api_perm_set2_.insert("history");
    212     api_perm_set2_.insert("unknown2");
    213 
    214     AddPattern(&host_perm_set1_, "http://*.google.com/*");
    215     AddPattern(&host_perm_set1_, "http://example.com/*");
    216     AddPattern(&host_perm_set1_, "chrome://favicon/*");
    217 
    218     AddPattern(&host_perm_set2_, "https://*.google.com/*");
    219     // with duplicate:
    220     AddPattern(&host_perm_set2_, "http://*.google.com/*");
    221 
    222     std::set_union(api_perm_set1_.begin(), api_perm_set1_.end(),
    223                    api_perm_set2_.begin(), api_perm_set2_.end(),
    224                    std::inserter(api_permissions_, api_permissions_.begin()));
    225 
    226     AddPattern(&host_permissions_, "http://*.google.com/*");
    227     AddPattern(&host_permissions_, "http://example.com/*");
    228     AddPattern(&host_permissions_, "chrome://favicon/*");
    229     AddPattern(&host_permissions_, "https://*.google.com/*");
    230 
    231     std::set<std::string> empty_set;
    232     std::set<std::string> api_perms;
    233     bool full_access = false;
    234     ExtensionExtent host_perms;
    235     ExtensionExtent empty_extent;
    236 
    237     // Make sure both granted api and host permissions start empty.
    238     EXPECT_FALSE(prefs()->GetGrantedPermissions(
    239         extension_id_, &full_access, &api_perms, &host_perms));
    240 
    241     EXPECT_TRUE(api_perms.empty());
    242     EXPECT_TRUE(host_perms.is_empty());
    243 
    244     // Add part of the api permissions.
    245     prefs()->AddGrantedPermissions(
    246         extension_id_, false, api_perm_set1_, empty_extent);
    247     EXPECT_TRUE(prefs()->GetGrantedPermissions(
    248         extension_id_, &full_access, &api_perms, &host_perms));
    249     EXPECT_EQ(api_perm_set1_, api_perms);
    250     EXPECT_TRUE(host_perms.is_empty());
    251     EXPECT_FALSE(full_access);
    252     host_perms.ClearPaths();
    253     api_perms.clear();
    254 
    255     // Add part of the host permissions.
    256     prefs()->AddGrantedPermissions(
    257         extension_id_, false, empty_set, host_perm_set1_);
    258     EXPECT_TRUE(prefs()->GetGrantedPermissions(
    259         extension_id_, &full_access, &api_perms, &host_perms));
    260     EXPECT_FALSE(full_access);
    261     EXPECT_EQ(api_perm_set1_, api_perms);
    262     AssertEqualExtents(&host_perm_set1_, &host_perms);
    263     host_perms.ClearPaths();
    264     api_perms.clear();
    265 
    266     // Add the rest of both the api and host permissions.
    267     prefs()->AddGrantedPermissions(extension_id_,
    268                                    true,
    269                                    api_perm_set2_,
    270                                    host_perm_set2_);
    271 
    272     EXPECT_TRUE(prefs()->GetGrantedPermissions(
    273         extension_id_, &full_access, &api_perms, &host_perms));
    274     EXPECT_TRUE(full_access);
    275     EXPECT_EQ(api_permissions_, api_perms);
    276     AssertEqualExtents(&host_permissions_, &host_perms);
    277   }
    278 
    279   virtual void Verify() {
    280     std::set<std::string> api_perms;
    281     ExtensionExtent host_perms;
    282     bool full_access;
    283 
    284     EXPECT_TRUE(prefs()->GetGrantedPermissions(
    285         extension_id_, &full_access, &api_perms, &host_perms));
    286     EXPECT_EQ(api_permissions_, api_perms);
    287     EXPECT_TRUE(full_access);
    288     AssertEqualExtents(&host_permissions_, &host_perms);
    289   }
    290 
    291  private:
    292   std::string extension_id_;
    293   std::set<std::string> api_perm_set1_;
    294   std::set<std::string> api_perm_set2_;
    295   ExtensionExtent host_perm_set1_;
    296   ExtensionExtent host_perm_set2_;
    297 
    298 
    299   std::set<std::string> api_permissions_;
    300   ExtensionExtent host_permissions_;
    301 };
    302 TEST_F(ExtensionPrefsGrantedPermissions, GrantedPermissions) {}
    303 
    304 // Tests the GetVersionString function.
    305 class ExtensionPrefsVersionString : public ExtensionPrefsTest {
    306  public:
    307   virtual void Initialize() {
    308     extension = prefs_.AddExtension("test");
    309     EXPECT_EQ("0.1", prefs()->GetVersionString(extension->id()));
    310     prefs()->OnExtensionUninstalled(extension->id(),
    311                                     Extension::INTERNAL, false);
    312   }
    313 
    314   virtual void Verify() {
    315     EXPECT_EQ("", prefs()->GetVersionString(extension->id()));
    316   }
    317 
    318  private:
    319   scoped_refptr<Extension> extension;
    320 };
    321 TEST_F(ExtensionPrefsVersionString, VersionString) {}
    322 
    323 // Tests various areas of blacklist functionality.
    324 class ExtensionPrefsBlacklist : public ExtensionPrefsTest {
    325  public:
    326   virtual void Initialize() {
    327     not_installed_id_ = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    328 
    329     // Install 5 extensions.
    330     for (int i = 0; i < 5; i++) {
    331       std::string name = "test" + base::IntToString(i);
    332       extensions_.push_back(prefs_.AddExtension(name));
    333     }
    334     EXPECT_EQ(NULL, prefs()->GetInstalledExtensionInfo(not_installed_id_));
    335 
    336     ExtensionList::const_iterator iter;
    337     for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
    338       EXPECT_FALSE(prefs()->IsExtensionBlacklisted((*iter)->id()));
    339     }
    340     // Blacklist one installed and one not-installed extension id.
    341     std::set<std::string> blacklisted_ids;
    342     blacklisted_ids.insert(extensions_[0]->id());
    343     blacklisted_ids.insert(not_installed_id_);
    344     prefs()->UpdateBlacklist(blacklisted_ids);
    345   }
    346 
    347   virtual void Verify() {
    348     // Make sure the two id's we expect to be blacklisted are.
    349     EXPECT_TRUE(prefs()->IsExtensionBlacklisted(extensions_[0]->id()));
    350     EXPECT_TRUE(prefs()->IsExtensionBlacklisted(not_installed_id_));
    351 
    352     // Make sure the other id's are not blacklisted.
    353     ExtensionList::const_iterator iter;
    354     for (iter = extensions_.begin() + 1; iter != extensions_.end(); ++iter) {
    355       EXPECT_FALSE(prefs()->IsExtensionBlacklisted((*iter)->id()));
    356     }
    357 
    358     // Make sure GetInstalledExtensionsInfo returns only the non-blacklisted
    359     // extensions data.
    360     scoped_ptr<ExtensionPrefs::ExtensionsInfo> info(
    361         prefs()->GetInstalledExtensionsInfo());
    362     EXPECT_EQ(4u, info->size());
    363     ExtensionPrefs::ExtensionsInfo::iterator info_iter;
    364     for (info_iter = info->begin(); info_iter != info->end(); ++info_iter) {
    365       ExtensionInfo* extension_info = info_iter->get();
    366       EXPECT_NE(extensions_[0]->id(), extension_info->extension_id);
    367     }
    368   }
    369 
    370  private:
    371   ExtensionList extensions_;
    372 
    373   // An id we'll make up that doesn't match any installed extension id.
    374   std::string not_installed_id_;
    375 };
    376 TEST_F(ExtensionPrefsBlacklist, Blacklist) {}
    377 
    378 // Tests force hiding browser actions.
    379 class ExtensionPrefsHidingBrowserActions : public ExtensionPrefsTest {
    380  public:
    381   virtual void Initialize() {
    382     // Install 5 extensions.
    383     for (int i = 0; i < 5; i++) {
    384       std::string name = "test" + base::IntToString(i);
    385       extensions_.push_back(prefs_.AddExtension(name));
    386     }
    387 
    388     ExtensionList::const_iterator iter;
    389     for (iter = extensions_.begin(); iter != extensions_.end(); ++iter)
    390       EXPECT_TRUE(prefs()->GetBrowserActionVisibility(*iter));
    391 
    392     prefs()->SetBrowserActionVisibility(extensions_[0], false);
    393     prefs()->SetBrowserActionVisibility(extensions_[1], true);
    394   }
    395 
    396   virtual void Verify() {
    397     // Make sure the one we hid is hidden.
    398     EXPECT_FALSE(prefs()->GetBrowserActionVisibility(extensions_[0]));
    399 
    400     // Make sure the other id's are not hidden.
    401     ExtensionList::const_iterator iter = extensions_.begin() + 1;
    402     for (; iter != extensions_.end(); ++iter) {
    403       SCOPED_TRACE(base::StringPrintf("Loop %d ",
    404                        static_cast<int>(iter - extensions_.begin())));
    405       EXPECT_TRUE(prefs()->GetBrowserActionVisibility(*iter));
    406     }
    407   }
    408 
    409  private:
    410   ExtensionList extensions_;
    411 };
    412 TEST_F(ExtensionPrefsHidingBrowserActions, ForceHide) {}
    413 
    414 // Tests the idle install information functions.
    415 class ExtensionPrefsIdleInstallInfo : public ExtensionPrefsTest {
    416  public:
    417   // Sets idle install information for one test extension.
    418   void SetIdleInfo(std::string id, int num) {
    419     prefs()->SetIdleInstallInfo(id,
    420                                 basedir_.AppendASCII(base::IntToString(num)),
    421                                 "1." + base::IntToString(num),
    422                                 now_ + TimeDelta::FromSeconds(num));
    423   }
    424 
    425   // Verifies that we get back expected idle install information previously
    426   // set by SetIdleInfo.
    427   void VerifyIdleInfo(std::string id, int num) {
    428     FilePath crx_path;
    429     std::string version;
    430     base::Time fetch_time;
    431     ASSERT_TRUE(prefs()->GetIdleInstallInfo(id, &crx_path, &version,
    432                                             &fetch_time));
    433     ASSERT_EQ(crx_path.value(),
    434               basedir_.AppendASCII(base::IntToString(num)).value());
    435     ASSERT_EQ("1." + base::IntToString(num), version);
    436     ASSERT_TRUE(fetch_time == now_ + TimeDelta::FromSeconds(num));
    437   }
    438 
    439   virtual void Initialize() {
    440     PathService::Get(chrome::DIR_TEST_DATA, &basedir_);
    441     now_ = Time::Now();
    442     id1_ = prefs_.AddExtensionAndReturnId("1");
    443     id2_ = prefs_.AddExtensionAndReturnId("2");
    444     id3_ = prefs_.AddExtensionAndReturnId("3");
    445     id4_ = prefs_.AddExtensionAndReturnId("4");
    446 
    447     // Set info for two extensions, then remove it.
    448     SetIdleInfo(id1_, 1);
    449     SetIdleInfo(id2_, 2);
    450     VerifyIdleInfo(id1_, 1);
    451     VerifyIdleInfo(id2_, 2);
    452     std::set<std::string> ids = prefs()->GetIdleInstallInfoIds();
    453     EXPECT_EQ(2u, ids.size());
    454     EXPECT_TRUE(ContainsKey(ids, id1_));
    455     EXPECT_TRUE(ContainsKey(ids, id2_));
    456     prefs()->RemoveIdleInstallInfo(id1_);
    457     prefs()->RemoveIdleInstallInfo(id2_);
    458     ids = prefs()->GetIdleInstallInfoIds();
    459     EXPECT_TRUE(ids.empty());
    460 
    461     // Try getting/removing info for an id that used to have info set.
    462     EXPECT_FALSE(prefs()->GetIdleInstallInfo(id1_, NULL, NULL, NULL));
    463     EXPECT_FALSE(prefs()->RemoveIdleInstallInfo(id1_));
    464 
    465     // Try getting/removing info for an id that has not yet had any info set.
    466     EXPECT_FALSE(prefs()->GetIdleInstallInfo(id3_, NULL, NULL, NULL));
    467     EXPECT_FALSE(prefs()->RemoveIdleInstallInfo(id3_));
    468 
    469     // Set info for 4 extensions, then remove for one of them.
    470     SetIdleInfo(id1_, 1);
    471     SetIdleInfo(id2_, 2);
    472     SetIdleInfo(id3_, 3);
    473     SetIdleInfo(id4_, 4);
    474     VerifyIdleInfo(id1_, 1);
    475     VerifyIdleInfo(id2_, 2);
    476     VerifyIdleInfo(id3_, 3);
    477     VerifyIdleInfo(id4_, 4);
    478     prefs()->RemoveIdleInstallInfo(id3_);
    479   }
    480 
    481   virtual void Verify() {
    482     // Make sure the info for the 3 extensions we expect is present.
    483     std::set<std::string> ids = prefs()->GetIdleInstallInfoIds();
    484     EXPECT_EQ(3u, ids.size());
    485     EXPECT_TRUE(ContainsKey(ids, id1_));
    486     EXPECT_TRUE(ContainsKey(ids, id2_));
    487     EXPECT_TRUE(ContainsKey(ids, id4_));
    488     VerifyIdleInfo(id1_, 1);
    489     VerifyIdleInfo(id2_, 2);
    490     VerifyIdleInfo(id4_, 4);
    491 
    492     // Make sure there isn't info the for the one extension id we removed.
    493     EXPECT_FALSE(prefs()->GetIdleInstallInfo(id3_, NULL, NULL, NULL));
    494   }
    495 
    496  protected:
    497   Time now_;
    498   FilePath basedir_;
    499   std::string id1_;
    500   std::string id2_;
    501   std::string id3_;
    502   std::string id4_;
    503 };
    504 TEST_F(ExtensionPrefsIdleInstallInfo, IdleInstallInfo) {}
    505 
    506 class ExtensionPrefsOnExtensionInstalled : public ExtensionPrefsTest {
    507  public:
    508   virtual void Initialize() {
    509     extension_ = prefs_.AddExtension("on_extension_installed");
    510     EXPECT_EQ(Extension::ENABLED,
    511               prefs()->GetExtensionState(extension_->id()));
    512     EXPECT_FALSE(prefs()->IsIncognitoEnabled(extension_->id()));
    513     prefs()->OnExtensionInstalled(extension_.get(),
    514                                   Extension::DISABLED, true);
    515   }
    516 
    517   virtual void Verify() {
    518     EXPECT_EQ(Extension::DISABLED,
    519               prefs()->GetExtensionState(extension_->id()));
    520     EXPECT_TRUE(prefs()->IsIncognitoEnabled(extension_->id()));
    521   }
    522 
    523  private:
    524   scoped_refptr<Extension> extension_;
    525 };
    526 TEST_F(ExtensionPrefsOnExtensionInstalled,
    527        ExtensionPrefsOnExtensionInstalled) {}
    528 
    529 class ExtensionPrefsAppLaunchIndex : public ExtensionPrefsTest {
    530  public:
    531   virtual void Initialize() {
    532     // No extensions yet.
    533     EXPECT_EQ(0, prefs()->GetNextAppLaunchIndex());
    534 
    535     extension_ = prefs_.AddExtension("on_extension_installed");
    536     EXPECT_EQ(Extension::ENABLED,
    537         prefs()->GetExtensionState(extension_->id()));
    538     prefs()->OnExtensionInstalled(extension_.get(),
    539         Extension::ENABLED, false);
    540   }
    541 
    542   virtual void Verify() {
    543     int launch_index = prefs()->GetAppLaunchIndex(extension_->id());
    544     // Extension should have been assigned a launch index > 0.
    545     EXPECT_GT(launch_index, 0);
    546     EXPECT_EQ(launch_index + 1, prefs()->GetNextAppLaunchIndex());
    547     // Set a new launch index of one higher and verify.
    548     prefs()->SetAppLaunchIndex(extension_->id(),
    549         prefs()->GetNextAppLaunchIndex());
    550     int new_launch_index = prefs()->GetAppLaunchIndex(extension_->id());
    551     EXPECT_EQ(launch_index + 1, new_launch_index);
    552 
    553     // This extension doesn't exist, so it should return -1.
    554     EXPECT_EQ(-1, prefs()->GetAppLaunchIndex("foo"));
    555   }
    556 
    557  private:
    558   scoped_refptr<Extension> extension_;
    559 };
    560 TEST_F(ExtensionPrefsAppLaunchIndex, ExtensionPrefsAppLaunchIndex) {}
    561 
    562 class ExtensionPrefsPageIndex : public ExtensionPrefsTest {
    563  public:
    564   virtual void Initialize() {
    565     extension_id_ = prefs_.AddExtensionAndReturnId("page_index");
    566 
    567     int page_index = prefs()->GetPageIndex(extension_id_);
    568     // Extension should not have been assigned a page
    569     EXPECT_EQ(page_index, -1);
    570 
    571     // Set the page index
    572     prefs()->SetPageIndex(extension_id_, 2);
    573   }
    574 
    575   virtual void Verify() {
    576     // Verify the page index.
    577     int page_index = prefs()->GetPageIndex(extension_id_);
    578     EXPECT_EQ(page_index, 2);
    579 
    580     // This extension doesn't exist, so it should return -1.
    581     EXPECT_EQ(-1, prefs()->GetPageIndex("foo"));
    582   }
    583 
    584  private:
    585   std::string extension_id_;
    586 };
    587 TEST_F(ExtensionPrefsPageIndex, ExtensionPrefsPageIndex) {}
    588 
    589 class ExtensionPrefsAppDraggedByUser : public ExtensionPrefsTest {
    590  public:
    591   virtual void Initialize() {
    592     extension_ = prefs_.AddExtension("on_extension_installed");
    593     EXPECT_FALSE(prefs()->WasAppDraggedByUser(extension_->id()));
    594     prefs()->OnExtensionInstalled(extension_.get(),
    595         Extension::ENABLED, false);
    596   }
    597 
    598   virtual void Verify() {
    599     // Set the flag and see if it persisted.
    600     prefs()->SetAppDraggedByUser(extension_->id());
    601     EXPECT_TRUE(prefs()->WasAppDraggedByUser(extension_->id()));
    602 
    603     // Make sure it doesn't change on consecutive calls.
    604     prefs()->SetAppDraggedByUser(extension_->id());
    605     EXPECT_TRUE(prefs()->WasAppDraggedByUser(extension_->id()));
    606   }
    607 
    608  private:
    609   scoped_refptr<Extension> extension_;
    610 };
    611 TEST_F(ExtensionPrefsAppDraggedByUser, ExtensionPrefsAppDraggedByUser) {}
    612 
    613 namespace keys = extension_manifest_keys;
    614 
    615 // Tests that we gracefully handle changes in the ID generation function for
    616 // unpacked extensions.
    617 class ExtensionPrefsIdChange : public ExtensionPrefsTest {
    618  public:
    619   virtual void Initialize() {
    620     DictionaryValue manifest;
    621     manifest.SetString(keys::kVersion, "1.0.0.0");
    622     manifest.SetString(keys::kName, "unused");
    623 
    624     extension_ = prefs_.AddExtensionWithManifest(
    625         manifest, Extension::LOAD);
    626     extension_id_ = extension_->id();
    627 
    628     DictionaryPrefUpdate extensions_dict_update(
    629         prefs()->pref_service(), ExtensionPrefs::kExtensionsPref);
    630 
    631     Value* extension_prefs;
    632     ASSERT_TRUE(extensions_dict_update->RemoveWithoutPathExpansion(
    633         extension_id_, &extension_prefs));
    634     extensions_dict_update->SetWithoutPathExpansion(
    635         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", extension_prefs);
    636   }
    637 
    638   virtual void Verify() {
    639     prefs_.RecreateExtensionPrefs();
    640     prefs()->SetExtensionState(extension_.get(), Extension::DISABLED);
    641     ExtensionPrefs::ExtensionIdSet extension_ids;
    642     prefs()->GetExtensions(&extension_ids);
    643     EXPECT_EQ(1U, extension_ids.size());
    644     EXPECT_EQ(extension_id_, extension_ids[0]);
    645   }
    646 
    647  private:
    648   scoped_refptr<Extension> extension_;
    649   std::string extension_id_;
    650 };
    651 TEST_F(ExtensionPrefsIdChange, IdChange) {}
    652 
    653 class ExtensionPrefsPreferencesBase : public ExtensionPrefsTest {
    654  public:
    655   ExtensionPrefsPreferencesBase()
    656       : ExtensionPrefsTest(),
    657         ext1_(NULL),
    658         ext2_(NULL),
    659         ext3_(NULL),
    660         installed() {
    661     DictionaryValue simple_dict;
    662     std::string error;
    663 
    664     simple_dict.SetString(keys::kVersion, "1.0.0.0");
    665     simple_dict.SetString(keys::kName, "unused");
    666 
    667     ext1_scoped_ = Extension::Create(
    668         prefs_.temp_dir().AppendASCII("ext1_"), Extension::EXTERNAL_PREF,
    669         simple_dict, Extension::STRICT_ERROR_CHECKS, &error);
    670     ext2_scoped_ = Extension::Create(
    671         prefs_.temp_dir().AppendASCII("ext2_"), Extension::EXTERNAL_PREF,
    672         simple_dict, Extension::STRICT_ERROR_CHECKS, &error);
    673     ext3_scoped_ = Extension::Create(
    674         prefs_.temp_dir().AppendASCII("ext3_"), Extension::EXTERNAL_PREF,
    675         simple_dict, Extension::STRICT_ERROR_CHECKS, &error);
    676 
    677     ext1_ = ext1_scoped_.get();
    678     ext2_ = ext2_scoped_.get();
    679     ext3_ = ext3_scoped_.get();
    680 
    681     for (size_t i = 0; i < arraysize(installed); ++i)
    682       installed[i] = false;
    683   }
    684 
    685   void RegisterPreferences() {
    686     prefs()->pref_service()->RegisterStringPref(kPref1, kDefaultPref1);
    687     prefs()->pref_service()->RegisterStringPref(kPref2, kDefaultPref2);
    688     prefs()->pref_service()->RegisterStringPref(kPref3, kDefaultPref3);
    689     prefs()->pref_service()->RegisterStringPref(kPref4, kDefaultPref4);
    690   }
    691 
    692   void InstallExtControlledPref(Extension *ext,
    693                                 const std::string& key,
    694                                 Value* val) {
    695     EnsureExtensionInstalled(ext);
    696     prefs()->SetExtensionControlledPref(ext->id(), key, false, val);
    697   }
    698 
    699   void InstallExtControlledPrefIncognito(Extension *ext,
    700                                          const std::string& key,
    701                                          Value* val) {
    702     EnsureExtensionInstalled(ext);
    703     prefs()->SetExtensionControlledPref(ext->id(), key, true, val);
    704   }
    705 
    706   void InstallExtension(Extension *ext) {
    707     EnsureExtensionInstalled(ext);
    708   }
    709 
    710   void UninstallExtension(const std::string& extension_id) {
    711     EnsureExtensionUninstalled(extension_id);
    712   }
    713 
    714   // Weak references, for convenience.
    715   Extension* ext1_;
    716   Extension* ext2_;
    717   Extension* ext3_;
    718 
    719   // Flags indicating whether each of the extensions has been installed, yet.
    720   bool installed[3];
    721 
    722  private:
    723   void EnsureExtensionInstalled(Extension *ext) {
    724     // Install extension the first time a preference is set for it.
    725     Extension* extensions[] = {ext1_, ext2_, ext3_};
    726     for (int i = 0; i < 3; ++i) {
    727       if (ext == extensions[i] && !installed[i]) {
    728         prefs()->OnExtensionInstalled(ext, Extension::ENABLED, true);
    729         installed[i] = true;
    730         break;
    731       }
    732     }
    733   }
    734 
    735   void EnsureExtensionUninstalled(const std::string& extension_id) {
    736     Extension* extensions[] = {ext1_, ext2_, ext3_};
    737     for (int i = 0; i < 3; ++i) {
    738       if (extensions[i]->id() == extension_id) {
    739         installed[i] = false;
    740         break;
    741       }
    742     }
    743     prefs()->OnExtensionUninstalled(extension_id, Extension::INTERNAL, false);
    744   }
    745 
    746   scoped_refptr<Extension> ext1_scoped_;
    747   scoped_refptr<Extension> ext2_scoped_;
    748   scoped_refptr<Extension> ext3_scoped_;
    749 };
    750 
    751 class ExtensionPrefsInstallOneExtension
    752     : public ExtensionPrefsPreferencesBase {
    753   virtual void Initialize() {
    754     InstallExtControlledPref(ext1_, kPref1, Value::CreateStringValue("val1"));
    755   }
    756   virtual void Verify() {
    757     std::string actual = prefs()->pref_service()->GetString(kPref1);
    758     EXPECT_EQ("val1", actual);
    759   }
    760 };
    761 TEST_F(ExtensionPrefsInstallOneExtension, ExtensionPrefsInstallOneExtension) {}
    762 
    763 // Check that we forget incognito values after a reload.
    764 class ExtensionPrefsInstallIncognito
    765     : public ExtensionPrefsPreferencesBase {
    766  public:
    767   ExtensionPrefsInstallIncognito() : iteration_(0) {}
    768 
    769   virtual void Initialize() {
    770     InstallExtControlledPref(ext1_, kPref1, Value::CreateStringValue("val1"));
    771     InstallExtControlledPrefIncognito(ext1_, kPref1,
    772                                       Value::CreateStringValue("val2"));
    773     scoped_ptr<PrefService> incog_prefs(prefs_.CreateIncognitoPrefService());
    774     std::string actual = incog_prefs->GetString(kPref1);
    775     EXPECT_EQ("val2", actual);
    776   }
    777   virtual void Verify() {
    778     // Main pref service shall see only non-incognito settings.
    779     std::string actual = prefs()->pref_service()->GetString(kPref1);
    780     EXPECT_EQ("val1", actual);
    781     // Incognito pref service shall see incognito values only during first run.
    782     // Once the pref service was reloaded, all values shall be discarded.
    783     scoped_ptr<PrefService> incog_prefs(prefs_.CreateIncognitoPrefService());
    784     actual = incog_prefs->GetString(kPref1);
    785     if (iteration_ == 0) {
    786       EXPECT_EQ("val2", actual);
    787     } else {
    788       EXPECT_EQ("val1", actual);
    789     }
    790     ++iteration_;
    791   }
    792   int iteration_;
    793 };
    794 TEST_F(ExtensionPrefsInstallIncognito, ExtensionPrefsInstallOneExtension) {}
    795 
    796 class ExtensionPrefsUninstallExtension
    797     : public ExtensionPrefsPreferencesBase {
    798   virtual void Initialize() {
    799     InstallExtControlledPref(ext1_, kPref1, Value::CreateStringValue("val1"));
    800     InstallExtControlledPref(ext1_, kPref2, Value::CreateStringValue("val2"));
    801 
    802     UninstallExtension(ext1_->id());
    803   }
    804   virtual void Verify() {
    805     std::string actual;
    806     actual = prefs()->pref_service()->GetString(kPref1);
    807     EXPECT_EQ(kDefaultPref1, actual);
    808     actual = prefs()->pref_service()->GetString(kPref2);
    809     EXPECT_EQ(kDefaultPref2, actual);
    810   }
    811 };
    812 TEST_F(ExtensionPrefsUninstallExtension,
    813     ExtensionPrefsUninstallExtension) {}
    814 
    815 // Tests triggering of notifications to registered observers.
    816 class ExtensionPrefsNotifyWhenNeeded
    817     : public ExtensionPrefsPreferencesBase {
    818   virtual void Initialize() {
    819     using testing::_;
    820     using testing::Mock;
    821     using testing::StrEq;
    822 
    823     NotificationObserverMock observer;
    824     PrefChangeRegistrar registrar;
    825     registrar.Init(prefs()->pref_service());
    826     registrar.Add(kPref1, &observer);
    827 
    828     NotificationObserverMock incognito_observer;
    829     scoped_ptr<PrefService> incog_prefs(prefs_.CreateIncognitoPrefService());
    830     PrefChangeRegistrar incognito_registrar;
    831     incognito_registrar.Init(incog_prefs.get());
    832     incognito_registrar.Add(kPref1, &incognito_observer);
    833 
    834     // Write value and check notification.
    835     EXPECT_CALL(observer, Observe(_, _, _));
    836     EXPECT_CALL(incognito_observer, Observe(_, _, _));
    837     InstallExtControlledPref(ext1_, kPref1,
    838         Value::CreateStringValue("https://www.chromium.org"));
    839     Mock::VerifyAndClearExpectations(&observer);
    840     Mock::VerifyAndClearExpectations(&incognito_observer);
    841 
    842     // Write same value.
    843     EXPECT_CALL(observer, Observe(_, _, _)).Times(0);
    844     EXPECT_CALL(incognito_observer, Observe(_, _, _)).Times(0);
    845     InstallExtControlledPref(ext1_, kPref1,
    846         Value::CreateStringValue("https://www.chromium.org"));
    847     Mock::VerifyAndClearExpectations(&observer);
    848     Mock::VerifyAndClearExpectations(&incognito_observer);
    849 
    850     // Change value.
    851     EXPECT_CALL(observer, Observe(_, _, _));
    852     EXPECT_CALL(incognito_observer, Observe(_, _, _));
    853     InstallExtControlledPref(ext1_, kPref1,
    854         Value::CreateStringValue("chrome://newtab"));
    855     Mock::VerifyAndClearExpectations(&observer);
    856     Mock::VerifyAndClearExpectations(&incognito_observer);
    857 
    858     // Change only incognito value.
    859     EXPECT_CALL(observer, Observe(_, _, _)).Times(0);
    860     EXPECT_CALL(incognito_observer, Observe(_, _, _));
    861     InstallExtControlledPrefIncognito(ext1_, kPref1,
    862         Value::CreateStringValue("chrome://newtab2"));
    863     Mock::VerifyAndClearExpectations(&observer);
    864     Mock::VerifyAndClearExpectations(&incognito_observer);
    865 
    866     // Uninstall.
    867     EXPECT_CALL(observer, Observe(_, _, _));
    868     EXPECT_CALL(incognito_observer, Observe(_, _, _));
    869     UninstallExtension(ext1_->id());
    870     Mock::VerifyAndClearExpectations(&observer);
    871     Mock::VerifyAndClearExpectations(&incognito_observer);
    872 
    873     registrar.Remove(kPref1, &observer);
    874     incognito_registrar.Remove(kPref1, &incognito_observer);
    875   }
    876   virtual void Verify() {
    877     std::string actual = prefs()->pref_service()->GetString(kPref1);
    878     EXPECT_EQ(kDefaultPref1, actual);
    879   }
    880 };
    881 TEST_F(ExtensionPrefsNotifyWhenNeeded,
    882     ExtensionPrefsNotifyWhenNeeded) {}
    883 
    884 // Tests disabling an extension.
    885 class ExtensionPrefsDisableExt
    886     : public ExtensionPrefsPreferencesBase {
    887   virtual void Initialize() {
    888     InstallExtControlledPref(ext1_, kPref1, Value::CreateStringValue("val1"));
    889     std::string actual = prefs()->pref_service()->GetString(kPref1);
    890     EXPECT_EQ("val1", actual);
    891     prefs()->SetExtensionState(ext1_, Extension::DISABLED);
    892   }
    893   virtual void Verify() {
    894     std::string actual = prefs()->pref_service()->GetString(kPref1);
    895     EXPECT_EQ(kDefaultPref1, actual);
    896   }
    897 };
    898 TEST_F(ExtensionPrefsDisableExt,  ExtensionPrefsDisableExt) {}
    899 
    900 // Tests disabling and reenabling an extension.
    901 class ExtensionPrefsReenableExt
    902     : public ExtensionPrefsPreferencesBase {
    903   virtual void Initialize() {
    904     InstallExtControlledPref(ext1_, kPref1, Value::CreateStringValue("val1"));
    905     prefs()->SetExtensionState(ext1_, Extension::DISABLED);
    906     prefs()->SetExtensionState(ext1_, Extension::ENABLED);
    907   }
    908   virtual void Verify() {
    909     std::string actual = prefs()->pref_service()->GetString(kPref1);
    910     EXPECT_EQ("val1", actual);
    911   }
    912 };
    913 TEST_F(ExtensionPrefsDisableExt,  ExtensionPrefsReenableExt) {}
    914 
    915 // Mock class to test whether objects are deleted correctly.
    916 class MockStringValue : public StringValue {
    917  public:
    918   explicit MockStringValue(const std::string& in_value)
    919       : StringValue(in_value) {
    920   }
    921   virtual ~MockStringValue() {
    922     Die();
    923   }
    924   MOCK_METHOD0(Die, void());
    925 };
    926 
    927 class ExtensionPrefsSetExtensionControlledPref
    928     : public ExtensionPrefsPreferencesBase {
    929  public:
    930   virtual void Initialize() {
    931     MockStringValue* v1 = new MockStringValue("https://www.chromium.org");
    932     MockStringValue* v2 = new MockStringValue("https://www.chromium.org");
    933     MockStringValue* v1i = new MockStringValue("https://www.chromium.org");
    934     MockStringValue* v2i = new MockStringValue("https://www.chromium.org");
    935     // Ownership is taken, value shall not be deleted.
    936     EXPECT_CALL(*v1, Die()).Times(0);
    937     EXPECT_CALL(*v1i, Die()).Times(0);
    938     InstallExtControlledPref(ext1_, kPref1, v1);
    939     InstallExtControlledPrefIncognito(ext1_, kPref1, v1i);
    940     testing::Mock::VerifyAndClearExpectations(v1);
    941     testing::Mock::VerifyAndClearExpectations(v1i);
    942     // Make sure there is no memory leak and both values are deleted.
    943     EXPECT_CALL(*v1, Die()).Times(1);
    944     EXPECT_CALL(*v1i, Die()).Times(1);
    945     EXPECT_CALL(*v2, Die()).Times(1);
    946     EXPECT_CALL(*v2i, Die()).Times(1);
    947     InstallExtControlledPref(ext1_, kPref1, v2);
    948     InstallExtControlledPrefIncognito(ext1_, kPref1, v2i);
    949     prefs_.RecreateExtensionPrefs();
    950     testing::Mock::VerifyAndClearExpectations(v1);
    951     testing::Mock::VerifyAndClearExpectations(v1i);
    952     testing::Mock::VerifyAndClearExpectations(v2);
    953     testing::Mock::VerifyAndClearExpectations(v2i);
    954   }
    955 
    956   virtual void Verify() {
    957   }
    958 };
    959 TEST_F(ExtensionPrefsSetExtensionControlledPref,
    960     ExtensionPrefsSetExtensionControlledPref) {}
    961