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