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