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