| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "extensions/common/features/simple_feature.h" | 5 #include "extensions/common/features/simple_feature.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/macros.h" | 12 #include "base/macros.h" |
| 13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
| 14 #include "base/test/scoped_command_line.h" | 14 #include "base/test/scoped_command_line.h" |
| 15 #include "base/values.h" | 15 #include "base/values.h" |
| 16 #include "extensions/common/features/api_feature.h" | 16 #include "extensions/common/features/api_feature.h" |
| 17 #include "extensions/common/features/complex_feature.h" | 17 #include "extensions/common/features/complex_feature.h" |
| 18 #include "extensions/common/features/feature_channel.h" | 18 #include "extensions/common/features/feature_channel.h" |
| 19 #include "extensions/common/features/json_feature_provider.h" | |
| 20 #include "extensions/common/features/permission_feature.h" | 19 #include "extensions/common/features/permission_feature.h" |
| 21 #include "extensions/common/manifest.h" | 20 #include "extensions/common/manifest.h" |
| 22 #include "extensions/common/value_builder.h" | 21 #include "extensions/common/value_builder.h" |
| 23 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
| 24 | 23 |
| 24 using version_info::Channel; |
| 25 |
| 25 namespace extensions { | 26 namespace extensions { |
| 26 | 27 |
| 27 namespace { | 28 namespace { |
| 28 | 29 |
| 29 struct IsAvailableTestData { | 30 struct IsAvailableTestData { |
| 30 std::string extension_id; | 31 std::string extension_id; |
| 31 Manifest::Type extension_type; | 32 Manifest::Type extension_type; |
| 32 Manifest::Location location; | 33 Manifest::Location location; |
| 33 Feature::Platform platform; | 34 Feature::Platform platform; |
| 34 int manifest_version; | 35 int manifest_version; |
| 35 Feature::AvailabilityResult expected_result; | 36 Feature::AvailabilityResult expected_result; |
| 36 }; | 37 }; |
| 37 | 38 |
| 38 template <class FeatureClass> | 39 template <class FeatureClass> |
| 39 SimpleFeature* CreateFeature() { | 40 SimpleFeature* CreateFeature() { |
| 40 return new FeatureClass(); | 41 return new FeatureClass(); |
| 41 } | 42 } |
| 42 | 43 |
| 43 Feature::AvailabilityResult IsAvailableInChannel( | 44 Feature::AvailabilityResult IsAvailableInChannel(Channel channel_for_feature, |
| 44 const std::string& channel, | 45 Channel channel_for_testing) { |
| 45 version_info::Channel channel_for_testing) { | |
| 46 ScopedCurrentChannel current_channel(channel_for_testing); | 46 ScopedCurrentChannel current_channel(channel_for_testing); |
| 47 | 47 |
| 48 SimpleFeature feature; | 48 SimpleFeature feature; |
| 49 | 49 feature.set_channel(channel_for_feature); |
| 50 base::DictionaryValue feature_value; | |
| 51 feature_value.SetString("channel", channel); | |
| 52 feature.Parse(&feature_value); | |
| 53 | |
| 54 return feature | 50 return feature |
| 55 .IsAvailableToManifest("random-extension", Manifest::TYPE_UNKNOWN, | 51 .IsAvailableToManifest("random-extension", Manifest::TYPE_UNKNOWN, |
| 56 Manifest::INVALID_LOCATION, -1, | 52 Manifest::INVALID_LOCATION, -1, |
| 57 Feature::GetCurrentPlatform()) | 53 Feature::GetCurrentPlatform()) |
| 58 .result(); | 54 .result(); |
| 59 } | 55 } |
| 60 | 56 |
| 61 } // namespace | 57 } // namespace |
| 62 | 58 |
| 63 class SimpleFeatureTest : public testing::Test { | 59 class SimpleFeatureTest : public testing::Test { |
| 64 protected: | 60 protected: |
| 65 SimpleFeatureTest() : current_channel_(version_info::Channel::UNKNOWN) {} | 61 SimpleFeatureTest() : current_channel_(Channel::UNKNOWN) {} |
| 66 bool LocationIsAvailable(SimpleFeature::Location feature_location, | 62 bool LocationIsAvailable(SimpleFeature::Location feature_location, |
| 67 Manifest::Location manifest_location) { | 63 Manifest::Location manifest_location) { |
| 68 SimpleFeature feature; | 64 SimpleFeature feature; |
| 69 feature.set_location(feature_location); | 65 feature.set_location(feature_location); |
| 70 Feature::AvailabilityResult availability_result = | 66 Feature::AvailabilityResult availability_result = |
| 71 feature.IsAvailableToManifest(std::string(), | 67 feature.IsAvailableToManifest(std::string(), |
| 72 Manifest::TYPE_UNKNOWN, | 68 Manifest::TYPE_UNKNOWN, |
| 73 manifest_location, | 69 manifest_location, |
| 74 -1, | 70 -1, |
| 75 Feature::UNSPECIFIED_PLATFORM).result(); | 71 Feature::UNSPECIFIED_PLATFORM).result(); |
| (...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 Feature::UNSPECIFIED_PLATFORM).result()); | 515 Feature::UNSPECIFIED_PLATFORM).result()); |
| 520 EXPECT_EQ( | 516 EXPECT_EQ( |
| 521 Feature::IS_AVAILABLE, | 517 Feature::IS_AVAILABLE, |
| 522 feature.IsAvailableToManifest(std::string(), | 518 feature.IsAvailableToManifest(std::string(), |
| 523 Manifest::TYPE_UNKNOWN, | 519 Manifest::TYPE_UNKNOWN, |
| 524 Manifest::INVALID_LOCATION, | 520 Manifest::INVALID_LOCATION, |
| 525 7, | 521 7, |
| 526 Feature::UNSPECIFIED_PLATFORM).result()); | 522 Feature::UNSPECIFIED_PLATFORM).result()); |
| 527 } | 523 } |
| 528 | 524 |
| 529 TEST_F(SimpleFeatureTest, ParseNull) { | |
| 530 std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue()); | |
| 531 std::unique_ptr<SimpleFeature> feature(new SimpleFeature()); | |
| 532 feature->Parse(value.get()); | |
| 533 EXPECT_TRUE(feature->whitelist().empty()); | |
| 534 EXPECT_TRUE(feature->extension_types().empty()); | |
| 535 EXPECT_TRUE(feature->contexts().empty()); | |
| 536 EXPECT_EQ(SimpleFeature::UNSPECIFIED_LOCATION, feature->location()); | |
| 537 EXPECT_TRUE(feature->platforms().empty()); | |
| 538 EXPECT_EQ(0, feature->min_manifest_version()); | |
| 539 EXPECT_EQ(0, feature->max_manifest_version()); | |
| 540 } | |
| 541 | |
| 542 TEST_F(SimpleFeatureTest, ParseWhitelist) { | |
| 543 std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue()); | |
| 544 base::ListValue* whitelist = new base::ListValue(); | |
| 545 whitelist->AppendString("foo"); | |
| 546 whitelist->AppendString("bar"); | |
| 547 value->Set("whitelist", whitelist); | |
| 548 std::unique_ptr<SimpleFeature> feature(new SimpleFeature()); | |
| 549 feature->Parse(value.get()); | |
| 550 EXPECT_EQ(2u, feature->whitelist().size()); | |
| 551 EXPECT_TRUE(base::STLCount(feature->whitelist(), "foo")); | |
| 552 EXPECT_TRUE(base::STLCount(feature->whitelist(), "bar")); | |
| 553 } | |
| 554 | |
| 555 TEST_F(SimpleFeatureTest, ParsePackageTypes) { | |
| 556 std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue()); | |
| 557 base::ListValue* extension_types = new base::ListValue(); | |
| 558 extension_types->AppendString("extension"); | |
| 559 extension_types->AppendString("theme"); | |
| 560 extension_types->AppendString("legacy_packaged_app"); | |
| 561 extension_types->AppendString("hosted_app"); | |
| 562 extension_types->AppendString("platform_app"); | |
| 563 extension_types->AppendString("shared_module"); | |
| 564 value->Set("extension_types", extension_types); | |
| 565 std::unique_ptr<SimpleFeature> feature(new SimpleFeature()); | |
| 566 feature->Parse(value.get()); | |
| 567 EXPECT_EQ(6u, feature->extension_types().size()); | |
| 568 EXPECT_TRUE( | |
| 569 base::STLCount(feature->extension_types(), Manifest::TYPE_EXTENSION)); | |
| 570 EXPECT_TRUE(base::STLCount(feature->extension_types(), Manifest::TYPE_THEME)); | |
| 571 EXPECT_TRUE(base::STLCount(feature->extension_types(), | |
| 572 Manifest::TYPE_LEGACY_PACKAGED_APP)); | |
| 573 EXPECT_TRUE( | |
| 574 base::STLCount(feature->extension_types(), Manifest::TYPE_HOSTED_APP)); | |
| 575 EXPECT_TRUE( | |
| 576 base::STLCount(feature->extension_types(), Manifest::TYPE_PLATFORM_APP)); | |
| 577 EXPECT_TRUE( | |
| 578 base::STLCount(feature->extension_types(), Manifest::TYPE_SHARED_MODULE)); | |
| 579 | |
| 580 value->SetString("extension_types", "all"); | |
| 581 std::unique_ptr<SimpleFeature> feature2(new SimpleFeature()); | |
| 582 feature2->Parse(value.get()); | |
| 583 EXPECT_EQ(feature->extension_types(), feature2->extension_types()); | |
| 584 } | |
| 585 | |
| 586 TEST_F(SimpleFeatureTest, ParseContexts) { | |
| 587 std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue()); | |
| 588 base::ListValue* contexts = new base::ListValue(); | |
| 589 contexts->AppendString("blessed_extension"); | |
| 590 contexts->AppendString("unblessed_extension"); | |
| 591 contexts->AppendString("content_script"); | |
| 592 contexts->AppendString("web_page"); | |
| 593 contexts->AppendString("blessed_web_page"); | |
| 594 contexts->AppendString("webui"); | |
| 595 contexts->AppendString("extension_service_worker"); | |
| 596 value->Set("contexts", contexts); | |
| 597 std::unique_ptr<SimpleFeature> feature(new SimpleFeature()); | |
| 598 feature->Parse(value.get()); | |
| 599 EXPECT_EQ(7u, feature->contexts().size()); | |
| 600 EXPECT_TRUE( | |
| 601 base::STLCount(feature->contexts(), Feature::BLESSED_EXTENSION_CONTEXT)); | |
| 602 EXPECT_TRUE(base::STLCount(feature->contexts(), | |
| 603 Feature::UNBLESSED_EXTENSION_CONTEXT)); | |
| 604 EXPECT_TRUE( | |
| 605 base::STLCount(feature->contexts(), Feature::CONTENT_SCRIPT_CONTEXT)); | |
| 606 EXPECT_TRUE(base::STLCount(feature->contexts(), Feature::WEB_PAGE_CONTEXT)); | |
| 607 EXPECT_TRUE( | |
| 608 base::STLCount(feature->contexts(), Feature::BLESSED_WEB_PAGE_CONTEXT)); | |
| 609 | |
| 610 value->SetString("contexts", "all"); | |
| 611 std::unique_ptr<SimpleFeature> feature2(new SimpleFeature()); | |
| 612 feature2->Parse(value.get()); | |
| 613 EXPECT_EQ(feature->contexts(), feature2->contexts()); | |
| 614 } | |
| 615 | |
| 616 TEST_F(SimpleFeatureTest, ParseLocation) { | |
| 617 std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue()); | |
| 618 value->SetString("location", "component"); | |
| 619 std::unique_ptr<SimpleFeature> feature(new SimpleFeature()); | |
| 620 feature->Parse(value.get()); | |
| 621 EXPECT_EQ(SimpleFeature::COMPONENT_LOCATION, feature->location()); | |
| 622 } | |
| 623 | |
| 624 TEST_F(SimpleFeatureTest, ParsePlatforms) { | |
| 625 std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue()); | |
| 626 std::unique_ptr<SimpleFeature> feature(new SimpleFeature()); | |
| 627 base::ListValue* platforms = new base::ListValue(); | |
| 628 value->Set("platforms", platforms); | |
| 629 feature->Parse(value.get()); | |
| 630 EXPECT_TRUE(feature->platforms().empty()); | |
| 631 | |
| 632 platforms->AppendString("chromeos"); | |
| 633 feature->Parse(value.get()); | |
| 634 EXPECT_FALSE(feature->platforms().empty()); | |
| 635 EXPECT_EQ(Feature::CHROMEOS_PLATFORM, *feature->platforms().begin()); | |
| 636 | |
| 637 platforms->Clear(); | |
| 638 platforms->AppendString("win"); | |
| 639 feature->Parse(value.get()); | |
| 640 EXPECT_FALSE(feature->platforms().empty()); | |
| 641 EXPECT_EQ(Feature::WIN_PLATFORM, *feature->platforms().begin()); | |
| 642 | |
| 643 platforms->Clear(); | |
| 644 platforms->AppendString("win"); | |
| 645 platforms->AppendString("chromeos"); | |
| 646 feature->Parse(value.get()); | |
| 647 std::vector<Feature::Platform> expected_platforms; | |
| 648 expected_platforms.push_back(Feature::CHROMEOS_PLATFORM); | |
| 649 expected_platforms.push_back(Feature::WIN_PLATFORM); | |
| 650 | |
| 651 EXPECT_FALSE(feature->platforms().empty()); | |
| 652 EXPECT_EQ(expected_platforms, feature->platforms()); | |
| 653 } | |
| 654 | |
| 655 TEST_F(SimpleFeatureTest, ParseManifestVersion) { | |
| 656 std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue()); | |
| 657 value->SetInteger("min_manifest_version", 1); | |
| 658 value->SetInteger("max_manifest_version", 5); | |
| 659 std::unique_ptr<SimpleFeature> feature(new SimpleFeature()); | |
| 660 feature->Parse(value.get()); | |
| 661 EXPECT_EQ(1, feature->min_manifest_version()); | |
| 662 EXPECT_EQ(5, feature->max_manifest_version()); | |
| 663 } | |
| 664 | |
| 665 TEST_F(SimpleFeatureTest, Inheritance) { | |
| 666 SimpleFeature feature; | |
| 667 feature.whitelist_.push_back("foo"); | |
| 668 feature.extension_types_.push_back(Manifest::TYPE_THEME); | |
| 669 feature.contexts_.push_back(Feature::BLESSED_EXTENSION_CONTEXT); | |
| 670 feature.set_location(SimpleFeature::COMPONENT_LOCATION); | |
| 671 feature.platforms_.push_back(Feature::CHROMEOS_PLATFORM); | |
| 672 feature.set_min_manifest_version(1); | |
| 673 feature.set_max_manifest_version(2); | |
| 674 | |
| 675 // Test additive parsing. Parsing an empty dictionary should result in no | |
| 676 // changes to a SimpleFeature. | |
| 677 base::DictionaryValue definition; | |
| 678 feature.Parse(&definition); | |
| 679 EXPECT_EQ(1u, feature.whitelist().size()); | |
| 680 EXPECT_EQ(1u, feature.extension_types().size()); | |
| 681 EXPECT_EQ(1u, feature.contexts().size()); | |
| 682 EXPECT_EQ(1, base::STLCount(feature.whitelist(), "foo")); | |
| 683 EXPECT_EQ(SimpleFeature::COMPONENT_LOCATION, feature.location()); | |
| 684 EXPECT_EQ(1u, feature.platforms().size()); | |
| 685 EXPECT_EQ(1, base::STLCount(feature.platforms(), Feature::CHROMEOS_PLATFORM)); | |
| 686 EXPECT_EQ(1, feature.min_manifest_version()); | |
| 687 EXPECT_EQ(2, feature.max_manifest_version()); | |
| 688 | |
| 689 base::ListValue* whitelist = new base::ListValue(); | |
| 690 base::ListValue* extension_types = new base::ListValue(); | |
| 691 base::ListValue* contexts = new base::ListValue(); | |
| 692 whitelist->AppendString("bar"); | |
| 693 extension_types->AppendString("extension"); | |
| 694 contexts->AppendString("unblessed_extension"); | |
| 695 definition.Set("whitelist", whitelist); | |
| 696 definition.Set("extension_types", extension_types); | |
| 697 definition.Set("contexts", contexts); | |
| 698 // Can't test location or platform because we only have one value so far. | |
| 699 definition.Set("min_manifest_version", new base::FundamentalValue(2)); | |
| 700 definition.Set("max_manifest_version", new base::FundamentalValue(3)); | |
| 701 | |
| 702 feature.Parse(&definition); | |
| 703 EXPECT_EQ(1u, feature.whitelist().size()); | |
| 704 EXPECT_EQ(1u, feature.extension_types().size()); | |
| 705 EXPECT_EQ(1u, feature.contexts().size()); | |
| 706 EXPECT_EQ(1, base::STLCount(feature.whitelist(), "bar")); | |
| 707 EXPECT_EQ( | |
| 708 1, base::STLCount(feature.extension_types(), Manifest::TYPE_EXTENSION)); | |
| 709 EXPECT_EQ(1, base::STLCount(feature.contexts(), | |
| 710 Feature::UNBLESSED_EXTENSION_CONTEXT)); | |
| 711 EXPECT_EQ(2, feature.min_manifest_version()); | |
| 712 EXPECT_EQ(3, feature.max_manifest_version()); | |
| 713 } | |
| 714 | |
| 715 TEST_F(SimpleFeatureTest, CommandLineSwitch) { | 525 TEST_F(SimpleFeatureTest, CommandLineSwitch) { |
| 716 SimpleFeature feature; | 526 SimpleFeature feature; |
| 717 feature.set_command_line_switch("laser-beams"); | 527 feature.set_command_line_switch("laser-beams"); |
| 718 { | 528 { |
| 719 EXPECT_EQ(Feature::MISSING_COMMAND_LINE_SWITCH, | 529 EXPECT_EQ(Feature::MISSING_COMMAND_LINE_SWITCH, |
| 720 feature.IsAvailableToEnvironment().result()); | 530 feature.IsAvailableToEnvironment().result()); |
| 721 } | 531 } |
| 722 { | 532 { |
| 723 base::test::ScopedCommandLine scoped_command_line; | 533 base::test::ScopedCommandLine scoped_command_line; |
| 724 scoped_command_line.GetProcessCommandLine()->AppendSwitch("laser-beams"); | 534 scoped_command_line.GetProcessCommandLine()->AppendSwitch("laser-beams"); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 770 "bbbbccccdddddddddeeeeeeffffgghhh", kIdArray, arraysize(kIdArray))); | 580 "bbbbccccdddddddddeeeeeeffffgghhh", kIdArray, arraysize(kIdArray))); |
| 771 EXPECT_TRUE(SimpleFeature::IsIdInArray( | 581 EXPECT_TRUE(SimpleFeature::IsIdInArray( |
| 772 "aaaabbbbccccddddeeeeffffgggghhhh", kIdArray, arraysize(kIdArray))); | 582 "aaaabbbbccccddddeeeeffffgggghhhh", kIdArray, arraysize(kIdArray))); |
| 773 } | 583 } |
| 774 | 584 |
| 775 // Tests that all combinations of feature channel and Chrome channel correctly | 585 // Tests that all combinations of feature channel and Chrome channel correctly |
| 776 // compute feature availability. | 586 // compute feature availability. |
| 777 TEST_F(SimpleFeatureTest, SupportedChannel) { | 587 TEST_F(SimpleFeatureTest, SupportedChannel) { |
| 778 // stable supported. | 588 // stable supported. |
| 779 EXPECT_EQ(Feature::IS_AVAILABLE, | 589 EXPECT_EQ(Feature::IS_AVAILABLE, |
| 780 IsAvailableInChannel("stable", version_info::Channel::UNKNOWN)); | 590 IsAvailableInChannel(Channel::STABLE, Channel::UNKNOWN)); |
| 781 EXPECT_EQ(Feature::IS_AVAILABLE, | 591 EXPECT_EQ(Feature::IS_AVAILABLE, |
| 782 IsAvailableInChannel("stable", version_info::Channel::CANARY)); | 592 IsAvailableInChannel(Channel::STABLE, Channel::CANARY)); |
| 783 EXPECT_EQ(Feature::IS_AVAILABLE, | 593 EXPECT_EQ(Feature::IS_AVAILABLE, |
| 784 IsAvailableInChannel("stable", version_info::Channel::DEV)); | 594 IsAvailableInChannel(Channel::STABLE, Channel::DEV)); |
| 785 EXPECT_EQ(Feature::IS_AVAILABLE, | 595 EXPECT_EQ(Feature::IS_AVAILABLE, |
| 786 IsAvailableInChannel("stable", version_info::Channel::BETA)); | 596 IsAvailableInChannel(Channel::STABLE, Channel::BETA)); |
| 787 EXPECT_EQ(Feature::IS_AVAILABLE, | 597 EXPECT_EQ(Feature::IS_AVAILABLE, |
| 788 IsAvailableInChannel("stable", version_info::Channel::STABLE)); | 598 IsAvailableInChannel(Channel::STABLE, Channel::STABLE)); |
| 789 | 599 |
| 790 // beta supported. | 600 // beta supported. |
| 791 EXPECT_EQ(Feature::IS_AVAILABLE, | 601 EXPECT_EQ(Feature::IS_AVAILABLE, |
| 792 IsAvailableInChannel("beta", version_info::Channel::UNKNOWN)); | 602 IsAvailableInChannel(Channel::BETA, Channel::UNKNOWN)); |
| 793 EXPECT_EQ(Feature::IS_AVAILABLE, | 603 EXPECT_EQ(Feature::IS_AVAILABLE, |
| 794 IsAvailableInChannel("beta", version_info::Channel::CANARY)); | 604 IsAvailableInChannel(Channel::BETA, Channel::CANARY)); |
| 795 EXPECT_EQ(Feature::IS_AVAILABLE, | 605 EXPECT_EQ(Feature::IS_AVAILABLE, |
| 796 IsAvailableInChannel("beta", version_info::Channel::DEV)); | 606 IsAvailableInChannel(Channel::BETA, Channel::DEV)); |
| 797 EXPECT_EQ(Feature::IS_AVAILABLE, | 607 EXPECT_EQ(Feature::IS_AVAILABLE, |
| 798 IsAvailableInChannel("beta", version_info::Channel::BETA)); | 608 IsAvailableInChannel(Channel::BETA, Channel::BETA)); |
| 799 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, | 609 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, |
| 800 IsAvailableInChannel("beta", version_info::Channel::STABLE)); | 610 IsAvailableInChannel(Channel::BETA, Channel::STABLE)); |
| 801 | 611 |
| 802 // dev supported. | 612 // dev supported. |
| 803 EXPECT_EQ(Feature::IS_AVAILABLE, | 613 EXPECT_EQ(Feature::IS_AVAILABLE, |
| 804 IsAvailableInChannel("dev", version_info::Channel::UNKNOWN)); | 614 IsAvailableInChannel(Channel::DEV, Channel::UNKNOWN)); |
| 805 EXPECT_EQ(Feature::IS_AVAILABLE, | 615 EXPECT_EQ(Feature::IS_AVAILABLE, |
| 806 IsAvailableInChannel("dev", version_info::Channel::CANARY)); | 616 IsAvailableInChannel(Channel::DEV, Channel::CANARY)); |
| 807 EXPECT_EQ(Feature::IS_AVAILABLE, | 617 EXPECT_EQ(Feature::IS_AVAILABLE, |
| 808 IsAvailableInChannel("dev", version_info::Channel::DEV)); | 618 IsAvailableInChannel(Channel::DEV, Channel::DEV)); |
| 809 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, | 619 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, |
| 810 IsAvailableInChannel("dev", version_info::Channel::BETA)); | 620 IsAvailableInChannel(Channel::DEV, Channel::BETA)); |
| 811 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, | 621 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, |
| 812 IsAvailableInChannel("dev", version_info::Channel::STABLE)); | 622 IsAvailableInChannel(Channel::DEV, Channel::STABLE)); |
| 813 | 623 |
| 814 // canary supported. | 624 // canary supported. |
| 815 EXPECT_EQ(Feature::IS_AVAILABLE, | 625 EXPECT_EQ(Feature::IS_AVAILABLE, |
| 816 IsAvailableInChannel("canary", version_info::Channel::UNKNOWN)); | 626 IsAvailableInChannel(Channel::CANARY, Channel::UNKNOWN)); |
| 817 EXPECT_EQ(Feature::IS_AVAILABLE, | 627 EXPECT_EQ(Feature::IS_AVAILABLE, |
| 818 IsAvailableInChannel("canary", version_info::Channel::CANARY)); | 628 IsAvailableInChannel(Channel::CANARY, Channel::CANARY)); |
| 819 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, | 629 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, |
| 820 IsAvailableInChannel("canary", version_info::Channel::DEV)); | 630 IsAvailableInChannel(Channel::CANARY, Channel::DEV)); |
| 821 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, | 631 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, |
| 822 IsAvailableInChannel("canary", version_info::Channel::BETA)); | 632 IsAvailableInChannel(Channel::CANARY, Channel::BETA)); |
| 823 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, | 633 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, |
| 824 IsAvailableInChannel("canary", version_info::Channel::STABLE)); | 634 IsAvailableInChannel(Channel::CANARY, Channel::STABLE)); |
| 825 | 635 |
| 826 // trunk supported. | 636 // trunk supported. |
| 827 EXPECT_EQ(Feature::IS_AVAILABLE, | 637 EXPECT_EQ(Feature::IS_AVAILABLE, |
| 828 IsAvailableInChannel("trunk", version_info::Channel::UNKNOWN)); | 638 IsAvailableInChannel(Channel::UNKNOWN, Channel::UNKNOWN)); |
| 829 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, | 639 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, |
| 830 IsAvailableInChannel("trunk", version_info::Channel::CANARY)); | 640 IsAvailableInChannel(Channel::UNKNOWN, Channel::CANARY)); |
| 831 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, | 641 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, |
| 832 IsAvailableInChannel("trunk", version_info::Channel::DEV)); | 642 IsAvailableInChannel(Channel::UNKNOWN, Channel::DEV)); |
| 833 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, | 643 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, |
| 834 IsAvailableInChannel("trunk", version_info::Channel::BETA)); | 644 IsAvailableInChannel(Channel::UNKNOWN, Channel::BETA)); |
| 835 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, | 645 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, |
| 836 IsAvailableInChannel("trunk", version_info::Channel::STABLE)); | 646 IsAvailableInChannel(Channel::UNKNOWN, Channel::STABLE)); |
| 837 } | |
| 838 | |
| 839 // Tests the validation of features with channel entries. | |
| 840 TEST_F(SimpleFeatureTest, FeatureValidation) { | |
| 841 std::string error; | |
| 842 { | |
| 843 PermissionFeature feature; | |
| 844 feature.channel_.reset( | |
| 845 new version_info::Channel(version_info::Channel::UNKNOWN)); | |
| 846 // The feature won't validate because it lacks an extension type. | |
| 847 EXPECT_FALSE(feature.Validate(&error)); | |
| 848 // If we add one, it works. | |
| 849 feature.extension_types_.push_back(Manifest::TYPE_EXTENSION); | |
| 850 EXPECT_TRUE(feature.Validate(&error)); | |
| 851 // Remove the channel, and feature1 won't validate. | |
| 852 feature.channel_.reset(); | |
| 853 EXPECT_FALSE(feature.Validate(&error)); | |
| 854 } | |
| 855 { | |
| 856 PermissionFeature feature; | |
| 857 feature.channel_.reset( | |
| 858 new version_info::Channel(version_info::Channel::UNKNOWN)); | |
| 859 feature.extension_types_.push_back(Manifest::TYPE_EXTENSION); | |
| 860 feature.contexts_.push_back(Feature::BLESSED_EXTENSION_CONTEXT); | |
| 861 // The feature won't validate because of the presence of "contexts". | |
| 862 EXPECT_FALSE(feature.Validate(&error)); | |
| 863 feature.contexts_.clear(); | |
| 864 EXPECT_TRUE(feature.Validate(&error)); | |
| 865 } | |
| 866 { | |
| 867 APIFeature feature; | |
| 868 feature.channel_.reset( | |
| 869 new version_info::Channel(version_info::Channel::STABLE)); | |
| 870 // API features require contexts. | |
| 871 EXPECT_FALSE(feature.Validate(&error)); | |
| 872 feature.contexts_.push_back(Feature::CONTENT_SCRIPT_CONTEXT); | |
| 873 EXPECT_TRUE(feature.Validate(&error)); | |
| 874 } | |
| 875 } | 647 } |
| 876 | 648 |
| 877 // Tests simple feature availability across channels. | 649 // Tests simple feature availability across channels. |
| 878 TEST_F(SimpleFeatureTest, SimpleFeatureAvailability) { | 650 TEST_F(SimpleFeatureTest, SimpleFeatureAvailability) { |
| 879 std::unique_ptr<ComplexFeature> complex_feature; | 651 std::unique_ptr<ComplexFeature> complex_feature; |
| 880 { | 652 { |
| 881 std::unique_ptr<SimpleFeature> feature1(CreateFeature<SimpleFeature>()); | 653 std::unique_ptr<SimpleFeature> feature1(CreateFeature<SimpleFeature>()); |
| 882 feature1->channel_.reset( | 654 feature1->channel_.reset(new Channel(Channel::BETA)); |
| 883 new version_info::Channel(version_info::Channel::BETA)); | |
| 884 feature1->extension_types_.push_back(Manifest::TYPE_EXTENSION); | 655 feature1->extension_types_.push_back(Manifest::TYPE_EXTENSION); |
| 885 std::unique_ptr<SimpleFeature> feature2(CreateFeature<SimpleFeature>()); | 656 std::unique_ptr<SimpleFeature> feature2(CreateFeature<SimpleFeature>()); |
| 886 feature2->channel_.reset( | 657 feature2->channel_.reset(new Channel(Channel::BETA)); |
| 887 new version_info::Channel(version_info::Channel::BETA)); | |
| 888 feature2->extension_types_.push_back(Manifest::TYPE_LEGACY_PACKAGED_APP); | 658 feature2->extension_types_.push_back(Manifest::TYPE_LEGACY_PACKAGED_APP); |
| 889 std::vector<Feature*> list; | 659 std::vector<Feature*> list; |
| 890 list.push_back(feature1.release()); | 660 list.push_back(feature1.release()); |
| 891 list.push_back(feature2.release()); | 661 list.push_back(feature2.release()); |
| 892 complex_feature.reset(new ComplexFeature(&list)); | 662 complex_feature.reset(new ComplexFeature(&list)); |
| 893 } | 663 } |
| 894 | 664 |
| 895 Feature* feature = static_cast<Feature*>(complex_feature.get()); | 665 Feature* feature = static_cast<Feature*>(complex_feature.get()); |
| 896 // Make sure both rules are applied correctly. | 666 // Make sure both rules are applied correctly. |
| 897 { | 667 { |
| 898 ScopedCurrentChannel current_channel(version_info::Channel::BETA); | 668 ScopedCurrentChannel current_channel(Channel::BETA); |
| 899 EXPECT_EQ( | 669 EXPECT_EQ( |
| 900 Feature::IS_AVAILABLE, | 670 Feature::IS_AVAILABLE, |
| 901 feature->IsAvailableToManifest("1", | 671 feature->IsAvailableToManifest("1", |
| 902 Manifest::TYPE_EXTENSION, | 672 Manifest::TYPE_EXTENSION, |
| 903 Manifest::INVALID_LOCATION, | 673 Manifest::INVALID_LOCATION, |
| 904 Feature::UNSPECIFIED_PLATFORM).result()); | 674 Feature::UNSPECIFIED_PLATFORM).result()); |
| 905 EXPECT_EQ( | 675 EXPECT_EQ( |
| 906 Feature::IS_AVAILABLE, | 676 Feature::IS_AVAILABLE, |
| 907 feature->IsAvailableToManifest("2", | 677 feature->IsAvailableToManifest("2", |
| 908 Manifest::TYPE_LEGACY_PACKAGED_APP, | 678 Manifest::TYPE_LEGACY_PACKAGED_APP, |
| 909 Manifest::INVALID_LOCATION, | 679 Manifest::INVALID_LOCATION, |
| 910 Feature::UNSPECIFIED_PLATFORM).result()); | 680 Feature::UNSPECIFIED_PLATFORM).result()); |
| 911 } | 681 } |
| 912 { | 682 { |
| 913 ScopedCurrentChannel current_channel(version_info::Channel::STABLE); | 683 ScopedCurrentChannel current_channel(Channel::STABLE); |
| 914 EXPECT_NE( | 684 EXPECT_NE( |
| 915 Feature::IS_AVAILABLE, | 685 Feature::IS_AVAILABLE, |
| 916 feature->IsAvailableToManifest("1", | 686 feature->IsAvailableToManifest("1", |
| 917 Manifest::TYPE_EXTENSION, | 687 Manifest::TYPE_EXTENSION, |
| 918 Manifest::INVALID_LOCATION, | 688 Manifest::INVALID_LOCATION, |
| 919 Feature::UNSPECIFIED_PLATFORM).result()); | 689 Feature::UNSPECIFIED_PLATFORM).result()); |
| 920 EXPECT_NE( | 690 EXPECT_NE( |
| 921 Feature::IS_AVAILABLE, | 691 Feature::IS_AVAILABLE, |
| 922 feature->IsAvailableToManifest("2", | 692 feature->IsAvailableToManifest("2", |
| 923 Manifest::TYPE_LEGACY_PACKAGED_APP, | 693 Manifest::TYPE_LEGACY_PACKAGED_APP, |
| 924 Manifest::INVALID_LOCATION, | 694 Manifest::INVALID_LOCATION, |
| 925 Feature::UNSPECIFIED_PLATFORM).result()); | 695 Feature::UNSPECIFIED_PLATFORM).result()); |
| 926 } | 696 } |
| 927 } | 697 } |
| 928 | 698 |
| 929 // Tests complex feature availability across channels. | 699 // Tests complex feature availability across channels. |
| 930 TEST_F(SimpleFeatureTest, ComplexFeatureAvailability) { | 700 TEST_F(SimpleFeatureTest, ComplexFeatureAvailability) { |
| 931 std::unique_ptr<ComplexFeature> complex_feature; | 701 std::unique_ptr<ComplexFeature> complex_feature; |
| 932 { | 702 { |
| 933 // Rule: "extension", channel trunk. | 703 // Rule: "extension", channel trunk. |
| 934 std::unique_ptr<SimpleFeature> feature1(CreateFeature<SimpleFeature>()); | 704 std::unique_ptr<SimpleFeature> feature1(CreateFeature<SimpleFeature>()); |
| 935 feature1->channel_.reset( | 705 feature1->channel_.reset(new Channel(Channel::UNKNOWN)); |
| 936 new version_info::Channel(version_info::Channel::UNKNOWN)); | |
| 937 feature1->extension_types_.push_back(Manifest::TYPE_EXTENSION); | 706 feature1->extension_types_.push_back(Manifest::TYPE_EXTENSION); |
| 938 std::unique_ptr<SimpleFeature> feature2(CreateFeature<SimpleFeature>()); | 707 std::unique_ptr<SimpleFeature> feature2(CreateFeature<SimpleFeature>()); |
| 939 // Rule: "legacy_packaged_app", channel stable. | 708 // Rule: "legacy_packaged_app", channel stable. |
| 940 feature2->channel_.reset( | 709 feature2->channel_.reset(new Channel(Channel::STABLE)); |
| 941 new version_info::Channel(version_info::Channel::STABLE)); | |
| 942 feature2->extension_types_.push_back(Manifest::TYPE_LEGACY_PACKAGED_APP); | 710 feature2->extension_types_.push_back(Manifest::TYPE_LEGACY_PACKAGED_APP); |
| 943 std::vector<Feature*> list; | 711 std::vector<Feature*> list; |
| 944 list.push_back(feature1.release()); | 712 list.push_back(feature1.release()); |
| 945 list.push_back(feature2.release()); | 713 list.push_back(feature2.release()); |
| 946 complex_feature.reset(new ComplexFeature(&list)); | 714 complex_feature.reset(new ComplexFeature(&list)); |
| 947 } | 715 } |
| 948 | 716 |
| 949 Feature* feature = static_cast<Feature*>(complex_feature.get()); | 717 Feature* feature = static_cast<Feature*>(complex_feature.get()); |
| 950 { | 718 { |
| 951 ScopedCurrentChannel current_channel(version_info::Channel::UNKNOWN); | 719 ScopedCurrentChannel current_channel(Channel::UNKNOWN); |
| 952 EXPECT_EQ(Feature::IS_AVAILABLE, | 720 EXPECT_EQ(Feature::IS_AVAILABLE, |
| 953 feature | 721 feature |
| 954 ->IsAvailableToManifest("1", Manifest::TYPE_EXTENSION, | 722 ->IsAvailableToManifest("1", Manifest::TYPE_EXTENSION, |
| 955 Manifest::INVALID_LOCATION, | 723 Manifest::INVALID_LOCATION, |
| 956 Feature::UNSPECIFIED_PLATFORM) | 724 Feature::UNSPECIFIED_PLATFORM) |
| 957 .result()); | 725 .result()); |
| 958 } | 726 } |
| 959 { | 727 { |
| 960 ScopedCurrentChannel current_channel(version_info::Channel::BETA); | 728 ScopedCurrentChannel current_channel(Channel::BETA); |
| 961 EXPECT_EQ(Feature::IS_AVAILABLE, | 729 EXPECT_EQ(Feature::IS_AVAILABLE, |
| 962 feature | 730 feature |
| 963 ->IsAvailableToManifest( | 731 ->IsAvailableToManifest( |
| 964 "2", Manifest::TYPE_LEGACY_PACKAGED_APP, | 732 "2", Manifest::TYPE_LEGACY_PACKAGED_APP, |
| 965 Manifest::INVALID_LOCATION, Feature::UNSPECIFIED_PLATFORM) | 733 Manifest::INVALID_LOCATION, Feature::UNSPECIFIED_PLATFORM) |
| 966 .result()); | 734 .result()); |
| 967 } | 735 } |
| 968 { | 736 { |
| 969 ScopedCurrentChannel current_channel(version_info::Channel::BETA); | 737 ScopedCurrentChannel current_channel(Channel::BETA); |
| 970 EXPECT_NE(Feature::IS_AVAILABLE, | 738 EXPECT_NE(Feature::IS_AVAILABLE, |
| 971 feature | 739 feature |
| 972 ->IsAvailableToManifest("1", Manifest::TYPE_EXTENSION, | 740 ->IsAvailableToManifest("1", Manifest::TYPE_EXTENSION, |
| 973 Manifest::INVALID_LOCATION, | 741 Manifest::INVALID_LOCATION, |
| 974 Feature::UNSPECIFIED_PLATFORM) | 742 Feature::UNSPECIFIED_PLATFORM) |
| 975 .result()); | 743 .result()); |
| 976 } | 744 } |
| 977 } | 745 } |
| 978 | 746 |
| 979 } // namespace extensions | 747 } // namespace extensions |
| OLD | NEW |