1 // Copyright 2017 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 #ifndef EXTENSIONS_COMMON_API_DECLARATIVE_NET_REQUEST_TEST_UTILS_H_ 6 #define EXTENSIONS_COMMON_API_DECLARATIVE_NET_REQUEST_TEST_UTILS_H_ 7 8 #include <memory> 9 #include <string> 10 #include <vector> 11 12 #include "base/files/file_path.h" 13 #include "base/optional.h" 14 #include "base/values.h" 15 #include "extensions/common/api/declarative_net_request/constants.h" 16 #include "extensions/common/url_pattern.h" 17 18 namespace base { 19 class DictionaryValue; 20 } // namespace base 21 22 namespace extensions { 23 namespace declarative_net_request { 24 25 struct DictionarySource { 26 DictionarySource() = default; 27 virtual ~DictionarySource() = default; 28 virtual std::unique_ptr<base::DictionaryValue> ToValue() const = 0; 29 }; 30 31 // Helper structs to simplify building base::Values which can later be used to 32 // serialize to JSON. The generated implementation for the JSON rules schema is 33 // not used since it's not flexible enough to generate the base::Value/JSON we 34 // want for tests. 35 struct TestRuleCondition : public DictionarySource { 36 TestRuleCondition(); 37 ~TestRuleCondition() override; 38 TestRuleCondition(const TestRuleCondition&); 39 TestRuleCondition& operator=(const TestRuleCondition&); 40 41 base::Optional<std::string> url_filter; 42 base::Optional<std::string> regex_filter; 43 base::Optional<bool> is_url_filter_case_sensitive; 44 base::Optional<std::vector<std::string>> domains; 45 base::Optional<std::vector<std::string>> excluded_domains; 46 base::Optional<std::vector<std::string>> resource_types; 47 base::Optional<std::vector<std::string>> excluded_resource_types; 48 base::Optional<std::string> domain_type; 49 50 std::unique_ptr<base::DictionaryValue> ToValue() const override; 51 }; 52 53 struct TestRuleQueryKeyValue : public DictionarySource { 54 TestRuleQueryKeyValue(); 55 ~TestRuleQueryKeyValue() override; 56 TestRuleQueryKeyValue(const TestRuleQueryKeyValue&); 57 TestRuleQueryKeyValue& operator=(const TestRuleQueryKeyValue&); 58 59 base::Optional<std::string> key; 60 base::Optional<std::string> value; 61 62 std::unique_ptr<base::DictionaryValue> ToValue() const override; 63 }; 64 65 struct TestRuleQueryTransform : public DictionarySource { 66 TestRuleQueryTransform(); 67 ~TestRuleQueryTransform() override; 68 TestRuleQueryTransform(const TestRuleQueryTransform&); 69 TestRuleQueryTransform& operator=(const TestRuleQueryTransform&); 70 71 base::Optional<std::vector<std::string>> remove_params; 72 base::Optional<std::vector<TestRuleQueryKeyValue>> add_or_replace_params; 73 74 std::unique_ptr<base::DictionaryValue> ToValue() const override; 75 }; 76 77 struct TestRuleTransform : public DictionarySource { 78 TestRuleTransform(); 79 ~TestRuleTransform() override; 80 TestRuleTransform(const TestRuleTransform&); 81 TestRuleTransform& operator=(const TestRuleTransform&); 82 83 base::Optional<std::string> scheme; 84 base::Optional<std::string> host; 85 base::Optional<std::string> port; 86 base::Optional<std::string> path; 87 base::Optional<std::string> query; 88 base::Optional<TestRuleQueryTransform> query_transform; 89 base::Optional<std::string> fragment; 90 base::Optional<std::string> username; 91 base::Optional<std::string> password; 92 93 std::unique_ptr<base::DictionaryValue> ToValue() const override; 94 }; 95 96 struct TestRuleRedirect : public DictionarySource { 97 TestRuleRedirect(); 98 ~TestRuleRedirect() override; 99 TestRuleRedirect(const TestRuleRedirect&); 100 TestRuleRedirect& operator=(const TestRuleRedirect&); 101 102 base::Optional<std::string> extension_path; 103 base::Optional<TestRuleTransform> transform; 104 base::Optional<std::string> url; 105 base::Optional<std::string> regex_substitution; 106 107 std::unique_ptr<base::DictionaryValue> ToValue() const override; 108 }; 109 110 struct TestHeaderInfo : public DictionarySource { 111 TestHeaderInfo(std::string header, 112 std::string operation, 113 base::Optional<std::string> value); 114 ~TestHeaderInfo() override; 115 TestHeaderInfo(const TestHeaderInfo&); 116 TestHeaderInfo& operator=(const TestHeaderInfo&); 117 118 base::Optional<std::string> header; 119 base::Optional<std::string> operation; 120 base::Optional<std::string> value; 121 122 std::unique_ptr<base::DictionaryValue> ToValue() const override; 123 }; 124 125 struct TestRuleAction : public DictionarySource { 126 TestRuleAction(); 127 ~TestRuleAction() override; 128 TestRuleAction(const TestRuleAction&); 129 TestRuleAction& operator=(const TestRuleAction&); 130 131 base::Optional<std::string> type; 132 base::Optional<std::vector<TestHeaderInfo>> request_headers; 133 base::Optional<std::vector<TestHeaderInfo>> response_headers; 134 base::Optional<TestRuleRedirect> redirect; 135 136 std::unique_ptr<base::DictionaryValue> ToValue() const override; 137 }; 138 139 struct TestRule : public DictionarySource { 140 TestRule(); 141 ~TestRule() override; 142 TestRule(const TestRule&); 143 TestRule& operator=(const TestRule&); 144 145 base::Optional<int> id; 146 base::Optional<int> priority; 147 base::Optional<TestRuleCondition> condition; 148 base::Optional<TestRuleAction> action; 149 150 std::unique_ptr<base::DictionaryValue> ToValue() const override; 151 }; 152 153 // Helper function to build a generic TestRule. 154 TestRule CreateGenericRule(int id = kMinValidID); 155 156 // Bitmasks to configure the extension under test. 157 enum ConfigFlag { 158 kConfig_None = 0, 159 160 // Whether a background script ("background.js") will be persisted for the 161 // extension. Clients can listen in to the "ready" message from the background 162 // page to detect its loading. 163 kConfig_HasBackgroundScript = 1 << 0, 164 165 // Whether the extension has the declarativeNetRequestFeedback permission. 166 kConfig_HasFeedbackPermission = 1 << 1, 167 168 // Whether the extension has the activeTab permission. 169 kConfig_HasActiveTab = 1 << 2, 170 171 // Whether the "declarative_net_request" manifest key should be omitted. 172 kConfig_OmitDeclarativeNetRequestKey = 1 << 3, 173 }; 174 175 // Describes a single extension ruleset. 176 struct TestRulesetInfo { 177 TestRulesetInfo(const std::string& manifest_id_and_path, 178 const base::Value& rules_value, 179 bool enabled = true); 180 TestRulesetInfo(const std::string& manifest_id, 181 const std::string& relative_file_path, 182 const base::Value& rules_value, 183 bool enabled = true); 184 TestRulesetInfo(const TestRulesetInfo&); 185 TestRulesetInfo& operator=(const TestRulesetInfo&); 186 187 // Unique ID for the ruleset. 188 const std::string manifest_id; 189 190 // File path relative to the extension directory. 191 const std::string relative_file_path; 192 193 // The base::Value corresponding to the rules in the ruleset. 194 const base::Value rules_value; 195 196 // Whether the ruleset is enabled by default. 197 const bool enabled; 198 199 // Returns the corresponding value to be specified in the manifest for the 200 // ruleset. 201 std::unique_ptr<base::DictionaryValue> GetManifestValue() const; 202 }; 203 204 // Helper to build an extension manifest which uses the 205 // kDeclarativeNetRequestKey manifest key. |hosts| specifies the host 206 // permissions to grant. |flags| is a bitmask of ConfigFlag to configure the 207 // extension. |ruleset_info| specifies the static rulesets for the extension. 208 std::unique_ptr<base::DictionaryValue> CreateManifest( 209 const std::vector<TestRulesetInfo>& ruleset_info, 210 const std::vector<std::string>& hosts = {}, 211 unsigned flags = ConfigFlag::kConfig_None, 212 const std::string& extension_name = "Test Extension"); 213 214 // Returns a ListValue corresponding to a vector of strings. 215 std::unique_ptr<base::ListValue> ToListValue( 216 const std::vector<std::string>& vec); 217 218 // Returns a ListValue corresponding to a vector of TestRules. 219 std::unique_ptr<base::ListValue> ToListValue( 220 const std::vector<TestRule>& rules); 221 222 // Writes the rulesets specified in |ruleset_info| in the given |extension_dir| 223 // together with the manifest file. |hosts| specifies the host permissions, the 224 // extensions should have. |flags| is a bitmask of ConfigFlag to configure the 225 // extension. 226 void WriteManifestAndRulesets( 227 const base::FilePath& extension_dir, 228 const std::vector<TestRulesetInfo>& ruleset_info, 229 const std::vector<std::string>& hosts, 230 unsigned flags = ConfigFlag::kConfig_None, 231 const std::string& extension_name = "Test Extension"); 232 233 // Specialization of WriteManifestAndRulesets above for an extension with a 234 // single static ruleset. 235 void WriteManifestAndRuleset( 236 const base::FilePath& extension_dir, 237 const TestRulesetInfo& ruleset_info, 238 const std::vector<std::string>& hosts, 239 unsigned flags = ConfigFlag::kConfig_None, 240 const std::string& extension_name = "Test Extension"); 241 242 } // namespace declarative_net_request 243 } // namespace extensions 244 245 #endif // EXTENSIONS_COMMON_API_DECLARATIVE_NET_REQUEST_TEST_UTILS_H_ 246