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 "chrome/browser/extensions/extension_prefs_unittest.h" 6 7 #include "base/basictypes.h" 8 #include "base/files/scoped_temp_dir.h" 9 #include "base/path_service.h" 10 #include "base/prefs/mock_pref_change_callback.h" 11 #include "base/prefs/pref_change_registrar.h" 12 #include "base/prefs/scoped_user_pref_update.h" 13 #include "base/stl_util.h" 14 #include "base/strings/string_number_conversions.h" 15 #include "base/strings/stringprintf.h" 16 #include "base/values.h" 17 #include "chrome/browser/extensions/extension_pref_value_map.h" 18 #include "chrome/browser/extensions/extension_prefs.h" 19 #include "chrome/browser/prefs/pref_service_syncable.h" 20 #include "chrome/common/chrome_paths.h" 21 #include "components/user_prefs/pref_registry_syncable.h" 22 #include "content/public/browser/notification_details.h" 23 #include "content/public/browser/notification_source.h" 24 #include "content/public/test/mock_notification_observer.h" 25 #include "extensions/common/extension.h" 26 #include "extensions/common/manifest_constants.h" 27 #include "extensions/common/permissions/permission_set.h" 28 #include "extensions/common/permissions/permissions_info.h" 29 #include "sync/api/string_ordinal.h" 30 31 using base::Time; 32 using base::TimeDelta; 33 using content::BrowserThread; 34 35 namespace extensions { 36 37 static void AddPattern(URLPatternSet* extent, const std::string& pattern) { 38 int schemes = URLPattern::SCHEME_ALL; 39 extent->AddPattern(URLPattern(schemes, pattern)); 40 } 41 42 ExtensionPrefsTest::ExtensionPrefsTest() 43 : ui_thread_(BrowserThread::UI, &message_loop_), 44 prefs_(message_loop_.message_loop_proxy().get()) {} 45 46 ExtensionPrefsTest::~ExtensionPrefsTest() { 47 } 48 49 void ExtensionPrefsTest::RegisterPreferences( 50 user_prefs::PrefRegistrySyncable* registry) {} 51 52 void ExtensionPrefsTest::SetUp() { 53 RegisterPreferences(prefs_.pref_registry().get()); 54 Initialize(); 55 } 56 57 void ExtensionPrefsTest::TearDown() { 58 Verify(); 59 60 // Reset ExtensionPrefs, and re-verify. 61 prefs_.ResetPrefRegistry(); 62 RegisterPreferences(prefs_.pref_registry().get()); 63 prefs_.RecreateExtensionPrefs(); 64 Verify(); 65 prefs_.pref_service()->CommitPendingWrite(); 66 message_loop_.RunUntilIdle(); 67 } 68 69 // Tests the LastPingDay/SetLastPingDay functions. 70 class ExtensionPrefsLastPingDay : public ExtensionPrefsTest { 71 public: 72 ExtensionPrefsLastPingDay() 73 : extension_time_(Time::Now() - TimeDelta::FromHours(4)), 74 blacklist_time_(Time::Now() - TimeDelta::FromHours(2)) {} 75 76 virtual void Initialize() OVERRIDE { 77 extension_id_ = prefs_.AddExtensionAndReturnId("last_ping_day"); 78 EXPECT_TRUE(prefs()->LastPingDay(extension_id_).is_null()); 79 prefs()->SetLastPingDay(extension_id_, extension_time_); 80 prefs()->SetBlacklistLastPingDay(blacklist_time_); 81 } 82 83 virtual void Verify() OVERRIDE { 84 Time result = prefs()->LastPingDay(extension_id_); 85 EXPECT_FALSE(result.is_null()); 86 EXPECT_TRUE(result == extension_time_); 87 result = prefs()->BlacklistLastPingDay(); 88 EXPECT_FALSE(result.is_null()); 89 EXPECT_TRUE(result == blacklist_time_); 90 } 91 92 private: 93 Time extension_time_; 94 Time blacklist_time_; 95 std::string extension_id_; 96 }; 97 TEST_F(ExtensionPrefsLastPingDay, LastPingDay) {} 98 99 // Tests the GetToolbarOrder/SetToolbarOrder functions. 100 class ExtensionPrefsToolbarOrder : public ExtensionPrefsTest { 101 public: 102 virtual void Initialize() OVERRIDE { 103 list_.push_back(prefs_.AddExtensionAndReturnId("1")); 104 list_.push_back(prefs_.AddExtensionAndReturnId("2")); 105 list_.push_back(prefs_.AddExtensionAndReturnId("3")); 106 ExtensionIdList before_list = prefs()->GetToolbarOrder(); 107 EXPECT_TRUE(before_list.empty()); 108 prefs()->SetToolbarOrder(list_); 109 } 110 111 virtual void Verify() OVERRIDE { 112 ExtensionIdList result = prefs()->GetToolbarOrder(); 113 ASSERT_EQ(list_, result); 114 } 115 116 private: 117 ExtensionIdList list_; 118 }; 119 TEST_F(ExtensionPrefsToolbarOrder, ToolbarOrder) {} 120 121 // Tests the GetKnownDisabled/SetKnownDisabled functions. 122 class ExtensionPrefsKnownDisabled : public ExtensionPrefsTest { 123 public: 124 virtual void Initialize() OVERRIDE { 125 ExtensionIdSet before_set; 126 EXPECT_FALSE(prefs()->GetKnownDisabled(&before_set)); 127 EXPECT_TRUE(before_set.empty()); 128 129 // Initialize to an empty list and confirm that GetKnownDisabled() returns 130 // true and an empty list. 131 prefs()->SetKnownDisabled(before_set); 132 EXPECT_TRUE(prefs()->GetKnownDisabled(&before_set)); 133 EXPECT_TRUE(before_set.empty()); 134 135 set_.insert(prefs_.AddExtensionAndReturnId("1")); 136 set_.insert(prefs_.AddExtensionAndReturnId("2")); 137 set_.insert(prefs_.AddExtensionAndReturnId("3")); 138 prefs()->SetKnownDisabled(set_); 139 } 140 141 virtual void Verify() OVERRIDE { 142 ExtensionIdSet result; 143 EXPECT_TRUE(prefs()->GetKnownDisabled(&result)); 144 ASSERT_EQ(set_, result); 145 } 146 147 private: 148 ExtensionIdSet set_; 149 }; 150 TEST_F(ExtensionPrefsKnownDisabled, KnownDisabled) {} 151 152 // Tests the IsExtensionDisabled/SetExtensionState functions. 153 class ExtensionPrefsExtensionState : public ExtensionPrefsTest { 154 public: 155 virtual void Initialize() OVERRIDE { 156 extension = prefs_.AddExtension("test"); 157 prefs()->SetExtensionState(extension->id(), Extension::DISABLED); 158 } 159 160 virtual void Verify() OVERRIDE { 161 EXPECT_TRUE(prefs()->IsExtensionDisabled(extension->id())); 162 } 163 164 private: 165 scoped_refptr<Extension> extension; 166 }; 167 TEST_F(ExtensionPrefsExtensionState, ExtensionState) {} 168 169 class ExtensionPrefsEscalatePermissions : public ExtensionPrefsTest { 170 public: 171 virtual void Initialize() OVERRIDE { 172 extension = prefs_.AddExtension("test"); 173 prefs()->SetDidExtensionEscalatePermissions(extension.get(), true); 174 } 175 176 virtual void Verify() OVERRIDE { 177 EXPECT_TRUE(prefs()->DidExtensionEscalatePermissions(extension->id())); 178 } 179 180 private: 181 scoped_refptr<Extension> extension; 182 }; 183 TEST_F(ExtensionPrefsEscalatePermissions, EscalatePermissions) {} 184 185 // Tests the AddGrantedPermissions / GetGrantedPermissions functions. 186 class ExtensionPrefsGrantedPermissions : public ExtensionPrefsTest { 187 public: 188 virtual void Initialize() OVERRIDE { 189 const APIPermissionInfo* permission_info = 190 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket); 191 192 extension_id_ = prefs_.AddExtensionAndReturnId("test"); 193 194 api_perm_set1_.insert(APIPermission::kTab); 195 api_perm_set1_.insert(APIPermission::kBookmark); 196 scoped_ptr<APIPermission> permission( 197 permission_info->CreateAPIPermission()); 198 { 199 scoped_ptr<base::ListValue> value(new base::ListValue()); 200 value->Append(new base::StringValue("tcp-connect:*.example.com:80")); 201 value->Append(new base::StringValue("udp-bind::8080")); 202 value->Append(new base::StringValue("udp-send-to::8888")); 203 if (!permission->FromValue(value.get())) 204 NOTREACHED(); 205 } 206 api_perm_set1_.insert(permission.release()); 207 208 api_perm_set2_.insert(APIPermission::kHistory); 209 210 AddPattern(&ehost_perm_set1_, "http://*.google.com/*"); 211 AddPattern(&ehost_perm_set1_, "http://example.com/*"); 212 AddPattern(&ehost_perm_set1_, "chrome://favicon/*"); 213 214 AddPattern(&ehost_perm_set2_, "https://*.google.com/*"); 215 // with duplicate: 216 AddPattern(&ehost_perm_set2_, "http://*.google.com/*"); 217 218 AddPattern(&shost_perm_set1_, "http://reddit.com/r/test/*"); 219 AddPattern(&shost_perm_set2_, "http://reddit.com/r/test/*"); 220 AddPattern(&shost_perm_set2_, "http://somesite.com/*"); 221 AddPattern(&shost_perm_set2_, "http://example.com/*"); 222 223 APIPermissionSet expected_apis = api_perm_set1_; 224 225 AddPattern(&ehost_permissions_, "http://*.google.com/*"); 226 AddPattern(&ehost_permissions_, "http://example.com/*"); 227 AddPattern(&ehost_permissions_, "chrome://favicon/*"); 228 AddPattern(&ehost_permissions_, "https://*.google.com/*"); 229 230 AddPattern(&shost_permissions_, "http://reddit.com/r/test/*"); 231 AddPattern(&shost_permissions_, "http://somesite.com/*"); 232 AddPattern(&shost_permissions_, "http://example.com/*"); 233 234 APIPermissionSet empty_set; 235 ManifestPermissionSet empty_manifest_permissions; 236 URLPatternSet empty_extent; 237 scoped_refptr<PermissionSet> permissions; 238 scoped_refptr<PermissionSet> granted_permissions; 239 240 // Make sure both granted api and host permissions start empty. 241 granted_permissions = 242 prefs()->GetGrantedPermissions(extension_id_); 243 EXPECT_TRUE(granted_permissions->IsEmpty()); 244 245 permissions = new PermissionSet( 246 api_perm_set1_, empty_manifest_permissions, empty_extent, empty_extent); 247 248 // Add part of the api permissions. 249 prefs()->AddGrantedPermissions(extension_id_, permissions.get()); 250 granted_permissions = prefs()->GetGrantedPermissions(extension_id_); 251 EXPECT_TRUE(granted_permissions.get()); 252 EXPECT_FALSE(granted_permissions->IsEmpty()); 253 EXPECT_EQ(expected_apis, granted_permissions->apis()); 254 EXPECT_TRUE(granted_permissions->effective_hosts().is_empty()); 255 EXPECT_FALSE(granted_permissions->HasEffectiveFullAccess()); 256 granted_permissions = NULL; 257 258 // Add part of the explicit host permissions. 259 permissions = new PermissionSet( 260 empty_set, empty_manifest_permissions, ehost_perm_set1_, empty_extent); 261 prefs()->AddGrantedPermissions(extension_id_, permissions.get()); 262 granted_permissions = prefs()->GetGrantedPermissions(extension_id_); 263 EXPECT_FALSE(granted_permissions->IsEmpty()); 264 EXPECT_FALSE(granted_permissions->HasEffectiveFullAccess()); 265 EXPECT_EQ(expected_apis, granted_permissions->apis()); 266 EXPECT_EQ(ehost_perm_set1_, 267 granted_permissions->explicit_hosts()); 268 EXPECT_EQ(ehost_perm_set1_, 269 granted_permissions->effective_hosts()); 270 271 // Add part of the scriptable host permissions. 272 permissions = new PermissionSet( 273 empty_set, empty_manifest_permissions, empty_extent, shost_perm_set1_); 274 prefs()->AddGrantedPermissions(extension_id_, permissions.get()); 275 granted_permissions = prefs()->GetGrantedPermissions(extension_id_); 276 EXPECT_FALSE(granted_permissions->IsEmpty()); 277 EXPECT_FALSE(granted_permissions->HasEffectiveFullAccess()); 278 EXPECT_EQ(expected_apis, granted_permissions->apis()); 279 EXPECT_EQ(ehost_perm_set1_, 280 granted_permissions->explicit_hosts()); 281 EXPECT_EQ(shost_perm_set1_, 282 granted_permissions->scriptable_hosts()); 283 284 URLPatternSet::CreateUnion(ehost_perm_set1_, shost_perm_set1_, 285 &effective_permissions_); 286 EXPECT_EQ(effective_permissions_, granted_permissions->effective_hosts()); 287 288 // Add the rest of the permissions. 289 permissions = new PermissionSet( 290 api_perm_set2_, empty_manifest_permissions, 291 ehost_perm_set2_, shost_perm_set2_); 292 293 APIPermissionSet::Union(expected_apis, api_perm_set2_, &api_permissions_); 294 295 prefs()->AddGrantedPermissions(extension_id_, permissions.get()); 296 granted_permissions = prefs()->GetGrantedPermissions(extension_id_); 297 EXPECT_TRUE(granted_permissions.get()); 298 EXPECT_FALSE(granted_permissions->IsEmpty()); 299 EXPECT_EQ(api_permissions_, granted_permissions->apis()); 300 EXPECT_EQ(ehost_permissions_, 301 granted_permissions->explicit_hosts()); 302 EXPECT_EQ(shost_permissions_, 303 granted_permissions->scriptable_hosts()); 304 effective_permissions_.ClearPatterns(); 305 URLPatternSet::CreateUnion(ehost_permissions_, shost_permissions_, 306 &effective_permissions_); 307 EXPECT_EQ(effective_permissions_, granted_permissions->effective_hosts()); 308 } 309 310 virtual void Verify() OVERRIDE { 311 scoped_refptr<PermissionSet> permissions( 312 prefs()->GetGrantedPermissions(extension_id_)); 313 EXPECT_TRUE(permissions.get()); 314 EXPECT_FALSE(permissions->HasEffectiveFullAccess()); 315 EXPECT_EQ(api_permissions_, permissions->apis()); 316 EXPECT_EQ(ehost_permissions_, 317 permissions->explicit_hosts()); 318 EXPECT_EQ(shost_permissions_, 319 permissions->scriptable_hosts()); 320 } 321 322 private: 323 std::string extension_id_; 324 APIPermissionSet api_perm_set1_; 325 APIPermissionSet api_perm_set2_; 326 URLPatternSet ehost_perm_set1_; 327 URLPatternSet ehost_perm_set2_; 328 URLPatternSet shost_perm_set1_; 329 URLPatternSet shost_perm_set2_; 330 331 APIPermissionSet api_permissions_; 332 URLPatternSet ehost_permissions_; 333 URLPatternSet shost_permissions_; 334 URLPatternSet effective_permissions_; 335 }; 336 TEST_F(ExtensionPrefsGrantedPermissions, GrantedPermissions) {} 337 338 // Tests the SetActivePermissions / GetActivePermissions functions. 339 class ExtensionPrefsActivePermissions : public ExtensionPrefsTest { 340 public: 341 virtual void Initialize() OVERRIDE { 342 extension_id_ = prefs_.AddExtensionAndReturnId("test"); 343 344 APIPermissionSet api_perms; 345 api_perms.insert(APIPermission::kTab); 346 api_perms.insert(APIPermission::kBookmark); 347 api_perms.insert(APIPermission::kHistory); 348 349 ManifestPermissionSet empty_manifest_permissions; 350 351 URLPatternSet ehosts; 352 AddPattern(&ehosts, "http://*.google.com/*"); 353 AddPattern(&ehosts, "http://example.com/*"); 354 AddPattern(&ehosts, "chrome://favicon/*"); 355 356 URLPatternSet shosts; 357 AddPattern(&shosts, "https://*.google.com/*"); 358 AddPattern(&shosts, "http://reddit.com/r/test/*"); 359 360 active_perms_ = new PermissionSet( 361 api_perms, empty_manifest_permissions, ehosts, shosts); 362 363 // Make sure the active permissions start empty. 364 scoped_refptr<PermissionSet> active( 365 prefs()->GetActivePermissions(extension_id_)); 366 EXPECT_TRUE(active->IsEmpty()); 367 368 // Set the active permissions. 369 prefs()->SetActivePermissions(extension_id_, active_perms_.get()); 370 active = prefs()->GetActivePermissions(extension_id_); 371 EXPECT_EQ(active_perms_->apis(), active->apis()); 372 EXPECT_EQ(active_perms_->explicit_hosts(), active->explicit_hosts()); 373 EXPECT_EQ(active_perms_->scriptable_hosts(), active->scriptable_hosts()); 374 EXPECT_EQ(*active_perms_.get(), *active.get()); 375 } 376 377 virtual void Verify() OVERRIDE { 378 scoped_refptr<PermissionSet> permissions( 379 prefs()->GetActivePermissions(extension_id_)); 380 EXPECT_EQ(*active_perms_.get(), *permissions.get()); 381 } 382 383 private: 384 std::string extension_id_; 385 scoped_refptr<PermissionSet> active_perms_; 386 }; 387 TEST_F(ExtensionPrefsActivePermissions, SetAndGetActivePermissions) {} 388 389 // Tests the GetVersionString function. 390 class ExtensionPrefsVersionString : public ExtensionPrefsTest { 391 public: 392 virtual void Initialize() OVERRIDE { 393 extension = prefs_.AddExtension("test"); 394 EXPECT_EQ("0.1", prefs()->GetVersionString(extension->id())); 395 prefs()->OnExtensionUninstalled(extension->id(), 396 Manifest::INTERNAL, false); 397 } 398 399 virtual void Verify() OVERRIDE { 400 EXPECT_EQ("", prefs()->GetVersionString(extension->id())); 401 } 402 403 private: 404 scoped_refptr<Extension> extension; 405 }; 406 TEST_F(ExtensionPrefsVersionString, VersionString) {} 407 408 class ExtensionPrefsAcknowledgment : public ExtensionPrefsTest { 409 public: 410 virtual void Initialize() OVERRIDE { 411 not_installed_id_ = "pghjnghklobnfoidcldiidjjjhkeeaoi"; 412 413 // Install some extensions. 414 for (int i = 0; i < 5; i++) { 415 std::string name = "test" + base::IntToString(i); 416 extensions_.push_back(prefs_.AddExtension(name)); 417 } 418 EXPECT_EQ(NULL, 419 prefs()->GetInstalledExtensionInfo(not_installed_id_).get()); 420 421 ExtensionList::const_iterator iter; 422 for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) { 423 std::string id = (*iter)->id(); 424 EXPECT_FALSE(prefs()->IsExternalExtensionAcknowledged(id)); 425 EXPECT_FALSE(prefs()->IsBlacklistedExtensionAcknowledged(id)); 426 if (external_id_.empty()) { 427 external_id_ = id; 428 continue; 429 } 430 if (blacklisted_id_.empty()) { 431 blacklisted_id_ = id; 432 continue; 433 } 434 } 435 // For each type of acknowledgment, acknowledge one installed and one 436 // not-installed extension id. 437 prefs()->AcknowledgeExternalExtension(external_id_); 438 prefs()->AcknowledgeBlacklistedExtension(blacklisted_id_); 439 prefs()->AcknowledgeExternalExtension(not_installed_id_); 440 prefs()->AcknowledgeBlacklistedExtension(not_installed_id_); 441 } 442 443 virtual void Verify() OVERRIDE { 444 ExtensionList::const_iterator iter; 445 for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) { 446 std::string id = (*iter)->id(); 447 if (id == external_id_) { 448 EXPECT_TRUE(prefs()->IsExternalExtensionAcknowledged(id)); 449 } else { 450 EXPECT_FALSE(prefs()->IsExternalExtensionAcknowledged(id)); 451 } 452 if (id == blacklisted_id_) { 453 EXPECT_TRUE(prefs()->IsBlacklistedExtensionAcknowledged(id)); 454 } else { 455 EXPECT_FALSE(prefs()->IsBlacklistedExtensionAcknowledged(id)); 456 } 457 } 458 EXPECT_TRUE(prefs()->IsExternalExtensionAcknowledged(not_installed_id_)); 459 EXPECT_TRUE(prefs()->IsBlacklistedExtensionAcknowledged(not_installed_id_)); 460 } 461 462 private: 463 ExtensionList extensions_; 464 465 std::string not_installed_id_; 466 std::string external_id_; 467 std::string blacklisted_id_; 468 }; 469 TEST_F(ExtensionPrefsAcknowledgment, Acknowledgment) {} 470 471 // Tests the idle install information functions. 472 class ExtensionPrefsDelayedInstallInfo : public ExtensionPrefsTest { 473 public: 474 // Sets idle install information for one test extension. 475 void SetIdleInfo(std::string id, int num) { 476 DictionaryValue manifest; 477 manifest.SetString(manifest_keys::kName, "test"); 478 manifest.SetString(manifest_keys::kVersion, "1." + base::IntToString(num)); 479 base::FilePath path = 480 prefs_.extensions_dir().AppendASCII(base::IntToString(num)); 481 std::string errors; 482 scoped_refptr<Extension> extension = Extension::Create( 483 path, Manifest::INTERNAL, manifest, Extension::NO_FLAGS, id, &errors); 484 ASSERT_TRUE(extension.get()) << errors; 485 ASSERT_EQ(id, extension->id()); 486 prefs()->SetDelayedInstallInfo(extension.get(), 487 Extension::ENABLED, 488 false, 489 ExtensionPrefs::DELAY_REASON_WAIT_FOR_IDLE, 490 syncer::StringOrdinal()); 491 } 492 493 // Verifies that we get back expected idle install information previously 494 // set by SetIdleInfo. 495 void VerifyIdleInfo(std::string id, int num) { 496 scoped_ptr<ExtensionInfo> info(prefs()->GetDelayedInstallInfo(id)); 497 ASSERT_TRUE(info); 498 std::string version; 499 ASSERT_TRUE(info->extension_manifest->GetString("version", &version)); 500 ASSERT_EQ("1." + base::IntToString(num), version); 501 ASSERT_EQ(base::IntToString(num), 502 info->extension_path.BaseName().MaybeAsASCII()); 503 } 504 505 bool HasInfoForId(ExtensionPrefs::ExtensionsInfo* info, 506 const std::string& id) { 507 for (size_t i = 0; i < info->size(); ++i) { 508 if (info->at(i)->extension_id == id) 509 return true; 510 } 511 return false; 512 } 513 514 virtual void Initialize() OVERRIDE { 515 PathService::Get(chrome::DIR_TEST_DATA, &basedir_); 516 now_ = Time::Now(); 517 id1_ = prefs_.AddExtensionAndReturnId("1"); 518 id2_ = prefs_.AddExtensionAndReturnId("2"); 519 id3_ = prefs_.AddExtensionAndReturnId("3"); 520 id4_ = prefs_.AddExtensionAndReturnId("4"); 521 522 // Set info for two extensions, then remove it. 523 SetIdleInfo(id1_, 1); 524 SetIdleInfo(id2_, 2); 525 VerifyIdleInfo(id1_, 1); 526 VerifyIdleInfo(id2_, 2); 527 scoped_ptr<ExtensionPrefs::ExtensionsInfo> info( 528 prefs()->GetAllDelayedInstallInfo()); 529 EXPECT_EQ(2u, info->size()); 530 EXPECT_TRUE(HasInfoForId(info.get(), id1_)); 531 EXPECT_TRUE(HasInfoForId(info.get(), id2_)); 532 prefs()->RemoveDelayedInstallInfo(id1_); 533 prefs()->RemoveDelayedInstallInfo(id2_); 534 info = prefs()->GetAllDelayedInstallInfo(); 535 EXPECT_TRUE(info->empty()); 536 537 // Try getting/removing info for an id that used to have info set. 538 EXPECT_FALSE(prefs()->GetDelayedInstallInfo(id1_)); 539 EXPECT_FALSE(prefs()->RemoveDelayedInstallInfo(id1_)); 540 541 // Try getting/removing info for an id that has not yet had any info set. 542 EXPECT_FALSE(prefs()->GetDelayedInstallInfo(id3_)); 543 EXPECT_FALSE(prefs()->RemoveDelayedInstallInfo(id3_)); 544 545 // Set info for 4 extensions, then remove for one of them. 546 SetIdleInfo(id1_, 1); 547 SetIdleInfo(id2_, 2); 548 SetIdleInfo(id3_, 3); 549 SetIdleInfo(id4_, 4); 550 VerifyIdleInfo(id1_, 1); 551 VerifyIdleInfo(id2_, 2); 552 VerifyIdleInfo(id3_, 3); 553 VerifyIdleInfo(id4_, 4); 554 prefs()->RemoveDelayedInstallInfo(id3_); 555 } 556 557 virtual void Verify() OVERRIDE { 558 // Make sure the info for the 3 extensions we expect is present. 559 scoped_ptr<ExtensionPrefs::ExtensionsInfo> info( 560 prefs()->GetAllDelayedInstallInfo()); 561 EXPECT_EQ(3u, info->size()); 562 EXPECT_TRUE(HasInfoForId(info.get(), id1_)); 563 EXPECT_TRUE(HasInfoForId(info.get(), id2_)); 564 EXPECT_TRUE(HasInfoForId(info.get(), id4_)); 565 VerifyIdleInfo(id1_, 1); 566 VerifyIdleInfo(id2_, 2); 567 VerifyIdleInfo(id4_, 4); 568 569 // Make sure there isn't info the for the one extension id we removed. 570 EXPECT_FALSE(prefs()->GetDelayedInstallInfo(id3_)); 571 } 572 573 protected: 574 Time now_; 575 base::FilePath basedir_; 576 std::string id1_; 577 std::string id2_; 578 std::string id3_; 579 std::string id4_; 580 }; 581 TEST_F(ExtensionPrefsDelayedInstallInfo, DelayedInstallInfo) {} 582 583 // Tests the FinishDelayedInstallInfo function. 584 class ExtensionPrefsFinishDelayedInstallInfo : public ExtensionPrefsTest { 585 public: 586 virtual void Initialize() OVERRIDE { 587 DictionaryValue dictionary; 588 dictionary.SetString(manifest_keys::kName, "test"); 589 dictionary.SetString(manifest_keys::kVersion, "0.1"); 590 dictionary.SetString(manifest_keys::kBackgroundPage, "background.html"); 591 scoped_refptr<Extension> extension = 592 prefs_.AddExtensionWithManifest(dictionary, Manifest::INTERNAL); 593 id_ = extension->id(); 594 595 596 // Set idle info 597 DictionaryValue manifest; 598 manifest.SetString(manifest_keys::kName, "test"); 599 manifest.SetString(manifest_keys::kVersion, "0.2"); 600 scoped_ptr<ListValue> scripts(new ListValue); 601 scripts->AppendString("test.js"); 602 manifest.Set(manifest_keys::kBackgroundScripts, scripts.release()); 603 base::FilePath path = 604 prefs_.extensions_dir().AppendASCII("test_0.2"); 605 std::string errors; 606 scoped_refptr<Extension> new_extension = Extension::Create( 607 path, Manifest::INTERNAL, manifest, Extension::NO_FLAGS, id_, &errors); 608 ASSERT_TRUE(new_extension.get()) << errors; 609 ASSERT_EQ(id_, new_extension->id()); 610 prefs()->SetDelayedInstallInfo(new_extension.get(), 611 Extension::ENABLED, 612 false, 613 ExtensionPrefs::DELAY_REASON_WAIT_FOR_IDLE, 614 syncer::StringOrdinal()); 615 616 // Finish idle installation 617 ASSERT_TRUE(prefs()->FinishDelayedInstallInfo(id_)); 618 } 619 620 virtual void Verify() OVERRIDE { 621 EXPECT_FALSE(prefs()->GetDelayedInstallInfo(id_)); 622 623 const DictionaryValue* manifest; 624 ASSERT_TRUE(prefs()->ReadPrefAsDictionary(id_, "manifest", &manifest)); 625 ASSERT_TRUE(manifest); 626 std::string value; 627 EXPECT_TRUE(manifest->GetString(manifest_keys::kName, &value)); 628 EXPECT_EQ("test", value); 629 EXPECT_TRUE(manifest->GetString(manifest_keys::kVersion, &value)); 630 EXPECT_EQ("0.2", value); 631 EXPECT_FALSE(manifest->GetString(manifest_keys::kBackgroundPage, &value)); 632 const ListValue* scripts; 633 ASSERT_TRUE(manifest->GetList(manifest_keys::kBackgroundScripts, &scripts)); 634 EXPECT_EQ(1u, scripts->GetSize()); 635 } 636 637 protected: 638 std::string id_; 639 }; 640 TEST_F(ExtensionPrefsFinishDelayedInstallInfo, FinishDelayedInstallInfo) {} 641 642 class ExtensionPrefsOnExtensionInstalled : public ExtensionPrefsTest { 643 public: 644 virtual void Initialize() OVERRIDE { 645 extension_ = prefs_.AddExtension("on_extension_installed"); 646 EXPECT_FALSE(prefs()->IsExtensionDisabled(extension_->id())); 647 prefs()->OnExtensionInstalled(extension_.get(), 648 Extension::DISABLED, 649 false, 650 syncer::StringOrdinal()); 651 } 652 653 virtual void Verify() OVERRIDE { 654 EXPECT_TRUE(prefs()->IsExtensionDisabled(extension_->id())); 655 } 656 657 private: 658 scoped_refptr<Extension> extension_; 659 }; 660 TEST_F(ExtensionPrefsOnExtensionInstalled, 661 ExtensionPrefsOnExtensionInstalled) {} 662 663 class ExtensionPrefsAppDraggedByUser : public ExtensionPrefsTest { 664 public: 665 virtual void Initialize() OVERRIDE { 666 extension_ = prefs_.AddExtension("on_extension_installed"); 667 EXPECT_FALSE(prefs()->WasAppDraggedByUser(extension_->id())); 668 prefs()->OnExtensionInstalled(extension_.get(), 669 Extension::ENABLED, 670 false, 671 syncer::StringOrdinal()); 672 } 673 674 virtual void Verify() OVERRIDE { 675 // Set the flag and see if it persisted. 676 prefs()->SetAppDraggedByUser(extension_->id()); 677 EXPECT_TRUE(prefs()->WasAppDraggedByUser(extension_->id())); 678 679 // Make sure it doesn't change on consecutive calls. 680 prefs()->SetAppDraggedByUser(extension_->id()); 681 EXPECT_TRUE(prefs()->WasAppDraggedByUser(extension_->id())); 682 } 683 684 private: 685 scoped_refptr<Extension> extension_; 686 }; 687 TEST_F(ExtensionPrefsAppDraggedByUser, ExtensionPrefsAppDraggedByUser) {} 688 689 class ExtensionPrefsFlags : public ExtensionPrefsTest { 690 public: 691 virtual void Initialize() OVERRIDE { 692 { 693 base::DictionaryValue dictionary; 694 dictionary.SetString(manifest_keys::kName, "from_webstore"); 695 dictionary.SetString(manifest_keys::kVersion, "0.1"); 696 webstore_extension_ = prefs_.AddExtensionWithManifestAndFlags( 697 dictionary, Manifest::INTERNAL, Extension::FROM_WEBSTORE); 698 } 699 700 { 701 base::DictionaryValue dictionary; 702 dictionary.SetString(manifest_keys::kName, "from_bookmark"); 703 dictionary.SetString(manifest_keys::kVersion, "0.1"); 704 bookmark_extension_ = prefs_.AddExtensionWithManifestAndFlags( 705 dictionary, Manifest::INTERNAL, Extension::FROM_BOOKMARK); 706 } 707 708 { 709 base::DictionaryValue dictionary; 710 dictionary.SetString(manifest_keys::kName, "was_installed_by_default"); 711 dictionary.SetString(manifest_keys::kVersion, "0.1"); 712 default_extension_ = prefs_.AddExtensionWithManifestAndFlags( 713 dictionary, 714 Manifest::INTERNAL, 715 Extension::WAS_INSTALLED_BY_DEFAULT); 716 } 717 } 718 719 virtual void Verify() OVERRIDE { 720 EXPECT_TRUE(prefs()->IsFromWebStore(webstore_extension_->id())); 721 EXPECT_FALSE(prefs()->IsFromBookmark(webstore_extension_->id())); 722 723 EXPECT_TRUE(prefs()->IsFromBookmark(bookmark_extension_->id())); 724 EXPECT_FALSE(prefs()->IsFromWebStore(bookmark_extension_->id())); 725 726 EXPECT_TRUE(prefs()->WasInstalledByDefault(default_extension_->id())); 727 } 728 729 private: 730 scoped_refptr<Extension> webstore_extension_; 731 scoped_refptr<Extension> bookmark_extension_; 732 scoped_refptr<Extension> default_extension_; 733 }; 734 TEST_F(ExtensionPrefsFlags, ExtensionPrefsFlags) {} 735 736 PrefsPrepopulatedTestBase::PrefsPrepopulatedTestBase() 737 : ExtensionPrefsTest() { 738 DictionaryValue simple_dict; 739 std::string error; 740 741 simple_dict.SetString(manifest_keys::kVersion, "1.0.0.0"); 742 simple_dict.SetString(manifest_keys::kName, "unused"); 743 744 extension1_ = Extension::Create( 745 prefs_.temp_dir().AppendASCII("ext1_"), 746 Manifest::EXTERNAL_PREF, 747 simple_dict, 748 Extension::NO_FLAGS, 749 &error); 750 extension2_ = Extension::Create( 751 prefs_.temp_dir().AppendASCII("ext2_"), 752 Manifest::EXTERNAL_PREF, 753 simple_dict, 754 Extension::NO_FLAGS, 755 &error); 756 extension3_ = Extension::Create( 757 prefs_.temp_dir().AppendASCII("ext3_"), 758 Manifest::EXTERNAL_PREF, 759 simple_dict, 760 Extension::NO_FLAGS, 761 &error); 762 extension4_ = Extension::Create( 763 prefs_.temp_dir().AppendASCII("ext4_"), 764 Manifest::EXTERNAL_PREF, 765 simple_dict, 766 Extension::NO_FLAGS, 767 &error); 768 769 for (size_t i = 0; i < kNumInstalledExtensions; ++i) 770 installed_[i] = false; 771 } 772 773 PrefsPrepopulatedTestBase::~PrefsPrepopulatedTestBase() { 774 } 775 776 // Tests that blacklist state can be queried. 777 class ExtensionPrefsBlacklistedExtensions : public ExtensionPrefsTest { 778 public: 779 virtual ~ExtensionPrefsBlacklistedExtensions() {} 780 781 virtual void Initialize() OVERRIDE { 782 extension_a_ = prefs_.AddExtension("a"); 783 extension_b_ = prefs_.AddExtension("b"); 784 extension_c_ = prefs_.AddExtension("c"); 785 } 786 787 virtual void Verify() OVERRIDE { 788 { 789 ExtensionIdSet ids; 790 EXPECT_EQ(ids, prefs()->GetBlacklistedExtensions()); 791 } 792 prefs()->SetExtensionBlacklisted(extension_a_->id(), true); 793 { 794 ExtensionIdSet ids; 795 ids.insert(extension_a_->id()); 796 EXPECT_EQ(ids, prefs()->GetBlacklistedExtensions()); 797 } 798 prefs()->SetExtensionBlacklisted(extension_b_->id(), true); 799 prefs()->SetExtensionBlacklisted(extension_c_->id(), true); 800 { 801 ExtensionIdSet ids; 802 ids.insert(extension_a_->id()); 803 ids.insert(extension_b_->id()); 804 ids.insert(extension_c_->id()); 805 EXPECT_EQ(ids, prefs()->GetBlacklistedExtensions()); 806 } 807 prefs()->SetExtensionBlacklisted(extension_a_->id(), false); 808 { 809 ExtensionIdSet ids; 810 ids.insert(extension_b_->id()); 811 ids.insert(extension_c_->id()); 812 EXPECT_EQ(ids, prefs()->GetBlacklistedExtensions()); 813 } 814 prefs()->SetExtensionBlacklisted(extension_b_->id(), false); 815 prefs()->SetExtensionBlacklisted(extension_c_->id(), false); 816 { 817 ExtensionIdSet ids; 818 EXPECT_EQ(ids, prefs()->GetBlacklistedExtensions()); 819 } 820 821 // The interesting part: make sure that we're cleaning up after ourselves 822 // when we're storing *just* the fact that the extension is blacklisted. 823 std::string arbitrary_id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 824 825 prefs()->SetExtensionBlacklisted(arbitrary_id, true); 826 prefs()->SetExtensionBlacklisted(extension_a_->id(), true); 827 828 // (And make sure that the acknowledged bit is also cleared). 829 prefs()->AcknowledgeBlacklistedExtension(arbitrary_id); 830 831 EXPECT_TRUE(prefs()->GetExtensionPref(arbitrary_id)); 832 { 833 ExtensionIdSet ids; 834 ids.insert(arbitrary_id); 835 ids.insert(extension_a_->id()); 836 EXPECT_EQ(ids, prefs()->GetBlacklistedExtensions()); 837 } 838 prefs()->SetExtensionBlacklisted(arbitrary_id, false); 839 prefs()->SetExtensionBlacklisted(extension_a_->id(), false); 840 EXPECT_FALSE(prefs()->GetExtensionPref(arbitrary_id)); 841 { 842 ExtensionIdSet ids; 843 EXPECT_EQ(ids, prefs()->GetBlacklistedExtensions()); 844 } 845 } 846 847 private: 848 scoped_refptr<const Extension> extension_a_; 849 scoped_refptr<const Extension> extension_b_; 850 scoped_refptr<const Extension> extension_c_; 851 }; 852 TEST_F(ExtensionPrefsBlacklistedExtensions, 853 ExtensionPrefsBlacklistedExtensions) {} 854 855 } // namespace extensions 856