Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(147)

Side by Side Diff: chrome/common/extensions/matcher/url_matcher_factory_unittest.cc

Issue 12092096: Move c/c/extensions/matcher/ to top level extension dir (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: TOT Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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/matcher/url_matcher_factory.h"
6
7 #include "base/basictypes.h"
8 #include "base/format_macros.h"
9 #include "base/stringprintf.h"
10 #include "base/values.h"
11 #include "chrome/common/extensions/matcher/url_matcher_constants.h"
12 #include "googleurl/src/gurl.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace extensions {
16
17 namespace keys = url_matcher_constants;
18
19 TEST(URLMatcherFactoryTest, CreateFromURLFilterDictionary) {
20 URLMatcher matcher;
21
22 std::string error;
23 scoped_refptr<URLMatcherConditionSet> result;
24
25 // Invalid key: {"invalid": "foobar"}
26 DictionaryValue invalid_condition;
27 invalid_condition.SetString("invalid", "foobar");
28
29 // Invalid value type: {"hostSuffix": []}
30 DictionaryValue invalid_condition2;
31 invalid_condition2.Set(keys::kHostSuffixKey, new ListValue);
32
33 // Invalid regex value: {"urlMatches": "*"}
34 DictionaryValue invalid_condition3;
35 invalid_condition3.SetString(keys::kURLMatchesKey, "*");
36
37 // Valid values:
38 // {
39 // "port_range": [80, [1000, 1010]],
40 // "schemes": ["http"],
41 // "hostSuffix": "example.com"
42 // "hostPrefix": "www"
43 // }
44
45 // Port range: Allow 80;1000-1010.
46 ListValue* port_range = new ListValue();
47 port_range->Append(Value::CreateIntegerValue(1000));
48 port_range->Append(Value::CreateIntegerValue(1010));
49 ListValue* port_ranges = new ListValue();
50 port_ranges->Append(Value::CreateIntegerValue(80));
51 port_ranges->Append(port_range);
52
53 ListValue* scheme_list = new ListValue();
54 scheme_list->Append(Value::CreateStringValue("http"));
55
56 DictionaryValue valid_condition;
57 valid_condition.SetString(keys::kHostSuffixKey, "example.com");
58 valid_condition.SetString(keys::kHostPrefixKey, "www");
59 valid_condition.Set(keys::kPortsKey, port_ranges);
60 valid_condition.Set(keys::kSchemesKey, scheme_list);
61
62 // Test wrong condition name passed.
63 error.clear();
64 result = URLMatcherFactory::CreateFromURLFilterDictionary(
65 matcher.condition_factory(), &invalid_condition, 1, &error);
66 EXPECT_FALSE(error.empty());
67 EXPECT_FALSE(result.get());
68
69 // Test wrong datatype in hostSuffix.
70 error.clear();
71 result = URLMatcherFactory::CreateFromURLFilterDictionary(
72 matcher.condition_factory(), &invalid_condition2, 2, &error);
73 EXPECT_FALSE(error.empty());
74 EXPECT_FALSE(result.get());
75
76 // Test invalid regex in urlMatches.
77 error.clear();
78 result = URLMatcherFactory::CreateFromURLFilterDictionary(
79 matcher.condition_factory(), &invalid_condition3, 3, &error);
80 EXPECT_FALSE(error.empty());
81 EXPECT_FALSE(result.get());
82
83 // Test success.
84 error.clear();
85 result = URLMatcherFactory::CreateFromURLFilterDictionary(
86 matcher.condition_factory(), &valid_condition, 100, &error);
87 EXPECT_EQ("", error);
88 ASSERT_TRUE(result.get());
89
90 URLMatcherConditionSet::Vector conditions;
91 conditions.push_back(result);
92 matcher.AddConditionSets(conditions);
93
94 EXPECT_EQ(1u, matcher.MatchURL(GURL("http://www.example.com")).size());
95 EXPECT_EQ(1u, matcher.MatchURL(GURL("http://www.example.com:80")).size());
96 EXPECT_EQ(1u, matcher.MatchURL(GURL("http://www.example.com:1000")).size());
97 // Wrong scheme.
98 EXPECT_EQ(0u, matcher.MatchURL(GURL("https://www.example.com:80")).size());
99 // Wrong port.
100 EXPECT_EQ(0u, matcher.MatchURL(GURL("http://www.example.com:81")).size());
101 // Unfulfilled host prefix.
102 EXPECT_EQ(0u, matcher.MatchURL(GURL("http://mail.example.com:81")).size());
103 }
104
105 // Using upper case letters for scheme and host values is currently an error.
106 // See more context at http://crbug.com/160702#c6 .
107 TEST(URLMatcherFactoryTest, UpperCase) {
108 URLMatcher matcher;
109 std::string error;
110 scoped_refptr<URLMatcherConditionSet> result;
111
112 // {"hostContains": "exaMple"}
113 DictionaryValue invalid_condition1;
114 invalid_condition1.SetString(keys::kHostContainsKey, "exaMple");
115
116 // {"hostSuffix": ".Com"}
117 DictionaryValue invalid_condition2;
118 invalid_condition2.SetString(keys::kHostSuffixKey, ".Com");
119
120 // {"hostPrefix": "WWw."}
121 DictionaryValue invalid_condition3;
122 invalid_condition3.SetString(keys::kHostPrefixKey, "WWw.");
123
124 // {"hostEquals": "WWW.example.Com"}
125 DictionaryValue invalid_condition4;
126 invalid_condition4.SetString(keys::kHostEqualsKey, "WWW.example.Com");
127
128 // {"scheme": ["HTTP"]}
129 ListValue* scheme_list = new ListValue();
130 scheme_list->Append(Value::CreateStringValue("HTTP"));
131 DictionaryValue invalid_condition5;
132 invalid_condition5.Set(keys::kSchemesKey, scheme_list);
133
134 const DictionaryValue* invalid_conditions[] = {
135 &invalid_condition1,
136 &invalid_condition2,
137 &invalid_condition3,
138 &invalid_condition4,
139 &invalid_condition5
140 };
141
142 for (size_t i = 0; i < arraysize(invalid_conditions); ++i) {
143 error.clear();
144 result = URLMatcherFactory::CreateFromURLFilterDictionary(
145 matcher.condition_factory(), invalid_conditions[i], 1, &error);
146 EXPECT_FALSE(error.empty()) << "in iteration " << i;
147 EXPECT_FALSE(result.get()) << "in iteration " << i;
148 }
149 }
150
151 // This class wraps a case sensitivity test for a single UrlFilter condition.
152 class UrlConditionCaseTest {
153 public:
154 // The condition is identified by the key |condition_key|. If that key is
155 // associated with string values, then |use_list_of_strings| should be false,
156 // if the key is associated with list-of-string values, then
157 // |use_list_of_strings| should be true. In |url| is the URL to test against.
158 UrlConditionCaseTest(const char* condition_key,
159 bool use_list_of_strings,
160 const std::string& expected_value,
161 const std::string& incorrect_case_value,
162 bool case_sensitive,
163 bool lower_case_enforced,
164 const GURL& url)
165 : condition_key_(condition_key),
166 use_list_of_strings_(use_list_of_strings),
167 expected_value_(expected_value),
168 incorrect_case_value_(incorrect_case_value),
169 expected_result_for_wrong_case_(ExpectedResult(case_sensitive,
170 lower_case_enforced)),
171 url_(url) {}
172
173 ~UrlConditionCaseTest() {}
174
175 // Match the condition against |url_|. Checks via EXPECT_* macros that
176 // |expected_value_| matches always, and that |incorrect_case_value_| matches
177 // iff |case_sensitive_| is false.
178 void Test() const;
179
180 private:
181 enum ResultType { OK, NOT_FULFILLED, CREATE_FAILURE };
182
183 // What is the expected result of |CheckCondition| if a wrong-case |value|
184 // containing upper case letters is supplied.
185 static ResultType ExpectedResult(bool case_sensitive,
186 bool lower_case_enforced) {
187 if (lower_case_enforced)
188 return CREATE_FAILURE;
189 if (case_sensitive)
190 return NOT_FULFILLED;
191 return OK;
192 }
193
194 // Test the condition |condition_key_| = |value| against |url_|.
195 // Check, via EXPECT_* macros, that either the condition cannot be constructed
196 // at all, or that the condition is not fulfilled, or that it is fulfilled,
197 // depending on the value of |expected_result|.
198 void CheckCondition(const std::string& value,
199 ResultType expected_result) const;
200
201 const char* condition_key_;
202 const bool use_list_of_strings_;
203 const std::string& expected_value_;
204 const std::string& incorrect_case_value_;
205 const ResultType expected_result_for_wrong_case_;
206 const GURL& url_;
207
208 // Allow implicit copy and assign, because a public copy constructor is
209 // needed, but never used (!), for the definition of arrays of this class.
210 };
211
212 void UrlConditionCaseTest::Test() const {
213 CheckCondition(expected_value_, OK);
214 CheckCondition(incorrect_case_value_, expected_result_for_wrong_case_);
215 }
216
217 void UrlConditionCaseTest::CheckCondition(
218 const std::string& value,
219 UrlConditionCaseTest::ResultType expected_result) const {
220 DictionaryValue condition;
221 if (use_list_of_strings_) {
222 ListValue* list = new ListValue();
223 list->Append(Value::CreateStringValue(value));
224 condition.SetWithoutPathExpansion(condition_key_, list);
225 } else {
226 condition.SetStringWithoutPathExpansion(condition_key_, value);
227 }
228
229 URLMatcher matcher;
230 std::string error;
231 scoped_refptr<URLMatcherConditionSet> result;
232
233 result = URLMatcherFactory::CreateFromURLFilterDictionary(
234 matcher.condition_factory(), &condition, 1, &error);
235 if (expected_result == CREATE_FAILURE) {
236 EXPECT_FALSE(error.empty());
237 EXPECT_FALSE(result);
238 return;
239 }
240 EXPECT_EQ("", error);
241 ASSERT_TRUE(result.get());
242
243 URLMatcherConditionSet::Vector conditions;
244 conditions.push_back(result);
245 matcher.AddConditionSets(conditions);
246 EXPECT_EQ((expected_result == OK ? 1u : 0u), matcher.MatchURL(url_).size())
247 << "while matching condition " << condition_key_ << " with value "
248 << value << " against url " << url_;
249 }
250
251 // This tests that the UrlFilter handles case sensitivity on various parts of
252 // URLs correctly.
253 TEST(URLMatcherFactoryTest, CaseSensitivity) {
254 const std::string kScheme("https");
255 const std::string kSchemeUpper("HTTPS");
256 const std::string kHost("www.example.com");
257 const std::string kHostUpper("WWW.EXAMPLE.COM");
258 const std::string kPath("/path");
259 const std::string kPathUpper("/PATH");
260 const std::string kQuery("?option=value&A=B");
261 const std::string kQueryUpper("?OPTION=VALUE&A=B");
262 const std::string kUrl(kScheme + "://" + kHost + ":1234" + kPath + kQuery);
263 const std::string kUrlUpper(
264 kSchemeUpper + "://" + kHostUpper + ":1234" + kPathUpper + kQueryUpper);
265 const GURL url(kUrl);
266 // Note: according to RFC 3986, and RFC 1034, schema and host, respectively
267 // should be case insensitive. See crbug.com/160702#6 for why we still
268 // require them to be case sensitive in UrlFilter, and enforce lower case.
269 const bool kIsSchemeLowerCaseEnforced = true;
270 const bool kIsHostLowerCaseEnforced = true;
271 const bool kIsPathLowerCaseEnforced = false;
272 const bool kIsQueryLowerCaseEnforced = false;
273 const bool kIsUrlLowerCaseEnforced = false;
274 const bool kIsSchemeCaseSensitive = true;
275 const bool kIsHostCaseSensitive = true;
276 const bool kIsPathCaseSensitive = true;
277 const bool kIsQueryCaseSensitive = true;
278 const bool kIsUrlCaseSensitive = kIsSchemeCaseSensitive ||
279 kIsHostCaseSensitive ||
280 kIsPathCaseSensitive ||
281 kIsQueryCaseSensitive;
282
283 const UrlConditionCaseTest case_tests[] = {
284 UrlConditionCaseTest(keys::kSchemesKey, true, kScheme, kSchemeUpper,
285 kIsSchemeCaseSensitive, kIsSchemeLowerCaseEnforced,
286 url),
287 UrlConditionCaseTest(keys::kHostContainsKey, false, kHost, kHostUpper,
288 kIsHostCaseSensitive, kIsHostLowerCaseEnforced, url),
289 UrlConditionCaseTest(keys::kHostEqualsKey, false, kHost, kHostUpper,
290 kIsHostCaseSensitive, kIsHostLowerCaseEnforced, url),
291 UrlConditionCaseTest(keys::kHostPrefixKey, false, kHost, kHostUpper,
292 kIsHostCaseSensitive, kIsHostLowerCaseEnforced, url),
293 UrlConditionCaseTest(keys::kHostSuffixKey, false, kHost, kHostUpper,
294 kIsHostCaseSensitive, kIsHostLowerCaseEnforced, url),
295 UrlConditionCaseTest(keys::kPathContainsKey, false, kPath, kPathUpper,
296 kIsPathCaseSensitive, kIsPathLowerCaseEnforced, url),
297 UrlConditionCaseTest(keys::kPathEqualsKey, false, kPath, kPathUpper,
298 kIsPathCaseSensitive, kIsPathLowerCaseEnforced, url),
299 UrlConditionCaseTest(keys::kPathPrefixKey, false, kPath, kPathUpper,
300 kIsPathCaseSensitive, kIsPathLowerCaseEnforced, url),
301 UrlConditionCaseTest(keys::kPathSuffixKey, false, kPath, kPathUpper,
302 kIsPathCaseSensitive, kIsPathLowerCaseEnforced, url),
303 UrlConditionCaseTest(keys::kQueryContainsKey, false, kQuery, kQueryUpper,
304 kIsQueryCaseSensitive, kIsQueryLowerCaseEnforced, url),
305 UrlConditionCaseTest(keys::kQueryEqualsKey, false, kQuery, kQueryUpper,
306 kIsQueryCaseSensitive, kIsQueryLowerCaseEnforced, url),
307 UrlConditionCaseTest(keys::kQueryPrefixKey, false, kQuery, kQueryUpper,
308 kIsQueryCaseSensitive, kIsQueryLowerCaseEnforced, url),
309 UrlConditionCaseTest(keys::kQuerySuffixKey, false, kQuery, kQueryUpper,
310 kIsQueryCaseSensitive, kIsQueryLowerCaseEnforced, url),
311 // Excluding kURLMatchesKey because case sensitivity can be specified in the
312 // RE2 expression.
313 UrlConditionCaseTest(keys::kURLContainsKey, false, kUrl, kUrlUpper,
314 kIsUrlCaseSensitive, kIsUrlLowerCaseEnforced, url),
315 UrlConditionCaseTest(keys::kURLEqualsKey, false, kUrl, kUrlUpper,
316 kIsUrlCaseSensitive, kIsUrlLowerCaseEnforced, url),
317 UrlConditionCaseTest(keys::kURLPrefixKey, false, kUrl, kUrlUpper,
318 kIsUrlCaseSensitive, kIsUrlLowerCaseEnforced, url),
319 UrlConditionCaseTest(keys::kURLSuffixKey, false, kUrl, kUrlUpper,
320 kIsUrlCaseSensitive, kIsUrlLowerCaseEnforced, url),
321 };
322
323 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(case_tests); ++i) {
324 SCOPED_TRACE(base::StringPrintf("Iteration: %" PRIuS, i));
325 case_tests[i].Test();
326 }
327 }
328
329 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/common/extensions/matcher/url_matcher_factory.cc ('k') | chrome/common/extensions/matcher/url_matcher_helpers.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698