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