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/complex_feature.h" | 17 #include "extensions/common/features/complex_feature.h" |
17 #include "extensions/common/features/feature_channel.h" | 18 #include "extensions/common/features/feature_channel.h" |
18 #include "extensions/common/features/json_feature_provider.h" | 19 #include "extensions/common/features/json_feature_provider.h" |
19 #include "extensions/common/features/permission_feature.h" | 20 #include "extensions/common/features/permission_feature.h" |
20 #include "extensions/common/manifest.h" | 21 #include "extensions/common/manifest.h" |
21 #include "extensions/common/value_builder.h" | 22 #include "extensions/common/value_builder.h" |
22 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
23 | 24 |
24 namespace extensions { | 25 namespace extensions { |
25 | 26 |
(...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
837 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, | 838 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, |
838 IsAvailableInChannel("trunk", version_info::Channel::DEV)); | 839 IsAvailableInChannel("trunk", version_info::Channel::DEV)); |
839 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, | 840 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, |
840 IsAvailableInChannel("trunk", version_info::Channel::BETA)); | 841 IsAvailableInChannel("trunk", version_info::Channel::BETA)); |
841 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, | 842 EXPECT_EQ(Feature::UNSUPPORTED_CHANNEL, |
842 IsAvailableInChannel("trunk", version_info::Channel::STABLE)); | 843 IsAvailableInChannel("trunk", version_info::Channel::STABLE)); |
843 } | 844 } |
844 | 845 |
845 // Tests the validation of features with channel entries. | 846 // Tests the validation of features with channel entries. |
846 TEST_F(SimpleFeatureTest, FeatureValidation) { | 847 TEST_F(SimpleFeatureTest, FeatureValidation) { |
847 std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue()); | 848 std::string error; |
848 | 849 { |
849 base::DictionaryValue* feature1 = new base::DictionaryValue(); | 850 PermissionFeature feature; |
850 feature1->SetString("channel", "trunk"); | 851 feature.channel_.reset( |
851 value->Set("feature1", feature1); | 852 new version_info::Channel(version_info::Channel::UNKNOWN)); |
852 | 853 // The feature won't validate because it lacks an extension type. |
853 base::DictionaryValue* feature2 = new base::DictionaryValue(); | 854 EXPECT_FALSE(feature.Validate(&error)); |
854 feature2->SetString("channel", "trunk"); | 855 // If we add one, it works. |
855 base::ListValue* extension_types = new base::ListValue(); | 856 feature.extension_types_.push_back(Manifest::TYPE_EXTENSION); |
856 extension_types->AppendString("extension"); | 857 EXPECT_TRUE(feature.Validate(&error)); |
857 feature2->Set("extension_types", extension_types); | 858 // Remove the channel, and feature1 won't validate. |
858 base::ListValue* contexts = new base::ListValue(); | 859 feature.channel_.reset(); |
859 contexts->AppendString("blessed_extension"); | 860 EXPECT_FALSE(feature.Validate(&error)); |
860 feature2->Set("contexts", contexts); | 861 } |
861 value->Set("feature2", feature2); | 862 { |
862 | 863 PermissionFeature feature; |
863 std::unique_ptr<JSONFeatureProvider> provider( | 864 feature.channel_.reset( |
864 new JSONFeatureProvider(*value, CreateFeature<PermissionFeature>)); | 865 new version_info::Channel(version_info::Channel::UNKNOWN)); |
865 | 866 feature.extension_types_.push_back(Manifest::TYPE_EXTENSION); |
866 // feature1 won't validate because it lacks an extension type. | 867 feature.contexts_.push_back(Feature::BLESSED_EXTENSION_CONTEXT); |
867 EXPECT_FALSE(provider->GetFeature("feature1")); | 868 // The feature won't validate because of the presence of "contexts". |
868 | 869 EXPECT_FALSE(feature.Validate(&error)); |
869 // If we add one, it works. | 870 feature.contexts_.clear(); |
870 feature1->Set("extension_types", extension_types->DeepCopy()); | 871 EXPECT_TRUE(feature.Validate(&error)); |
871 provider.reset( | 872 } |
872 new JSONFeatureProvider(*value, CreateFeature<PermissionFeature>)); | 873 { |
873 EXPECT_TRUE(provider->GetFeature("feature1")); | 874 APIFeature feature; |
874 | 875 feature.channel_.reset( |
875 // Remove the channel, and feature1 won't validate. | 876 new version_info::Channel(version_info::Channel::STABLE)); |
876 feature1->Remove("channel", NULL); | 877 // API features require contexts. |
877 provider.reset( | 878 EXPECT_FALSE(feature.Validate(&error)); |
878 new JSONFeatureProvider(*value, CreateFeature<PermissionFeature>)); | 879 feature.contexts_.push_back(Feature::CONTENT_SCRIPT_CONTEXT); |
879 EXPECT_FALSE(provider->GetFeature("feature1")); | 880 EXPECT_TRUE(feature.Validate(&error)); |
880 | 881 } |
881 // feature2 won't validate because of the presence of "contexts". | |
882 EXPECT_FALSE(provider->GetFeature("feature2")); | |
883 | |
884 // If we remove it, it works. | |
885 feature2->Remove("contexts", NULL); | |
886 provider.reset( | |
887 new JSONFeatureProvider(*value, CreateFeature<PermissionFeature>)); | |
888 EXPECT_TRUE(provider->GetFeature("feature2")); | |
889 } | 882 } |
890 | 883 |
891 // Tests simple feature availability across channels. | 884 // Tests simple feature availability across channels. |
892 TEST_F(SimpleFeatureTest, SimpleFeatureAvailability) { | 885 TEST_F(SimpleFeatureTest, SimpleFeatureAvailability) { |
893 std::unique_ptr<base::DictionaryValue> rule( | 886 std::unique_ptr<ComplexFeature> complex_feature; |
894 DictionaryBuilder() | 887 { |
895 .Set("feature1", | 888 std::unique_ptr<SimpleFeature> feature1(CreateFeature<SimpleFeature>()); |
896 ListBuilder() | 889 feature1->channel_.reset( |
897 .Append(DictionaryBuilder() | 890 new version_info::Channel(version_info::Channel::BETA)); |
898 .Set("channel", "beta") | 891 feature1->extension_types_.push_back(Manifest::TYPE_EXTENSION); |
899 .Set("extension_types", | 892 std::unique_ptr<SimpleFeature> feature2(CreateFeature<SimpleFeature>()); |
900 ListBuilder().Append("extension").Build()) | 893 feature2->channel_.reset( |
901 .Build()) | 894 new version_info::Channel(version_info::Channel::BETA)); |
902 .Append(DictionaryBuilder() | 895 feature2->extension_types_.push_back(Manifest::TYPE_LEGACY_PACKAGED_APP); |
903 .Set("channel", "beta") | 896 std::unique_ptr<ComplexFeature::FeatureList> list( |
904 .Set("extension_types", | 897 new ComplexFeature::FeatureList()); |
905 ListBuilder() | 898 list->push_back(std::move(feature1)); |
906 .Append("legacy_packaged_app") | 899 list->push_back(std::move(feature2)); |
907 .Build()) | 900 complex_feature.reset(new ComplexFeature(std::move(list))); |
908 .Build()) | 901 } |
909 .Build()) | |
910 .Build()); | |
911 | 902 |
912 std::unique_ptr<JSONFeatureProvider> provider( | 903 Feature* feature = static_cast<Feature*>(complex_feature.get()); |
913 new JSONFeatureProvider(*rule, CreateFeature<SimpleFeature>)); | |
914 | |
915 Feature* feature = provider->GetFeature("feature1"); | |
916 EXPECT_TRUE(feature); | |
917 | |
918 // Make sure both rules are applied correctly. | 904 // Make sure both rules are applied correctly. |
919 { | 905 { |
920 ScopedCurrentChannel current_channel(version_info::Channel::BETA); | 906 ScopedCurrentChannel current_channel(version_info::Channel::BETA); |
921 EXPECT_EQ( | 907 EXPECT_EQ( |
922 Feature::IS_AVAILABLE, | 908 Feature::IS_AVAILABLE, |
923 feature->IsAvailableToManifest("1", | 909 feature->IsAvailableToManifest("1", |
924 Manifest::TYPE_EXTENSION, | 910 Manifest::TYPE_EXTENSION, |
925 Manifest::INVALID_LOCATION, | 911 Manifest::INVALID_LOCATION, |
926 Feature::UNSPECIFIED_PLATFORM).result()); | 912 Feature::UNSPECIFIED_PLATFORM).result()); |
927 EXPECT_EQ( | 913 EXPECT_EQ( |
(...skipping 15 matching lines...) Expand all Loading... | |
943 Feature::IS_AVAILABLE, | 929 Feature::IS_AVAILABLE, |
944 feature->IsAvailableToManifest("2", | 930 feature->IsAvailableToManifest("2", |
945 Manifest::TYPE_LEGACY_PACKAGED_APP, | 931 Manifest::TYPE_LEGACY_PACKAGED_APP, |
946 Manifest::INVALID_LOCATION, | 932 Manifest::INVALID_LOCATION, |
947 Feature::UNSPECIFIED_PLATFORM).result()); | 933 Feature::UNSPECIFIED_PLATFORM).result()); |
948 } | 934 } |
949 } | 935 } |
950 | 936 |
951 // Tests complex feature availability across channels. | 937 // Tests complex feature availability across channels. |
952 TEST_F(SimpleFeatureTest, ComplexFeatureAvailability) { | 938 TEST_F(SimpleFeatureTest, ComplexFeatureAvailability) { |
953 std::unique_ptr<ComplexFeature::FeatureList> features( | 939 std::unique_ptr<ComplexFeature> complex_feature; |
954 new ComplexFeature::FeatureList()); | 940 { |
941 std::unique_ptr<SimpleFeature> feature1(CreateFeature<SimpleFeature>()); | |
lazyboy
2016/07/15 22:53:40
Retain the comment: "Rule: "extension", channel tr
Devlin
2016/07/18 17:51:58
Done.
| |
942 feature1->channel_.reset( | |
943 new version_info::Channel(version_info::Channel::UNKNOWN)); | |
944 feature1->extension_types_.push_back(Manifest::TYPE_EXTENSION); | |
945 std::unique_ptr<SimpleFeature> feature2(CreateFeature<SimpleFeature>()); | |
946 feature2->channel_.reset( | |
lazyboy
2016/07/15 22:53:40
Same for this one.
Devlin
2016/07/18 17:51:58
Done.
| |
947 new version_info::Channel(version_info::Channel::STABLE)); | |
948 feature2->extension_types_.push_back(Manifest::TYPE_LEGACY_PACKAGED_APP); | |
949 std::unique_ptr<ComplexFeature::FeatureList> list( | |
950 new ComplexFeature::FeatureList()); | |
951 list->push_back(std::move(feature1)); | |
952 list->push_back(std::move(feature2)); | |
953 complex_feature.reset(new ComplexFeature(std::move(list))); | |
954 } | |
955 | 955 |
956 // Rule: "extension", channel trunk. | 956 Feature* feature = static_cast<Feature*>(complex_feature.get()); |
957 std::unique_ptr<SimpleFeature> simple_feature(CreateFeature<SimpleFeature>()); | |
958 std::unique_ptr<base::DictionaryValue> rule( | |
959 DictionaryBuilder() | |
960 .Set("channel", "trunk") | |
961 .Set("extension_types", ListBuilder().Append("extension").Build()) | |
962 .Build()); | |
963 simple_feature->Parse(rule.get()); | |
964 features->push_back(std::move(simple_feature)); | |
965 | |
966 // Rule: "legacy_packaged_app", channel stable. | |
967 simple_feature.reset(CreateFeature<SimpleFeature>()); | |
968 rule = DictionaryBuilder() | |
969 .Set("channel", "stable") | |
970 .Set("extension_types", | |
971 ListBuilder().Append("legacy_packaged_app").Build()) | |
972 .Build(); | |
973 simple_feature->Parse(rule.get()); | |
974 features->push_back(std::move(simple_feature)); | |
975 | |
976 std::unique_ptr<ComplexFeature> feature( | |
977 new ComplexFeature(std::move(features))); | |
978 | |
979 // Test match 1st rule. | |
980 { | 957 { |
981 ScopedCurrentChannel current_channel(version_info::Channel::UNKNOWN); | 958 ScopedCurrentChannel current_channel(version_info::Channel::UNKNOWN); |
982 EXPECT_EQ( | 959 EXPECT_EQ(Feature::IS_AVAILABLE, |
983 Feature::IS_AVAILABLE, | 960 feature |
984 feature->IsAvailableToManifest("1", | 961 ->IsAvailableToManifest("1", Manifest::TYPE_EXTENSION, |
985 Manifest::TYPE_EXTENSION, | 962 Manifest::INVALID_LOCATION, |
986 Manifest::INVALID_LOCATION, | 963 Feature::UNSPECIFIED_PLATFORM) |
987 Feature::UNSPECIFIED_PLATFORM, | 964 .result()); |
988 Feature::GetCurrentPlatform()).result()); | |
989 } | 965 } |
990 | |
991 // Test match 2nd rule. | |
992 { | 966 { |
993 ScopedCurrentChannel current_channel(version_info::Channel::BETA); | 967 ScopedCurrentChannel current_channel(version_info::Channel::BETA); |
994 EXPECT_EQ( | 968 EXPECT_EQ(Feature::IS_AVAILABLE, |
995 Feature::IS_AVAILABLE, | 969 feature |
996 feature->IsAvailableToManifest("2", | 970 ->IsAvailableToManifest( |
997 Manifest::TYPE_LEGACY_PACKAGED_APP, | 971 "2", Manifest::TYPE_LEGACY_PACKAGED_APP, |
998 Manifest::INVALID_LOCATION, | 972 Manifest::INVALID_LOCATION, Feature::UNSPECIFIED_PLATFORM) |
999 Feature::UNSPECIFIED_PLATFORM, | 973 .result()); |
1000 Feature::GetCurrentPlatform()).result()); | |
1001 } | 974 } |
1002 | |
1003 // Test feature not available to extensions above channel unknown. | |
1004 { | 975 { |
1005 ScopedCurrentChannel current_channel(version_info::Channel::BETA); | 976 ScopedCurrentChannel current_channel(version_info::Channel::BETA); |
1006 EXPECT_NE( | 977 EXPECT_NE(Feature::IS_AVAILABLE, |
1007 Feature::IS_AVAILABLE, | 978 feature |
1008 feature->IsAvailableToManifest("1", | 979 ->IsAvailableToManifest("1", Manifest::TYPE_EXTENSION, |
1009 Manifest::TYPE_EXTENSION, | 980 Manifest::INVALID_LOCATION, |
1010 Manifest::INVALID_LOCATION, | 981 Feature::UNSPECIFIED_PLATFORM) |
1011 Feature::UNSPECIFIED_PLATFORM, | 982 .result()); |
1012 Feature::GetCurrentPlatform()).result()); | |
1013 } | 983 } |
1014 } | 984 } |
1015 | 985 |
1016 } // namespace extensions | 986 } // namespace extensions |
OLD | NEW |