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 "base/basictypes.h"
      6 #include "base/memory/ref_counted.h"
      7 #include "base/memory/scoped_ptr.h"
      8 #include "base/prefs/pref_store_observer_mock.h"
      9 #include "base/values.h"
     10 #include "chrome/browser/extensions/extension_pref_value_map.h"
     11 #include "testing/gmock/include/gmock/gmock.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 
     14 namespace {
     15 const char kExt1[] = "ext1";
     16 const char kExt2[] = "ext2";
     17 const char kExt3[] = "ext3";
     18 
     19 const char kPref1[] = "path1.subpath";
     20 const char kPref2[] = "path2";
     21 const char kPref3[] = "path3";
     22 const char kPref4[] = "path4";
     23 }  // namespace
     24 
     25 static Value* CreateVal(const char* str) {
     26   return Value::CreateStringValue(str);
     27 }
     28 
     29 static base::Time CreateTime(int64 t) {
     30   return base::Time::FromInternalValue(t);
     31 }
     32 
     33 template <typename BASECLASS>
     34 class ExtensionPrefValueMapTestBase : public BASECLASS {
     35  public:
     36   static const extensions::ExtensionPrefsScope kRegular =
     37       extensions::kExtensionPrefsScopeRegular;
     38   static const extensions::ExtensionPrefsScope kRegularOnly =
     39       extensions::kExtensionPrefsScopeRegularOnly;
     40   static const extensions::ExtensionPrefsScope kIncognitoPersistent =
     41       extensions::kExtensionPrefsScopeIncognitoPersistent;
     42   static const extensions::ExtensionPrefsScope kIncognitoSessionOnly =
     43       extensions::kExtensionPrefsScopeIncognitoSessionOnly;
     44 
     45   // Returns an empty string if the key is not set.
     46   std::string GetValue(const char * key, bool incognito) const {
     47     const Value *value = epvm_.GetEffectivePrefValue(key, incognito, NULL);
     48     std::string string_value;
     49     if (value)
     50       value->GetAsString(&string_value);
     51     return string_value;
     52   }
     53 
     54  protected:
     55   ExtensionPrefValueMap epvm_;
     56 };
     57 
     58 class ExtensionPrefValueMapTest
     59     : public ExtensionPrefValueMapTestBase<testing::Test> {
     60 };
     61 
     62 // A gmock-ified implementation of PrefStore::Observer.
     63 class ExtensionPrefValueMapObserverMock
     64     : public ExtensionPrefValueMap::Observer {
     65  public:
     66   ExtensionPrefValueMapObserverMock() {}
     67   virtual ~ExtensionPrefValueMapObserverMock() {}
     68 
     69   MOCK_METHOD1(OnPrefValueChanged, void(const std::string&));
     70   MOCK_METHOD0(OnInitializationCompleted, void());
     71   MOCK_METHOD0(OnExtensionPrefValueMapDestruction, void());
     72 
     73  private:
     74   DISALLOW_COPY_AND_ASSIGN(ExtensionPrefValueMapObserverMock);
     75 };
     76 
     77 TEST_F(ExtensionPrefValueMapTest, SetAndGetPrefValue) {
     78   epvm_.RegisterExtension(kExt1, CreateTime(10), true);
     79   epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val1"));
     80   EXPECT_EQ("val1", GetValue(kPref1, false));
     81 };
     82 
     83 TEST_F(ExtensionPrefValueMapTest, GetNotSetPrefValue) {
     84   epvm_.RegisterExtension(kExt1, CreateTime(10), true);
     85   EXPECT_EQ("", GetValue(kPref1, false));
     86 };
     87 
     88 // Make sure the last-installed extension wins for each preference.
     89 TEST_F(ExtensionPrefValueMapTest, Override) {
     90   epvm_.RegisterExtension(kExt1, CreateTime(10), true);
     91   epvm_.RegisterExtension(kExt2, CreateTime(20), true);
     92   epvm_.RegisterExtension(kExt3, CreateTime(30), true);
     93 
     94   epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val1"));
     95   epvm_.SetExtensionPref(kExt2, kPref1, kRegular, CreateVal("val2"));
     96   epvm_.SetExtensionPref(kExt3, kPref1, kRegular, CreateVal("val3"));
     97 
     98   epvm_.SetExtensionPref(kExt1, kPref2, kRegular, CreateVal("val4"));
     99   epvm_.SetExtensionPref(kExt2, kPref2, kRegular, CreateVal("val5"));
    100 
    101   epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val6"));
    102   epvm_.SetExtensionPref(kExt1, kPref2, kRegular, CreateVal("val7"));
    103   epvm_.SetExtensionPref(kExt1, kPref3, kRegular, CreateVal("val8"));
    104 
    105   EXPECT_EQ("val3", GetValue(kPref1, false));
    106   EXPECT_EQ("val5", GetValue(kPref2, false));
    107   EXPECT_EQ("val8", GetValue(kPref3, false));
    108 }
    109 
    110 TEST_F(ExtensionPrefValueMapTest, OverrideChecks) {
    111   epvm_.RegisterExtension(kExt1, CreateTime(10), true);
    112   epvm_.RegisterExtension(kExt2, CreateTime(20), true);
    113   epvm_.RegisterExtension(kExt3, CreateTime(30), true);
    114 
    115   EXPECT_FALSE(epvm_.DoesExtensionControlPref(kExt1, kPref1, NULL));
    116   EXPECT_FALSE(epvm_.DoesExtensionControlPref(kExt2, kPref1, NULL));
    117   EXPECT_FALSE(epvm_.DoesExtensionControlPref(kExt3, kPref1, NULL));
    118   EXPECT_TRUE(epvm_.CanExtensionControlPref(kExt1, kPref1, false));
    119   EXPECT_TRUE(epvm_.CanExtensionControlPref(kExt2, kPref1, false));
    120   EXPECT_TRUE(epvm_.CanExtensionControlPref(kExt3, kPref1, false));
    121 
    122   epvm_.SetExtensionPref(kExt2, kPref1, kRegular, CreateVal("val1"));
    123 
    124   EXPECT_FALSE(epvm_.DoesExtensionControlPref(kExt1, kPref1, NULL));
    125   EXPECT_TRUE(epvm_.DoesExtensionControlPref(kExt2, kPref1, NULL));
    126   EXPECT_FALSE(epvm_.DoesExtensionControlPref(kExt3, kPref1, NULL));
    127   EXPECT_FALSE(epvm_.CanExtensionControlPref(kExt1, kPref1, false));
    128   EXPECT_TRUE(epvm_.CanExtensionControlPref(kExt2, kPref1, false));
    129   EXPECT_TRUE(epvm_.CanExtensionControlPref(kExt3, kPref1, false));
    130 }
    131 
    132 TEST_F(ExtensionPrefValueMapTest, SetAndGetPrefValueIncognito) {
    133   epvm_.RegisterExtension(kExt1, CreateTime(10), true);
    134   epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val1"));
    135   EXPECT_EQ("val1", GetValue(kPref1, true));
    136 }
    137 
    138 TEST_F(ExtensionPrefValueMapTest, UninstallOnlyExtension) {
    139   epvm_.RegisterExtension(kExt1, CreateTime(10), true);
    140   epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val1"));
    141   epvm_.UnregisterExtension(kExt1);
    142 
    143   EXPECT_EQ("", GetValue(kPref1, false));
    144 }
    145 
    146 // Tests uninstalling an extension that wasn't winning for any preferences.
    147 TEST_F(ExtensionPrefValueMapTest, UninstallIrrelevantExtension) {
    148   epvm_.RegisterExtension(kExt1, CreateTime(10), true);
    149   epvm_.RegisterExtension(kExt2, CreateTime(10), true);
    150 
    151   epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val1"));
    152   epvm_.SetExtensionPref(kExt2, kPref1, kRegular, CreateVal("val2"));
    153 
    154   epvm_.SetExtensionPref(kExt1, kPref2, kRegular, CreateVal("val3"));
    155   epvm_.SetExtensionPref(kExt2, kPref2, kRegular, CreateVal("val4"));
    156 
    157   epvm_.UnregisterExtension(kExt1);
    158 
    159   EXPECT_EQ("val2", GetValue(kPref1, false));
    160   EXPECT_EQ("val4", GetValue(kPref2, false));
    161 }
    162 
    163 // Tests uninstalling an extension that was winning for all preferences.
    164 TEST_F(ExtensionPrefValueMapTest, UninstallExtensionFromTop) {
    165   epvm_.RegisterExtension(kExt1, CreateTime(10), true);
    166   epvm_.RegisterExtension(kExt2, CreateTime(20), true);
    167   epvm_.RegisterExtension(kExt3, CreateTime(30), true);
    168 
    169   epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val1"));
    170   epvm_.SetExtensionPref(kExt2, kPref1, kRegular, CreateVal("val2"));
    171   epvm_.SetExtensionPref(kExt3, kPref1, kRegular, CreateVal("val3"));
    172 
    173   epvm_.SetExtensionPref(kExt1, kPref2, kRegular, CreateVal("val4"));
    174   epvm_.SetExtensionPref(kExt3, kPref2, kRegular, CreateVal("val5"));
    175 
    176   epvm_.UnregisterExtension(kExt3);
    177 
    178   EXPECT_EQ("val2", GetValue(kPref1, false));
    179   EXPECT_EQ("val4", GetValue(kPref2, false));
    180 }
    181 
    182 // Tests uninstalling an extension that was winning for only some preferences.
    183 TEST_F(ExtensionPrefValueMapTest, UninstallExtensionFromMiddle) {
    184   epvm_.RegisterExtension(kExt1, CreateTime(10), true);
    185   epvm_.RegisterExtension(kExt2, CreateTime(20), true);
    186   epvm_.RegisterExtension(kExt3, CreateTime(30), true);
    187 
    188   epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val1"));
    189   epvm_.SetExtensionPref(kExt2, kPref1, kRegular, CreateVal("val2"));
    190   epvm_.SetExtensionPref(kExt3, kPref1, kRegular, CreateVal("val3"));
    191 
    192   epvm_.SetExtensionPref(kExt1, kPref2, kRegular, CreateVal("val4"));
    193   epvm_.SetExtensionPref(kExt2, kPref2, kRegular, CreateVal("val5"));
    194 
    195   epvm_.SetExtensionPref(kExt1, kPref3, kRegular, CreateVal("val6"));
    196 
    197   epvm_.SetExtensionPref(kExt2, kPref4, kRegular, CreateVal("val7"));
    198 
    199   epvm_.UnregisterExtension(kExt2);
    200 
    201   EXPECT_EQ("val3", GetValue(kPref1, false));
    202   EXPECT_EQ("val4", GetValue(kPref2, false));
    203   EXPECT_EQ("val6", GetValue(kPref3, false));
    204   EXPECT_EQ("", GetValue(kPref4, false));
    205 }
    206 
    207 // Tests triggering of notifications to registered observers.
    208 TEST_F(ExtensionPrefValueMapTest, NotifyWhenNeeded) {
    209   using testing::_;
    210   using testing::Mock;
    211   using testing::StrEq;
    212 
    213   epvm_.RegisterExtension(kExt1, CreateTime(10), true);
    214 
    215   ExtensionPrefValueMapObserverMock observer;
    216   epvm_.AddObserver(&observer);
    217 
    218   EXPECT_CALL(observer, OnPrefValueChanged(std::string(kPref1)));
    219   epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val1"));
    220   Mock::VerifyAndClearExpectations(&observer);
    221 
    222   // Write the same value again.
    223   EXPECT_CALL(observer, OnPrefValueChanged(std::string(kPref1))).Times(0);
    224   epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val1"));
    225   Mock::VerifyAndClearExpectations(&observer);
    226 
    227   // Override incognito value.
    228   EXPECT_CALL(observer, OnPrefValueChanged(std::string(kPref1)));
    229   epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val2"));
    230   Mock::VerifyAndClearExpectations(&observer);
    231 
    232   // Override non-incognito value.
    233   EXPECT_CALL(observer, OnPrefValueChanged(std::string(kPref1)));
    234   epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val3"));
    235   Mock::VerifyAndClearExpectations(&observer);
    236 
    237   // Disable.
    238   EXPECT_CALL(observer, OnPrefValueChanged(std::string(kPref1)));
    239   epvm_.SetExtensionState(kExt1, false);
    240   Mock::VerifyAndClearExpectations(&observer);
    241 
    242   // Enable.
    243   EXPECT_CALL(observer, OnPrefValueChanged(std::string(kPref1)));
    244   epvm_.SetExtensionState(kExt1, true);
    245   Mock::VerifyAndClearExpectations(&observer);
    246 
    247   // Uninstall
    248   EXPECT_CALL(observer, OnPrefValueChanged(std::string(kPref1)));
    249   epvm_.UnregisterExtension(kExt1);
    250   Mock::VerifyAndClearExpectations(&observer);
    251 
    252   epvm_.RemoveObserver(&observer);
    253 
    254   // Write new value --> no notification after removing observer.
    255   EXPECT_CALL(observer, OnPrefValueChanged(std::string(kPref1))).Times(0);
    256   epvm_.RegisterExtension(kExt1, CreateTime(10), true);
    257   epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val4"));
    258   Mock::VerifyAndClearExpectations(&observer);
    259 }
    260 
    261 // Tests disabling an extension.
    262 TEST_F(ExtensionPrefValueMapTest, DisableExt) {
    263   epvm_.RegisterExtension(kExt1, CreateTime(10), true);
    264 
    265   epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val1"));
    266   epvm_.SetExtensionState(kExt1, false);
    267   EXPECT_EQ("", GetValue(kPref1, false));
    268 }
    269 
    270 // Tests disabling and reenabling an extension.
    271 TEST_F(ExtensionPrefValueMapTest, ReenableExt) {
    272   epvm_.RegisterExtension(kExt1, CreateTime(10), true);
    273 
    274   epvm_.SetExtensionPref(kExt1, kPref1, kRegular, CreateVal("val1"));
    275   epvm_.SetExtensionState(kExt1, false);
    276   epvm_.SetExtensionState(kExt1, true);
    277   EXPECT_EQ("val1", GetValue(kPref1, false));
    278 }
    279 
    280 struct OverrideIncognitoTestCase {
    281   OverrideIncognitoTestCase(int val_ext1_regular,
    282                             int val_ext1_regular_only,
    283                             int val_ext1_incognito_pers,
    284                             int val_ext1_incognito_sess,
    285                             int val_ext2_regular,
    286                             int val_ext2_regular_only,
    287                             int val_ext2_incognito_pers,
    288                             int val_ext2_incognito_sess,
    289                             int effective_value_regular,
    290                             int effective_value_incognito)
    291       : val_ext1_regular_(val_ext1_regular),
    292         val_ext1_regular_only_(val_ext1_regular_only),
    293         val_ext1_incognito_pers_(val_ext1_incognito_pers),
    294         val_ext1_incognito_sess_(val_ext1_incognito_sess),
    295         val_ext2_regular_(val_ext2_regular),
    296         val_ext2_regular_only_(val_ext2_regular_only),
    297         val_ext2_incognito_pers_(val_ext2_incognito_pers),
    298         val_ext2_incognito_sess_(val_ext2_incognito_sess),
    299         effective_value_regular_(effective_value_regular),
    300         effective_value_incognito_(effective_value_incognito) {}
    301 
    302   // pers. = persistent
    303   // sess. = session only
    304   int val_ext1_regular_;           // pref value of extension 1
    305   int val_ext1_regular_only_;      // pref value of extension 1 regular-only.
    306   int val_ext1_incognito_pers_;    // pref value of extension 1 incognito pers.
    307   int val_ext1_incognito_sess_;    // pref value of extension 1 incognito sess.
    308   int val_ext2_regular_;           // pref value of extension 2
    309   int val_ext2_regular_only_;      // pref value of extension 2 regular-only.
    310   int val_ext2_incognito_pers_;    // pref value of extension 2 incognito pers.
    311   int val_ext2_incognito_sess_;    // pref value of extension 2 incognito sess.
    312   int effective_value_regular_;    // desired winner regular
    313   int effective_value_incognito_;  // desired winner incognito
    314 };
    315 
    316 class ExtensionPrefValueMapTestIncognitoTests
    317     : public ExtensionPrefValueMapTestBase<
    318           testing::TestWithParam<OverrideIncognitoTestCase> > {
    319 };
    320 
    321 TEST_P(ExtensionPrefValueMapTestIncognitoTests, OverrideIncognito) {
    322   OverrideIncognitoTestCase test = GetParam();
    323   const char* strings[] = {
    324       "undefined",
    325       "val1",
    326       "val2",
    327       "val3",
    328       "val4",
    329       "val5",
    330       "val6",
    331       "val7",
    332       "val8",
    333   };
    334 
    335   epvm_.RegisterExtension(kExt1, CreateTime(10), true);
    336   epvm_.RegisterExtension(kExt2, CreateTime(20), true);
    337   if (test.val_ext1_regular_) {
    338     epvm_.SetExtensionPref(kExt1, kPref1, kRegular,
    339                            CreateVal(strings[test.val_ext1_regular_]));
    340   }
    341   if (test.val_ext1_regular_only_) {
    342     epvm_.SetExtensionPref(kExt1, kPref1, kRegularOnly,
    343                            CreateVal(strings[test.val_ext1_regular_only_]));
    344   }
    345   if (test.val_ext1_incognito_pers_) {
    346     epvm_.SetExtensionPref(kExt1, kPref1, kIncognitoPersistent,
    347                            CreateVal(strings[test.val_ext1_incognito_pers_]));
    348   }
    349   if (test.val_ext1_incognito_sess_) {
    350     epvm_.SetExtensionPref(kExt1, kPref1, kIncognitoSessionOnly,
    351                            CreateVal(strings[test.val_ext1_incognito_sess_]));
    352   }
    353   if (test.val_ext2_regular_) {
    354     epvm_.SetExtensionPref(kExt2, kPref1, kRegular,
    355                            CreateVal(strings[test.val_ext2_regular_]));
    356   }
    357   if (test.val_ext2_regular_only_) {
    358     epvm_.SetExtensionPref(kExt2, kPref1, kRegularOnly,
    359                            CreateVal(strings[test.val_ext2_regular_only_]));
    360   }
    361   if (test.val_ext2_incognito_pers_) {
    362     epvm_.SetExtensionPref(kExt2, kPref1, kIncognitoPersistent,
    363                            CreateVal(strings[test.val_ext2_incognito_pers_]));
    364   }
    365   if (test.val_ext2_incognito_sess_) {
    366     epvm_.SetExtensionPref(kExt2, kPref1, kIncognitoSessionOnly,
    367                            CreateVal(strings[test.val_ext2_incognito_sess_]));
    368   }
    369   std::string actual;
    370   EXPECT_EQ(strings[test.effective_value_regular_], GetValue(kPref1, false));
    371   EXPECT_EQ(strings[test.effective_value_incognito_], GetValue(kPref1, true));
    372   epvm_.UnregisterExtension(kExt1);
    373   epvm_.UnregisterExtension(kExt2);
    374 }
    375 
    376 INSTANTIATE_TEST_CASE_P(
    377     ExtensionPrefValueMapTestIncognitoTestsInstance,
    378     ExtensionPrefValueMapTestIncognitoTests,
    379     testing::Values(
    380         // e.g. (1, 0, 0, 0,  0, 0, 7, 0,  1, 7), means:
    381         // ext1 regular is set to "val1", ext2 incognito persistent is set to
    382         // "val7"
    383         // --> the winning regular value is "val1", the winning incognito
    384         //     value is "val7".
    385         OverrideIncognitoTestCase(1, 0, 0, 0,  0, 0, 0, 0,  1, 1),
    386         OverrideIncognitoTestCase(1, 2, 0, 0,  0, 0, 0, 0,  2, 1),
    387         OverrideIncognitoTestCase(1, 0, 3, 0,  0, 0, 0, 0,  1, 3),
    388         OverrideIncognitoTestCase(1, 0, 0, 4,  0, 0, 0, 0,  1, 4),
    389         OverrideIncognitoTestCase(1, 0, 3, 4,  0, 0, 0, 0,  1, 4),
    390         OverrideIncognitoTestCase(1, 2, 3, 0,  0, 0, 0, 0,  2, 3),
    391         OverrideIncognitoTestCase(1, 0, 0, 0,  5, 0, 0, 0,  5, 5),
    392         OverrideIncognitoTestCase(1, 2, 3, 0,  5, 0, 0, 0,  5, 5),
    393         OverrideIncognitoTestCase(1, 0, 0, 0,  0, 6, 0, 0,  6, 1),
    394         OverrideIncognitoTestCase(1, 0, 3, 0,  5, 6, 0, 0,  6, 5),
    395         OverrideIncognitoTestCase(1, 0, 0, 4,  5, 6, 0, 0,  6, 5),
    396         OverrideIncognitoTestCase(1, 0, 0, 0,  0, 0, 7, 0,  1, 7),
    397         OverrideIncognitoTestCase(1, 2, 0, 0,  5, 0, 7, 0,  5, 7),
    398         OverrideIncognitoTestCase(1, 2, 0, 0,  5, 0, 0, 8,  5, 8),
    399         OverrideIncognitoTestCase(1, 2, 0, 0,  5, 0, 7, 8,  5, 8),
    400         OverrideIncognitoTestCase(1, 2, 3, 0,  0, 6, 7, 0,  6, 7)));
    401