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/common/extensions/features/simple_feature.h" 6 7 #include "chrome/common/extensions/features/feature_channel.h" 8 #include "extensions/common/value_builder.h" 9 #include "testing/gtest/include/gtest/gtest.h" 10 11 using chrome::VersionInfo; 12 using extensions::DictionaryBuilder; 13 using extensions::Extension; 14 using extensions::Feature; 15 using extensions::ListBuilder; 16 using extensions::Manifest; 17 using extensions::ScopedCurrentChannel; 18 using extensions::SimpleFeature; 19 20 namespace { 21 22 struct IsAvailableTestData { 23 std::string extension_id; 24 Manifest::Type extension_type; 25 Feature::Location location; 26 Feature::Platform platform; 27 int manifest_version; 28 Feature::AvailabilityResult expected_result; 29 }; 30 31 class ExtensionSimpleFeatureTest : public testing::Test { 32 protected: 33 ExtensionSimpleFeatureTest() 34 : current_channel_(VersionInfo::CHANNEL_UNKNOWN) {} 35 virtual ~ExtensionSimpleFeatureTest() {} 36 37 private: 38 ScopedCurrentChannel current_channel_; 39 }; 40 41 TEST_F(ExtensionSimpleFeatureTest, IsAvailableNullCase) { 42 const IsAvailableTestData tests[] = { 43 { "", Manifest::TYPE_UNKNOWN, 44 Feature::UNSPECIFIED_LOCATION, Feature::UNSPECIFIED_PLATFORM, -1, 45 Feature::IS_AVAILABLE }, 46 { "random-extension", Manifest::TYPE_UNKNOWN, 47 Feature::UNSPECIFIED_LOCATION, Feature::UNSPECIFIED_PLATFORM, -1, 48 Feature::IS_AVAILABLE }, 49 { "", Manifest::TYPE_LEGACY_PACKAGED_APP, 50 Feature::UNSPECIFIED_LOCATION, Feature::UNSPECIFIED_PLATFORM, -1, 51 Feature::IS_AVAILABLE }, 52 { "", Manifest::TYPE_UNKNOWN, 53 Feature::UNSPECIFIED_LOCATION, Feature::UNSPECIFIED_PLATFORM, -1, 54 Feature::IS_AVAILABLE }, 55 { "", Manifest::TYPE_UNKNOWN, 56 Feature::COMPONENT_LOCATION, Feature::UNSPECIFIED_PLATFORM, -1, 57 Feature::IS_AVAILABLE }, 58 { "", Manifest::TYPE_UNKNOWN, 59 Feature::UNSPECIFIED_LOCATION, Feature::CHROMEOS_PLATFORM, -1, 60 Feature::IS_AVAILABLE }, 61 { "", Manifest::TYPE_UNKNOWN, 62 Feature::UNSPECIFIED_LOCATION, Feature::UNSPECIFIED_PLATFORM, 25, 63 Feature::IS_AVAILABLE } 64 }; 65 66 SimpleFeature feature; 67 for (size_t i = 0; i < arraysize(tests); ++i) { 68 const IsAvailableTestData& test = tests[i]; 69 EXPECT_EQ(test.expected_result, 70 feature.IsAvailableToManifest(test.extension_id, 71 test.extension_type, 72 test.location, 73 test.manifest_version, 74 test.platform).result()); 75 } 76 } 77 78 TEST_F(ExtensionSimpleFeatureTest, Whitelist) { 79 const std::string kIdFoo("fooabbbbccccddddeeeeffffgggghhhh"); 80 const std::string kIdBar("barabbbbccccddddeeeeffffgggghhhh"); 81 const std::string kIdBaz("bazabbbbccccddddeeeeffffgggghhhh"); 82 SimpleFeature feature; 83 feature.whitelist()->insert(kIdFoo); 84 feature.whitelist()->insert(kIdBar); 85 86 EXPECT_EQ(Feature::IS_AVAILABLE, feature.IsAvailableToManifest( 87 kIdFoo, Manifest::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, -1, 88 Feature::UNSPECIFIED_PLATFORM).result()); 89 EXPECT_EQ(Feature::IS_AVAILABLE, feature.IsAvailableToManifest( 90 kIdBar, Manifest::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, -1, 91 Feature::UNSPECIFIED_PLATFORM).result()); 92 93 EXPECT_EQ(Feature::NOT_FOUND_IN_WHITELIST, feature.IsAvailableToManifest( 94 kIdBaz, Manifest::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, -1, 95 Feature::UNSPECIFIED_PLATFORM).result()); 96 EXPECT_EQ( 97 Feature::NOT_FOUND_IN_WHITELIST, 98 feature.IsAvailableToManifest(std::string(), 99 Manifest::TYPE_UNKNOWN, 100 Feature::UNSPECIFIED_LOCATION, 101 -1, 102 Feature::UNSPECIFIED_PLATFORM).result()); 103 104 feature.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP); 105 EXPECT_EQ(Feature::NOT_FOUND_IN_WHITELIST, feature.IsAvailableToManifest( 106 kIdBaz, Manifest::TYPE_LEGACY_PACKAGED_APP, 107 Feature::UNSPECIFIED_LOCATION, -1, 108 Feature::UNSPECIFIED_PLATFORM).result()); 109 } 110 111 TEST_F(ExtensionSimpleFeatureTest, HashedIdWhitelist) { 112 // echo -n "fooabbbbccccddddeeeeffffgggghhhh" | 113 // sha1sum | tr '[:lower:]' '[:upper:]' 114 const std::string kIdFoo("fooabbbbccccddddeeeeffffgggghhhh"); 115 const std::string kIdFooHashed("55BC7228A0D502A2A48C9BB16B07062A01E62897"); 116 SimpleFeature feature; 117 118 feature.whitelist()->insert(kIdFooHashed); 119 120 EXPECT_EQ(Feature::IS_AVAILABLE, feature.IsAvailableToManifest( 121 kIdFoo, Manifest::TYPE_UNKNOWN, Feature::UNSPECIFIED_LOCATION, -1, 122 Feature::UNSPECIFIED_PLATFORM).result()); 123 EXPECT_NE(Feature::IS_AVAILABLE, feature.IsAvailableToManifest( 124 kIdFooHashed, Manifest::TYPE_UNKNOWN, 125 Feature::UNSPECIFIED_LOCATION, -1, 126 Feature::UNSPECIFIED_PLATFORM).result()); 127 EXPECT_EQ(Feature::NOT_FOUND_IN_WHITELIST, feature.IsAvailableToManifest( 128 "slightlytoooolongforanextensionid", Manifest::TYPE_UNKNOWN, 129 Feature::UNSPECIFIED_LOCATION, -1, 130 Feature::UNSPECIFIED_PLATFORM).result()); 131 EXPECT_EQ(Feature::NOT_FOUND_IN_WHITELIST, feature.IsAvailableToManifest( 132 "tooshortforanextensionid", Manifest::TYPE_UNKNOWN, 133 Feature::UNSPECIFIED_LOCATION, -1, 134 Feature::UNSPECIFIED_PLATFORM).result()); 135 } 136 137 TEST_F(ExtensionSimpleFeatureTest, PackageType) { 138 SimpleFeature feature; 139 feature.extension_types()->insert(Manifest::TYPE_EXTENSION); 140 feature.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP); 141 142 EXPECT_EQ( 143 Feature::IS_AVAILABLE, 144 feature.IsAvailableToManifest(std::string(), 145 Manifest::TYPE_EXTENSION, 146 Feature::UNSPECIFIED_LOCATION, 147 -1, 148 Feature::UNSPECIFIED_PLATFORM).result()); 149 EXPECT_EQ( 150 Feature::IS_AVAILABLE, 151 feature.IsAvailableToManifest(std::string(), 152 Manifest::TYPE_LEGACY_PACKAGED_APP, 153 Feature::UNSPECIFIED_LOCATION, 154 -1, 155 Feature::UNSPECIFIED_PLATFORM).result()); 156 157 EXPECT_EQ( 158 Feature::INVALID_TYPE, 159 feature.IsAvailableToManifest(std::string(), 160 Manifest::TYPE_UNKNOWN, 161 Feature::UNSPECIFIED_LOCATION, 162 -1, 163 Feature::UNSPECIFIED_PLATFORM).result()); 164 EXPECT_EQ( 165 Feature::INVALID_TYPE, 166 feature.IsAvailableToManifest(std::string(), 167 Manifest::TYPE_THEME, 168 Feature::UNSPECIFIED_LOCATION, 169 -1, 170 Feature::UNSPECIFIED_PLATFORM).result()); 171 } 172 173 TEST_F(ExtensionSimpleFeatureTest, Context) { 174 SimpleFeature feature; 175 feature.set_name("somefeature"); 176 feature.GetContexts()->insert(Feature::BLESSED_EXTENSION_CONTEXT); 177 feature.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP); 178 feature.platforms()->insert(Feature::CHROMEOS_PLATFORM); 179 feature.set_min_manifest_version(21); 180 feature.set_max_manifest_version(25); 181 182 base::DictionaryValue manifest; 183 manifest.SetString("name", "test"); 184 manifest.SetString("version", "1"); 185 manifest.SetInteger("manifest_version", 21); 186 manifest.SetString("app.launch.local_path", "foo.html"); 187 188 std::string error; 189 scoped_refptr<const Extension> extension(Extension::Create( 190 base::FilePath(), Manifest::INTERNAL, manifest, Extension::NO_FLAGS, 191 &error)); 192 EXPECT_EQ("", error); 193 ASSERT_TRUE(extension.get()); 194 195 feature.whitelist()->insert("monkey"); 196 EXPECT_EQ(Feature::NOT_FOUND_IN_WHITELIST, feature.IsAvailableToContext( 197 extension.get(), Feature::BLESSED_EXTENSION_CONTEXT, 198 Feature::CHROMEOS_PLATFORM).result()); 199 feature.whitelist()->clear(); 200 201 feature.extension_types()->clear(); 202 feature.extension_types()->insert(Manifest::TYPE_THEME); 203 { 204 Feature::Availability availability = feature.IsAvailableToContext( 205 extension.get(), Feature::BLESSED_EXTENSION_CONTEXT, 206 Feature::CHROMEOS_PLATFORM); 207 EXPECT_EQ(Feature::INVALID_TYPE, availability.result()); 208 EXPECT_EQ("'somefeature' is only allowed for themes, " 209 "but this is a legacy packaged app.", 210 availability.message()); 211 } 212 213 feature.extension_types()->clear(); 214 feature.extension_types()->insert(Manifest::TYPE_LEGACY_PACKAGED_APP); 215 feature.GetContexts()->clear(); 216 feature.GetContexts()->insert(Feature::UNBLESSED_EXTENSION_CONTEXT); 217 feature.GetContexts()->insert(Feature::CONTENT_SCRIPT_CONTEXT); 218 { 219 Feature::Availability availability = feature.IsAvailableToContext( 220 extension.get(), Feature::BLESSED_EXTENSION_CONTEXT, 221 Feature::CHROMEOS_PLATFORM); 222 EXPECT_EQ(Feature::INVALID_CONTEXT, availability.result()); 223 EXPECT_EQ("'somefeature' is only allowed to run in extension iframes and " 224 "content scripts, but this is a privileged page", 225 availability.message()); 226 } 227 228 feature.GetContexts()->insert(Feature::WEB_PAGE_CONTEXT); 229 { 230 Feature::Availability availability = feature.IsAvailableToContext( 231 extension.get(), Feature::BLESSED_EXTENSION_CONTEXT, 232 Feature::CHROMEOS_PLATFORM); 233 EXPECT_EQ(Feature::INVALID_CONTEXT, availability.result()); 234 EXPECT_EQ("'somefeature' is only allowed to run in extension iframes, " 235 "content scripts, and web pages, but this is a privileged page", 236 availability.message()); 237 } 238 239 feature.GetContexts()->clear(); 240 feature.GetContexts()->insert(Feature::BLESSED_EXTENSION_CONTEXT); 241 feature.set_location(Feature::COMPONENT_LOCATION); 242 EXPECT_EQ(Feature::INVALID_LOCATION, feature.IsAvailableToContext( 243 extension.get(), Feature::BLESSED_EXTENSION_CONTEXT, 244 Feature::CHROMEOS_PLATFORM).result()); 245 feature.set_location(Feature::UNSPECIFIED_LOCATION); 246 247 EXPECT_EQ(Feature::INVALID_PLATFORM, feature.IsAvailableToContext( 248 extension.get(), Feature::BLESSED_EXTENSION_CONTEXT, 249 Feature::UNSPECIFIED_PLATFORM).result()); 250 251 feature.set_min_manifest_version(22); 252 EXPECT_EQ(Feature::INVALID_MIN_MANIFEST_VERSION, feature.IsAvailableToContext( 253 extension.get(), Feature::BLESSED_EXTENSION_CONTEXT, 254 Feature::CHROMEOS_PLATFORM).result()); 255 feature.set_min_manifest_version(21); 256 257 feature.set_max_manifest_version(18); 258 EXPECT_EQ(Feature::INVALID_MAX_MANIFEST_VERSION, feature.IsAvailableToContext( 259 extension.get(), Feature::BLESSED_EXTENSION_CONTEXT, 260 Feature::CHROMEOS_PLATFORM).result()); 261 feature.set_max_manifest_version(25); 262 } 263 264 TEST_F(ExtensionSimpleFeatureTest, Location) { 265 SimpleFeature feature; 266 267 // If the feature specifies "component" as its location, then only component 268 // extensions can access it. 269 feature.set_location(Feature::COMPONENT_LOCATION); 270 EXPECT_EQ( 271 Feature::IS_AVAILABLE, 272 feature.IsAvailableToManifest(std::string(), 273 Manifest::TYPE_UNKNOWN, 274 Feature::COMPONENT_LOCATION, 275 -1, 276 Feature::UNSPECIFIED_PLATFORM).result()); 277 EXPECT_EQ( 278 Feature::INVALID_LOCATION, 279 feature.IsAvailableToManifest(std::string(), 280 Manifest::TYPE_UNKNOWN, 281 Feature::UNSPECIFIED_LOCATION, 282 -1, 283 Feature::UNSPECIFIED_PLATFORM).result()); 284 285 // But component extensions can access anything else, whatever their location. 286 feature.set_location(Feature::UNSPECIFIED_LOCATION); 287 EXPECT_EQ( 288 Feature::IS_AVAILABLE, 289 feature.IsAvailableToManifest(std::string(), 290 Manifest::TYPE_UNKNOWN, 291 Feature::COMPONENT_LOCATION, 292 -1, 293 Feature::UNSPECIFIED_PLATFORM).result()); 294 } 295 296 TEST_F(ExtensionSimpleFeatureTest, Platform) { 297 SimpleFeature feature; 298 feature.platforms()->insert(Feature::CHROMEOS_PLATFORM); 299 EXPECT_EQ(Feature::IS_AVAILABLE, 300 feature.IsAvailableToManifest(std::string(), 301 Manifest::TYPE_UNKNOWN, 302 Feature::UNSPECIFIED_LOCATION, 303 -1, 304 Feature::CHROMEOS_PLATFORM).result()); 305 EXPECT_EQ( 306 Feature::INVALID_PLATFORM, 307 feature.IsAvailableToManifest(std::string(), 308 Manifest::TYPE_UNKNOWN, 309 Feature::UNSPECIFIED_LOCATION, 310 -1, 311 Feature::UNSPECIFIED_PLATFORM).result()); 312 } 313 314 TEST_F(ExtensionSimpleFeatureTest, Version) { 315 SimpleFeature feature; 316 feature.set_min_manifest_version(5); 317 318 EXPECT_EQ( 319 Feature::INVALID_MIN_MANIFEST_VERSION, 320 feature.IsAvailableToManifest(std::string(), 321 Manifest::TYPE_UNKNOWN, 322 Feature::UNSPECIFIED_LOCATION, 323 0, 324 Feature::UNSPECIFIED_PLATFORM).result()); 325 EXPECT_EQ( 326 Feature::INVALID_MIN_MANIFEST_VERSION, 327 feature.IsAvailableToManifest(std::string(), 328 Manifest::TYPE_UNKNOWN, 329 Feature::UNSPECIFIED_LOCATION, 330 4, 331 Feature::UNSPECIFIED_PLATFORM).result()); 332 333 EXPECT_EQ( 334 Feature::IS_AVAILABLE, 335 feature.IsAvailableToManifest(std::string(), 336 Manifest::TYPE_UNKNOWN, 337 Feature::UNSPECIFIED_LOCATION, 338 5, 339 Feature::UNSPECIFIED_PLATFORM).result()); 340 EXPECT_EQ( 341 Feature::IS_AVAILABLE, 342 feature.IsAvailableToManifest(std::string(), 343 Manifest::TYPE_UNKNOWN, 344 Feature::UNSPECIFIED_LOCATION, 345 10, 346 Feature::UNSPECIFIED_PLATFORM).result()); 347 348 feature.set_max_manifest_version(8); 349 350 EXPECT_EQ( 351 Feature::INVALID_MAX_MANIFEST_VERSION, 352 feature.IsAvailableToManifest(std::string(), 353 Manifest::TYPE_UNKNOWN, 354 Feature::UNSPECIFIED_LOCATION, 355 10, 356 Feature::UNSPECIFIED_PLATFORM).result()); 357 EXPECT_EQ( 358 Feature::IS_AVAILABLE, 359 feature.IsAvailableToManifest(std::string(), 360 Manifest::TYPE_UNKNOWN, 361 Feature::UNSPECIFIED_LOCATION, 362 8, 363 Feature::UNSPECIFIED_PLATFORM).result()); 364 EXPECT_EQ( 365 Feature::IS_AVAILABLE, 366 feature.IsAvailableToManifest(std::string(), 367 Manifest::TYPE_UNKNOWN, 368 Feature::UNSPECIFIED_LOCATION, 369 7, 370 Feature::UNSPECIFIED_PLATFORM).result()); 371 } 372 373 TEST_F(ExtensionSimpleFeatureTest, ParseNull) { 374 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); 375 scoped_ptr<SimpleFeature> feature(new SimpleFeature()); 376 feature->Parse(value.get()); 377 EXPECT_TRUE(feature->whitelist()->empty()); 378 EXPECT_TRUE(feature->extension_types()->empty()); 379 EXPECT_TRUE(feature->GetContexts()->empty()); 380 EXPECT_EQ(Feature::UNSPECIFIED_LOCATION, feature->location()); 381 EXPECT_TRUE(feature->platforms()->empty()); 382 EXPECT_EQ(0, feature->min_manifest_version()); 383 EXPECT_EQ(0, feature->max_manifest_version()); 384 } 385 386 TEST_F(ExtensionSimpleFeatureTest, ParseWhitelist) { 387 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); 388 base::ListValue* whitelist = new base::ListValue(); 389 whitelist->Append(new base::StringValue("foo")); 390 whitelist->Append(new base::StringValue("bar")); 391 value->Set("whitelist", whitelist); 392 scoped_ptr<SimpleFeature> feature(new SimpleFeature()); 393 feature->Parse(value.get()); 394 EXPECT_EQ(2u, feature->whitelist()->size()); 395 EXPECT_TRUE(feature->whitelist()->count("foo")); 396 EXPECT_TRUE(feature->whitelist()->count("bar")); 397 } 398 399 TEST_F(ExtensionSimpleFeatureTest, ParsePackageTypes) { 400 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); 401 base::ListValue* extension_types = new base::ListValue(); 402 extension_types->Append(new base::StringValue("extension")); 403 extension_types->Append(new base::StringValue("theme")); 404 extension_types->Append(new base::StringValue("legacy_packaged_app")); 405 extension_types->Append(new base::StringValue("hosted_app")); 406 extension_types->Append(new base::StringValue("platform_app")); 407 extension_types->Append(new base::StringValue("shared_module")); 408 value->Set("extension_types", extension_types); 409 scoped_ptr<SimpleFeature> feature(new SimpleFeature()); 410 feature->Parse(value.get()); 411 EXPECT_EQ(6u, feature->extension_types()->size()); 412 EXPECT_TRUE(feature->extension_types()->count(Manifest::TYPE_EXTENSION)); 413 EXPECT_TRUE(feature->extension_types()->count(Manifest::TYPE_THEME)); 414 EXPECT_TRUE(feature->extension_types()->count( 415 Manifest::TYPE_LEGACY_PACKAGED_APP)); 416 EXPECT_TRUE(feature->extension_types()->count(Manifest::TYPE_HOSTED_APP)); 417 EXPECT_TRUE(feature->extension_types()->count(Manifest::TYPE_PLATFORM_APP)); 418 EXPECT_TRUE(feature->extension_types()->count(Manifest::TYPE_SHARED_MODULE)); 419 420 value->SetString("extension_types", "all"); 421 scoped_ptr<SimpleFeature> feature2(new SimpleFeature()); 422 feature2->Parse(value.get()); 423 EXPECT_EQ(*(feature->extension_types()), *(feature2->extension_types())); 424 } 425 426 TEST_F(ExtensionSimpleFeatureTest, ParseContexts) { 427 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); 428 base::ListValue* contexts = new base::ListValue(); 429 contexts->Append(new base::StringValue("blessed_extension")); 430 contexts->Append(new base::StringValue("unblessed_extension")); 431 contexts->Append(new base::StringValue("content_script")); 432 contexts->Append(new base::StringValue("web_page")); 433 contexts->Append(new base::StringValue("blessed_web_page")); 434 value->Set("contexts", contexts); 435 scoped_ptr<SimpleFeature> feature(new SimpleFeature()); 436 feature->Parse(value.get()); 437 EXPECT_EQ(5u, feature->GetContexts()->size()); 438 EXPECT_TRUE( 439 feature->GetContexts()->count(Feature::BLESSED_EXTENSION_CONTEXT)); 440 EXPECT_TRUE( 441 feature->GetContexts()->count(Feature::UNBLESSED_EXTENSION_CONTEXT)); 442 EXPECT_TRUE( 443 feature->GetContexts()->count(Feature::CONTENT_SCRIPT_CONTEXT)); 444 EXPECT_TRUE( 445 feature->GetContexts()->count(Feature::WEB_PAGE_CONTEXT)); 446 EXPECT_TRUE( 447 feature->GetContexts()->count(Feature::BLESSED_WEB_PAGE_CONTEXT)); 448 449 value->SetString("contexts", "all"); 450 scoped_ptr<SimpleFeature> feature2(new SimpleFeature()); 451 feature2->Parse(value.get()); 452 EXPECT_EQ(*(feature->GetContexts()), *(feature2->GetContexts())); 453 } 454 455 TEST_F(ExtensionSimpleFeatureTest, ParseLocation) { 456 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); 457 value->SetString("location", "component"); 458 scoped_ptr<SimpleFeature> feature(new SimpleFeature()); 459 feature->Parse(value.get()); 460 EXPECT_EQ(Feature::COMPONENT_LOCATION, feature->location()); 461 } 462 463 TEST_F(ExtensionSimpleFeatureTest, ParsePlatforms) { 464 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); 465 scoped_ptr<SimpleFeature> feature(new SimpleFeature()); 466 base::ListValue* platforms = new base::ListValue(); 467 value->Set("platforms", platforms); 468 feature->Parse(value.get()); 469 EXPECT_TRUE(feature->platforms()->empty()); 470 471 platforms->AppendString("chromeos"); 472 feature->Parse(value.get()); 473 EXPECT_FALSE(feature->platforms()->empty()); 474 EXPECT_EQ(Feature::CHROMEOS_PLATFORM, *feature->platforms()->begin()); 475 476 platforms->Clear(); 477 platforms->AppendString("win"); 478 feature->Parse(value.get()); 479 EXPECT_FALSE(feature->platforms()->empty()); 480 EXPECT_EQ(Feature::WIN_PLATFORM, *feature->platforms()->begin()); 481 482 platforms->Clear(); 483 platforms->AppendString("win"); 484 platforms->AppendString("chromeos"); 485 feature->Parse(value.get()); 486 std::set<Feature::Platform> expected_platforms; 487 expected_platforms.insert(Feature::CHROMEOS_PLATFORM); 488 expected_platforms.insert(Feature::WIN_PLATFORM); 489 490 EXPECT_FALSE(feature->platforms()->empty()); 491 EXPECT_EQ(expected_platforms, *feature->platforms()); 492 } 493 494 TEST_F(ExtensionSimpleFeatureTest, ManifestVersion) { 495 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); 496 value->SetInteger("min_manifest_version", 1); 497 value->SetInteger("max_manifest_version", 5); 498 scoped_ptr<SimpleFeature> feature(new SimpleFeature()); 499 feature->Parse(value.get()); 500 EXPECT_EQ(1, feature->min_manifest_version()); 501 EXPECT_EQ(5, feature->max_manifest_version()); 502 } 503 504 TEST_F(ExtensionSimpleFeatureTest, Inheritance) { 505 SimpleFeature feature; 506 feature.whitelist()->insert("foo"); 507 feature.extension_types()->insert(Manifest::TYPE_THEME); 508 feature.GetContexts()->insert(Feature::BLESSED_EXTENSION_CONTEXT); 509 feature.set_location(Feature::COMPONENT_LOCATION); 510 feature.platforms()->insert(Feature::CHROMEOS_PLATFORM); 511 feature.set_min_manifest_version(1); 512 feature.set_max_manifest_version(2); 513 514 SimpleFeature feature2 = feature; 515 EXPECT_TRUE(feature2.Equals(feature)); 516 517 base::DictionaryValue definition; 518 feature2.Parse(&definition); 519 EXPECT_TRUE(feature2.Equals(feature)); 520 521 base::ListValue* whitelist = new base::ListValue(); 522 base::ListValue* extension_types = new base::ListValue(); 523 base::ListValue* contexts = new base::ListValue(); 524 whitelist->Append(new base::StringValue("bar")); 525 extension_types->Append(new base::StringValue("extension")); 526 contexts->Append(new base::StringValue("unblessed_extension")); 527 definition.Set("whitelist", whitelist); 528 definition.Set("extension_types", extension_types); 529 definition.Set("contexts", contexts); 530 // Can't test location or platform because we only have one value so far. 531 definition.Set("min_manifest_version", new base::FundamentalValue(2)); 532 definition.Set("max_manifest_version", new base::FundamentalValue(3)); 533 534 feature2.Parse(&definition); 535 EXPECT_FALSE(feature2.Equals(feature)); 536 EXPECT_EQ(1u, feature2.whitelist()->size()); 537 EXPECT_EQ(1u, feature2.extension_types()->size()); 538 EXPECT_EQ(1u, feature2.GetContexts()->size()); 539 EXPECT_EQ(1u, feature2.whitelist()->count("bar")); 540 EXPECT_EQ(1u, feature2.extension_types()->count(Manifest::TYPE_EXTENSION)); 541 EXPECT_EQ(1u, feature2.GetContexts()->count( 542 Feature::UNBLESSED_EXTENSION_CONTEXT)); 543 EXPECT_EQ(2, feature2.min_manifest_version()); 544 EXPECT_EQ(3, feature2.max_manifest_version()); 545 } 546 547 TEST_F(ExtensionSimpleFeatureTest, Equals) { 548 SimpleFeature feature; 549 feature.whitelist()->insert("foo"); 550 feature.extension_types()->insert(Manifest::TYPE_THEME); 551 feature.GetContexts()->insert(Feature::UNBLESSED_EXTENSION_CONTEXT); 552 feature.set_location(Feature::COMPONENT_LOCATION); 553 feature.platforms()->insert(Feature::CHROMEOS_PLATFORM); 554 feature.set_min_manifest_version(18); 555 feature.set_max_manifest_version(25); 556 557 SimpleFeature feature2(feature); 558 EXPECT_TRUE(feature2.Equals(feature)); 559 560 feature2.whitelist()->clear(); 561 EXPECT_FALSE(feature2.Equals(feature)); 562 563 feature2 = feature; 564 feature2.extension_types()->clear(); 565 EXPECT_FALSE(feature2.Equals(feature)); 566 567 feature2 = feature; 568 feature2.GetContexts()->clear(); 569 EXPECT_FALSE(feature2.Equals(feature)); 570 571 feature2 = feature; 572 feature2.set_location(Feature::UNSPECIFIED_LOCATION); 573 EXPECT_FALSE(feature2.Equals(feature)); 574 575 feature2 = feature; 576 feature.platforms()->insert(Feature::UNSPECIFIED_PLATFORM); 577 EXPECT_FALSE(feature2.Equals(feature)); 578 579 feature2 = feature; 580 feature2.set_min_manifest_version(0); 581 EXPECT_FALSE(feature2.Equals(feature)); 582 583 feature2 = feature; 584 feature2.set_max_manifest_version(0); 585 EXPECT_FALSE(feature2.Equals(feature)); 586 } 587 588 Feature::AvailabilityResult IsAvailableInChannel( 589 const std::string& channel, VersionInfo::Channel channel_for_testing) { 590 ScopedCurrentChannel current_channel(channel_for_testing); 591 592 SimpleFeature feature; 593 if (!channel.empty()) { 594 base::DictionaryValue feature_value; 595 feature_value.SetString("channel", channel); 596 feature.Parse(&feature_value); 597 } 598 599 return feature.IsAvailableToManifest( 600 "random-extension", 601 Manifest::TYPE_UNKNOWN, 602 Feature::UNSPECIFIED_LOCATION, 603 -1, 604 Feature::GetCurrentPlatform()).result(); 605 } 606 607 TEST_F(ExtensionSimpleFeatureTest, SupportedChannel) { 608 // stable supported. 609 EXPECT_EQ(Feature::IS_AVAILABLE, 610 IsAvailableInChannel("stable", VersionInfo::CHANNEL_UNKNOWN)); 611 EXPECT_EQ(Feature::IS_AVAILABLE, 612 IsAvailableInChannel("stable", VersionInfo::CHANNEL_CANARY)); 613 EXPECT_EQ(Feature::IS_AVAILABLE, 614 IsAvailableInChannel("stable", VersionInfo::CHANNEL_DEV)); 615 EXPECT_EQ(Feature::IS_AVAILABLE, 616 IsAvailableInChannel("stable", VersionInfo::CHANNEL_BETA)); 617 EXPECT_EQ(Feature::IS_AVAILABLE, 618 IsAvailableInChannel("stable", VersionInfo::CHANNEL_STABLE)); 619 620 // beta supported. 621 EXPECT_EQ(Feature::IS_AVAILABLE, 622 IsAvailableInChannel("beta", VersionInfo::CHANNEL_UNKNOWN)); 623 EXPECT_EQ(Feature::IS_AVAILABLE, 624 IsAvailableInChannel("beta", VersionInfo::CHANNEL_CANARY)); 625 EXPECT_EQ(Feature::IS_AVAILABLE, 626 IsAvailableInChannel("beta", VersionInfo::CHANNEL_DEV)); 627 EXPECT_EQ(Feature::IS_AVAILABLE, 628 IsAvailableInChannel("beta", VersionInfo::CHANNEL_BETA)); 629 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, 630 IsAvailableInChannel("beta", VersionInfo::CHANNEL_STABLE)); 631 632 // dev supported. 633 EXPECT_EQ(Feature::IS_AVAILABLE, 634 IsAvailableInChannel("dev", VersionInfo::CHANNEL_UNKNOWN)); 635 EXPECT_EQ(Feature::IS_AVAILABLE, 636 IsAvailableInChannel("dev", VersionInfo::CHANNEL_CANARY)); 637 EXPECT_EQ(Feature::IS_AVAILABLE, 638 IsAvailableInChannel("dev", VersionInfo::CHANNEL_DEV)); 639 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, 640 IsAvailableInChannel("dev", VersionInfo::CHANNEL_BETA)); 641 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, 642 IsAvailableInChannel("dev", VersionInfo::CHANNEL_STABLE)); 643 644 // canary supported. 645 EXPECT_EQ(Feature::IS_AVAILABLE, 646 IsAvailableInChannel("canary", VersionInfo::CHANNEL_UNKNOWN)); 647 EXPECT_EQ(Feature::IS_AVAILABLE, 648 IsAvailableInChannel("canary", VersionInfo::CHANNEL_CANARY)); 649 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, 650 IsAvailableInChannel("canary", VersionInfo::CHANNEL_DEV)); 651 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, 652 IsAvailableInChannel("canary", VersionInfo::CHANNEL_BETA)); 653 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, 654 IsAvailableInChannel("canary", VersionInfo::CHANNEL_STABLE)); 655 656 // trunk supported. 657 EXPECT_EQ(Feature::IS_AVAILABLE, 658 IsAvailableInChannel("trunk", VersionInfo::CHANNEL_UNKNOWN)); 659 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, 660 IsAvailableInChannel("trunk", VersionInfo::CHANNEL_CANARY)); 661 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, 662 IsAvailableInChannel("trunk", VersionInfo::CHANNEL_DEV)); 663 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, 664 IsAvailableInChannel("trunk", VersionInfo::CHANNEL_BETA)); 665 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, 666 IsAvailableInChannel("trunk", VersionInfo::CHANNEL_STABLE)); 667 } 668 669 } // namespace 670