1 // Copyright 2013 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.
5 #include "components/url_matcher/url_matcher.h"
7 #include "base/strings/string_util.h"
8 #include "testing/gtest/include/gtest/gtest.h"
11 namespace url_matcher
{
14 // URLMatcherCondition
17 TEST(URLMatcherConditionTest
, Constructors
) {
18 StringPattern
pattern("example.com", 1);
19 URLMatcherCondition
m1(URLMatcherCondition::HOST_SUFFIX
, &pattern
);
20 EXPECT_EQ(URLMatcherCondition::HOST_SUFFIX
, m1
.criterion());
21 EXPECT_EQ(&pattern
, m1
.string_pattern());
23 URLMatcherCondition m2
;
25 EXPECT_EQ(URLMatcherCondition::HOST_SUFFIX
, m2
.criterion());
26 EXPECT_EQ(&pattern
, m2
.string_pattern());
28 URLMatcherCondition
m3(m1
);
29 EXPECT_EQ(URLMatcherCondition::HOST_SUFFIX
, m3
.criterion());
30 EXPECT_EQ(&pattern
, m3
.string_pattern());
33 TEST(URLMatcherSchemeFilter
, TestMatching
) {
34 URLMatcherSchemeFilter
filter1("https");
35 std::vector
<std::string
> filter2_content
;
36 filter2_content
.push_back("http");
37 filter2_content
.push_back("https");
38 URLMatcherSchemeFilter
filter2(filter2_content
);
40 GURL
matching_url("https://www.foobar.com");
41 GURL
non_matching_url("http://www.foobar.com");
42 EXPECT_TRUE(filter1
.IsMatch(matching_url
));
43 EXPECT_FALSE(filter1
.IsMatch(non_matching_url
));
44 EXPECT_TRUE(filter2
.IsMatch(matching_url
));
45 EXPECT_TRUE(filter2
.IsMatch(non_matching_url
));
48 TEST(URLMatcherPortFilter
, TestMatching
) {
49 std::vector
<URLMatcherPortFilter::Range
> ranges
;
50 ranges
.push_back(URLMatcherPortFilter::CreateRange(80, 90));
51 ranges
.push_back(URLMatcherPortFilter::CreateRange(8080));
52 URLMatcherPortFilter
filter(ranges
);
53 EXPECT_TRUE(filter
.IsMatch(GURL("http://www.example.com")));
54 EXPECT_TRUE(filter
.IsMatch(GURL("http://www.example.com:80")));
55 EXPECT_TRUE(filter
.IsMatch(GURL("http://www.example.com:81")));
56 EXPECT_TRUE(filter
.IsMatch(GURL("http://www.example.com:90")));
57 EXPECT_TRUE(filter
.IsMatch(GURL("http://www.example.com:8080")));
58 EXPECT_FALSE(filter
.IsMatch(GURL("http://www.example.com:79")));
59 EXPECT_FALSE(filter
.IsMatch(GURL("http://www.example.com:91")));
60 EXPECT_FALSE(filter
.IsMatch(GURL("https://www.example.com")));
63 TEST(URLMatcherConditionTest
, IsFullURLCondition
) {
64 StringPattern
pattern("example.com", 1);
65 EXPECT_FALSE(URLMatcherCondition(URLMatcherCondition::HOST_SUFFIX
,
66 &pattern
).IsFullURLCondition());
68 EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::HOST_CONTAINS
,
69 &pattern
).IsFullURLCondition());
70 EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::PATH_CONTAINS
,
71 &pattern
).IsFullURLCondition());
72 EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::QUERY_CONTAINS
,
73 &pattern
).IsFullURLCondition());
75 EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::URL_PREFIX
,
76 &pattern
).IsFullURLCondition());
77 EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::URL_SUFFIX
,
78 &pattern
).IsFullURLCondition());
79 EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::URL_CONTAINS
,
80 &pattern
).IsFullURLCondition());
81 EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::URL_EQUALS
,
82 &pattern
).IsFullURLCondition());
85 TEST(URLMatcherConditionTest
, IsMatch
) {
86 GURL
url1("http://www.example.com/www.foobar.com/index.html");
87 GURL
url2("http://www.foobar.com/example.com/index.html");
89 StringPattern
pattern("example.com", 1);
90 URLMatcherCondition
m1(URLMatcherCondition::HOST_SUFFIX
, &pattern
);
92 std::set
<StringPattern::ID
> matching_patterns
;
94 // matches = {0} --> matcher did not indicate that m1 was a match.
95 matching_patterns
.insert(0);
96 EXPECT_FALSE(m1
.IsMatch(matching_patterns
, url1
));
98 // matches = {0, 1} --> matcher did indicate that m1 was a match.
99 matching_patterns
.insert(1);
100 EXPECT_TRUE(m1
.IsMatch(matching_patterns
, url1
));
102 // For m2 we use a HOST_CONTAINS test, which requires a post-validation
103 // whether the match reported by the SubstringSetMatcher occurs really
104 // in the correct url component.
105 URLMatcherCondition
m2(URLMatcherCondition::HOST_CONTAINS
, &pattern
);
106 EXPECT_TRUE(m2
.IsMatch(matching_patterns
, url1
));
107 EXPECT_FALSE(m2
.IsMatch(matching_patterns
, url2
));
110 TEST(URLMatcherConditionTest
, Comparison
) {
111 StringPattern
p1("foobar.com", 1);
112 StringPattern
p2("foobar.com", 2);
113 // The first component of each test is expected to be < than the second.
114 URLMatcherCondition test_smaller
[][2] = {
115 {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX
, &p1
),
116 URLMatcherCondition(URLMatcherCondition::HOST_SUFFIX
, &p1
)},
117 {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX
, &p1
),
118 URLMatcherCondition(URLMatcherCondition::HOST_PREFIX
, &p2
)},
119 {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX
, NULL
),
120 URLMatcherCondition(URLMatcherCondition::HOST_PREFIX
, &p2
)},
121 {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX
, &p1
),
122 URLMatcherCondition(URLMatcherCondition::HOST_SUFFIX
, NULL
)},
124 for (size_t i
= 0; i
< arraysize(test_smaller
); ++i
) {
125 EXPECT_TRUE(test_smaller
[i
][0] < test_smaller
[i
][1])
126 << "Test " << i
<< " of test_smaller failed";
127 EXPECT_FALSE(test_smaller
[i
][1] < test_smaller
[i
][0])
128 << "Test " << i
<< " of test_smaller failed";
130 URLMatcherCondition test_equal
[][2] = {
131 {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX
, &p1
),
132 URLMatcherCondition(URLMatcherCondition::HOST_PREFIX
, &p1
)},
133 {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX
, NULL
),
134 URLMatcherCondition(URLMatcherCondition::HOST_PREFIX
, NULL
)},
136 for (size_t i
= 0; i
< arraysize(test_equal
); ++i
) {
137 EXPECT_FALSE(test_equal
[i
][0] < test_equal
[i
][1])
138 << "Test " << i
<< " of test_equal failed";
139 EXPECT_FALSE(test_equal
[i
][1] < test_equal
[i
][0])
140 << "Test " << i
<< " of test_equal failed";
145 // URLMatcherConditionFactory
150 bool Matches(const URLMatcherCondition
& condition
, std::string text
) {
151 return text
.find(condition
.string_pattern()->pattern()) !=
157 TEST(URLMatcherConditionFactoryTest
, GURLCharacterSet
) {
158 // GURL guarantees that neither domain, nor path, nor query may contain
159 // non ASCII-7 characters. We test this here, because a change to this
160 // guarantee breaks this implementation horribly.
161 GURL
url("http://www.föö.com/föö?föö#föö");
162 EXPECT_TRUE(base::IsStringASCII(url
.host()));
163 EXPECT_TRUE(base::IsStringASCII(url
.path()));
164 EXPECT_TRUE(base::IsStringASCII(url
.query()));
165 EXPECT_FALSE(base::IsStringASCII(url
.ref()));
168 TEST(URLMatcherConditionFactoryTest
, Criteria
) {
169 URLMatcherConditionFactory factory
;
170 EXPECT_EQ(URLMatcherCondition::HOST_PREFIX
,
171 factory
.CreateHostPrefixCondition("foo").criterion());
172 EXPECT_EQ(URLMatcherCondition::HOST_SUFFIX
,
173 factory
.CreateHostSuffixCondition("foo").criterion());
174 EXPECT_EQ(URLMatcherCondition::HOST_CONTAINS
,
175 factory
.CreateHostContainsCondition("foo").criterion());
176 EXPECT_EQ(URLMatcherCondition::HOST_EQUALS
,
177 factory
.CreateHostEqualsCondition("foo").criterion());
178 EXPECT_EQ(URLMatcherCondition::PATH_PREFIX
,
179 factory
.CreatePathPrefixCondition("foo").criterion());
180 EXPECT_EQ(URLMatcherCondition::PATH_SUFFIX
,
181 factory
.CreatePathSuffixCondition("foo").criterion());
182 EXPECT_EQ(URLMatcherCondition::PATH_CONTAINS
,
183 factory
.CreatePathContainsCondition("foo").criterion());
184 EXPECT_EQ(URLMatcherCondition::PATH_EQUALS
,
185 factory
.CreatePathEqualsCondition("foo").criterion());
186 EXPECT_EQ(URLMatcherCondition::QUERY_PREFIX
,
187 factory
.CreateQueryPrefixCondition("foo").criterion());
188 EXPECT_EQ(URLMatcherCondition::QUERY_SUFFIX
,
189 factory
.CreateQuerySuffixCondition("foo").criterion());
190 EXPECT_EQ(URLMatcherCondition::QUERY_CONTAINS
,
191 factory
.CreateQueryContainsCondition("foo").criterion());
192 EXPECT_EQ(URLMatcherCondition::QUERY_EQUALS
,
193 factory
.CreateQueryEqualsCondition("foo").criterion());
194 EXPECT_EQ(URLMatcherCondition::HOST_SUFFIX_PATH_PREFIX
,
195 factory
.CreateHostSuffixPathPrefixCondition("foo",
197 EXPECT_EQ(URLMatcherCondition::HOST_EQUALS_PATH_PREFIX
,
198 factory
.CreateHostEqualsPathPrefixCondition("foo",
200 EXPECT_EQ(URLMatcherCondition::URL_PREFIX
,
201 factory
.CreateURLPrefixCondition("foo").criterion());
202 EXPECT_EQ(URLMatcherCondition::URL_SUFFIX
,
203 factory
.CreateURLSuffixCondition("foo").criterion());
204 EXPECT_EQ(URLMatcherCondition::URL_CONTAINS
,
205 factory
.CreateURLContainsCondition("foo").criterion());
206 EXPECT_EQ(URLMatcherCondition::URL_EQUALS
,
207 factory
.CreateURLEqualsCondition("foo").criterion());
208 EXPECT_EQ(URLMatcherCondition::URL_MATCHES
,
209 factory
.CreateURLMatchesCondition("foo").criterion());
212 TEST(URLMatcherConditionFactoryTest
, TestSingletonProperty
) {
213 URLMatcherConditionFactory factory
;
214 URLMatcherCondition c1
= factory
.CreateHostEqualsCondition("www.google.com");
215 URLMatcherCondition c2
= factory
.CreateHostEqualsCondition("www.google.com");
216 EXPECT_EQ(c1
.criterion(), c2
.criterion());
217 EXPECT_EQ(c1
.string_pattern(), c2
.string_pattern());
218 URLMatcherCondition c3
= factory
.CreateHostEqualsCondition("www.google.de");
219 EXPECT_EQ(c2
.criterion(), c3
.criterion());
220 EXPECT_NE(c2
.string_pattern(), c3
.string_pattern());
221 EXPECT_NE(c2
.string_pattern()->id(), c3
.string_pattern()->id());
222 EXPECT_NE(c2
.string_pattern()->pattern(),
223 c3
.string_pattern()->pattern());
224 URLMatcherCondition c4
= factory
.CreateURLMatchesCondition("www.google.com");
225 URLMatcherCondition c5
= factory
.CreateURLContainsCondition("www.google.com");
226 // Regex patterns and substring patterns do not share IDs.
227 EXPECT_EQ(c5
.string_pattern()->pattern(), c4
.string_pattern()->pattern());
228 EXPECT_NE(c5
.string_pattern(), c4
.string_pattern());
229 EXPECT_NE(c5
.string_pattern()->id(), c4
.string_pattern()->id());
231 // Check that all StringPattern singletons are freed if we call
232 // ForgetUnusedPatterns.
233 StringPattern::ID old_id_1
= c1
.string_pattern()->id();
234 StringPattern::ID old_id_4
= c4
.string_pattern()->id();
235 factory
.ForgetUnusedPatterns(std::set
<StringPattern::ID
>());
236 EXPECT_TRUE(factory
.IsEmpty());
237 URLMatcherCondition c6
= factory
.CreateHostEqualsCondition("www.google.com");
238 EXPECT_NE(old_id_1
, c6
.string_pattern()->id());
239 URLMatcherCondition c7
= factory
.CreateURLMatchesCondition("www.google.com");
240 EXPECT_NE(old_id_4
, c7
.string_pattern()->id());
243 TEST(URLMatcherConditionFactoryTest
, TestComponentSearches
) {
244 GURL
gurl("https://www.google.com:1234/webhp?sourceid=chrome-instant&ie=UTF-8"
245 "&ion=1#hl=en&output=search&sclient=psy-ab&q=chrome%20is%20awesome");
246 URLMatcherConditionFactory factory
;
247 std::string url
= factory
.CanonicalizeURLForComponentSearches(gurl
);
249 // Test host component.
250 EXPECT_TRUE(Matches(factory
.CreateHostPrefixCondition(std::string()), url
));
251 EXPECT_TRUE(Matches(factory
.CreateHostPrefixCondition("www.goog"), url
));
253 Matches(factory
.CreateHostPrefixCondition("www.google.com"), url
));
255 Matches(factory
.CreateHostPrefixCondition(".www.google.com"), url
));
256 EXPECT_FALSE(Matches(factory
.CreateHostPrefixCondition("google.com"), url
));
258 Matches(factory
.CreateHostPrefixCondition("www.google.com/"), url
));
259 EXPECT_FALSE(Matches(factory
.CreateHostPrefixCondition("webhp"), url
));
261 EXPECT_TRUE(Matches(factory
.CreateHostSuffixCondition(std::string()), url
));
262 EXPECT_TRUE(Matches(factory
.CreateHostSuffixCondition("com"), url
));
263 EXPECT_TRUE(Matches(factory
.CreateHostSuffixCondition(".com"), url
));
265 Matches(factory
.CreateHostSuffixCondition("www.google.com"), url
));
267 Matches(factory
.CreateHostSuffixCondition(".www.google.com"), url
));
268 EXPECT_FALSE(Matches(factory
.CreateHostSuffixCondition("www"), url
));
270 Matches(factory
.CreateHostSuffixCondition("www.google.com/"), url
));
271 EXPECT_FALSE(Matches(factory
.CreateHostSuffixCondition("webhp"), url
));
273 EXPECT_FALSE(Matches(factory
.CreateHostEqualsCondition(std::string()), url
));
274 EXPECT_FALSE(Matches(factory
.CreateHostEqualsCondition("www"), url
));
276 Matches(factory
.CreateHostEqualsCondition("www.google.com"), url
));
278 Matches(factory
.CreateHostEqualsCondition("www.google.com/"), url
));
281 // Test path component.
282 EXPECT_TRUE(Matches(factory
.CreatePathPrefixCondition(std::string()), url
));
283 EXPECT_TRUE(Matches(factory
.CreatePathPrefixCondition("/web"), url
));
284 EXPECT_TRUE(Matches(factory
.CreatePathPrefixCondition("/webhp"), url
));
285 EXPECT_FALSE(Matches(factory
.CreatePathPrefixCondition("webhp"), url
));
286 EXPECT_FALSE(Matches(factory
.CreatePathPrefixCondition("/webhp?"), url
));
287 EXPECT_FALSE(Matches(factory
.CreatePathPrefixCondition("?sourceid"), url
));
289 EXPECT_TRUE(Matches(factory
.CreatePathSuffixCondition(std::string()), url
));
290 EXPECT_TRUE(Matches(factory
.CreatePathSuffixCondition("webhp"), url
));
291 EXPECT_TRUE(Matches(factory
.CreatePathSuffixCondition("/webhp"), url
));
292 EXPECT_FALSE(Matches(factory
.CreatePathSuffixCondition("/web"), url
));
293 EXPECT_FALSE(Matches(factory
.CreatePathSuffixCondition("/webhp?"), url
));
295 EXPECT_TRUE(Matches(factory
.CreatePathEqualsCondition("/webhp"), url
));
296 EXPECT_FALSE(Matches(factory
.CreatePathEqualsCondition("webhp"), url
));
297 EXPECT_FALSE(Matches(factory
.CreatePathEqualsCondition("/webhp?"), url
));
299 Matches(factory
.CreatePathEqualsCondition("www.google.com"), url
));
302 // Test query component.
303 EXPECT_TRUE(Matches(factory
.CreateQueryPrefixCondition(std::string()), url
));
304 EXPECT_TRUE(Matches(factory
.CreateQueryPrefixCondition("sourceid"), url
));
305 // The '?' at the beginning is just ignored.
306 EXPECT_TRUE(Matches(factory
.CreateQueryPrefixCondition("?sourceid"), url
));
308 EXPECT_TRUE(Matches(factory
.CreateQuerySuffixCondition(std::string()), url
));
309 EXPECT_TRUE(Matches(factory
.CreateQuerySuffixCondition("ion=1"), url
));
310 EXPECT_FALSE(Matches(factory
.CreateQuerySuffixCondition("www"), url
));
311 // "Suffix" condition + pattern starting with '?' = "equals" condition.
312 EXPECT_FALSE(Matches(factory
.CreateQuerySuffixCondition(
313 "?sourceid=chrome-instant&ie=UTF-8&ion="), url
));
314 EXPECT_TRUE(Matches(factory
.CreateQuerySuffixCondition(
315 "?sourceid=chrome-instant&ie=UTF-8&ion=1"), url
));
317 EXPECT_FALSE(Matches(factory
.CreateQueryEqualsCondition(
318 "?sourceid=chrome-instant&ie=UTF-8&ion="), url
));
319 EXPECT_FALSE(Matches(factory
.CreateQueryEqualsCondition(
320 "sourceid=chrome-instant&ie=UTF-8&ion="), url
));
321 EXPECT_TRUE(Matches(factory
.CreateQueryEqualsCondition(
322 "sourceid=chrome-instant&ie=UTF-8&ion=1"), url
));
323 // The '?' at the beginning is just ignored.
324 EXPECT_TRUE(Matches(factory
.CreateQueryEqualsCondition(
325 "?sourceid=chrome-instant&ie=UTF-8&ion=1"), url
));
327 Matches(factory
.CreateQueryEqualsCondition("www.google.com"), url
));
330 // Test adjacent components
331 EXPECT_TRUE(Matches(factory
.CreateHostSuffixPathPrefixCondition(
332 "google.com", "/webhp"), url
));
334 factory
.CreateHostSuffixPathPrefixCondition(std::string(), "/webhp"),
337 factory
.CreateHostSuffixPathPrefixCondition("google.com", std::string()),
339 EXPECT_FALSE(Matches(
340 factory
.CreateHostSuffixPathPrefixCondition("www", std::string()), url
));
342 EXPECT_TRUE(Matches(factory
.CreateHostEqualsPathPrefixCondition(
343 "www.google.com", "/webhp"), url
));
344 EXPECT_FALSE(Matches(
345 factory
.CreateHostEqualsPathPrefixCondition(std::string(), "/webhp"),
347 EXPECT_TRUE(Matches(factory
.CreateHostEqualsPathPrefixCondition(
348 "www.google.com", std::string()),
350 EXPECT_FALSE(Matches(
351 factory
.CreateHostEqualsPathPrefixCondition("google.com", std::string()),
355 TEST(URLMatcherConditionFactoryTest
, TestFullSearches
) {
356 // The Port 443 is stripped because it is the default port for https.
357 GURL
gurl("https://www.google.com:443/webhp?sourceid=chrome-instant&ie=UTF-8"
358 "&ion=1#hl=en&output=search&sclient=psy-ab&q=chrome%20is%20awesome");
359 URLMatcherConditionFactory factory
;
360 std::string url
= factory
.CanonicalizeURLForFullSearches(gurl
);
362 EXPECT_TRUE(Matches(factory
.CreateURLPrefixCondition(std::string()), url
));
364 Matches(factory
.CreateURLPrefixCondition("https://www.goog"), url
));
365 EXPECT_TRUE(Matches(factory
.CreateURLPrefixCondition(
366 "https://www.google.com"), url
));
367 EXPECT_TRUE(Matches(factory
.CreateURLPrefixCondition(
368 "https://www.google.com/webhp?"), url
));
369 EXPECT_FALSE(Matches(factory
.CreateURLPrefixCondition(
370 "http://www.google.com"), url
));
371 EXPECT_FALSE(Matches(factory
.CreateURLPrefixCondition("webhp"), url
));
373 EXPECT_TRUE(Matches(factory
.CreateURLSuffixCondition(std::string()), url
));
374 EXPECT_TRUE(Matches(factory
.CreateURLSuffixCondition("ion=1"), url
));
375 EXPECT_FALSE(Matches(factory
.CreateURLSuffixCondition("www"), url
));
377 EXPECT_TRUE(Matches(factory
.CreateURLContainsCondition(std::string()), url
));
378 EXPECT_TRUE(Matches(factory
.CreateURLContainsCondition("www.goog"), url
));
379 EXPECT_TRUE(Matches(factory
.CreateURLContainsCondition("webhp"), url
));
380 EXPECT_TRUE(Matches(factory
.CreateURLContainsCondition("?"), url
));
381 EXPECT_TRUE(Matches(factory
.CreateURLContainsCondition("sourceid"), url
));
382 EXPECT_TRUE(Matches(factory
.CreateURLContainsCondition("ion=1"), url
));
383 EXPECT_FALSE(Matches(factory
.CreateURLContainsCondition(".www.goog"), url
));
384 EXPECT_FALSE(Matches(factory
.CreateURLContainsCondition("foobar"), url
));
385 EXPECT_FALSE(Matches(factory
.CreateURLContainsCondition("search"), url
));
386 EXPECT_FALSE(Matches(factory
.CreateURLContainsCondition(":443"), url
));
388 EXPECT_TRUE(Matches(factory
.CreateURLEqualsCondition(
389 "https://www.google.com/webhp?sourceid=chrome-instant&ie=UTF-8&ion=1"),
392 Matches(factory
.CreateURLEqualsCondition("https://www.google.com"), url
));
394 // Same as above but this time with a non-standard port.
395 gurl
= GURL("https://www.google.com:1234/webhp?sourceid=chrome-instant&"
396 "ie=UTF-8&ion=1#hl=en&output=search&sclient=psy-ab&q=chrome%20is%20"
398 url
= factory
.CanonicalizeURLForFullSearches(gurl
);
399 EXPECT_TRUE(Matches(factory
.CreateURLPrefixCondition(
400 "https://www.google.com:1234/webhp?"), url
));
401 EXPECT_TRUE(Matches(factory
.CreateURLContainsCondition(":1234"), url
));
405 // URLMatcherConditionSet
408 TEST(URLMatcherConditionSetTest
, Constructor
) {
409 URLMatcherConditionFactory factory
;
410 URLMatcherCondition m1
= factory
.CreateHostSuffixCondition("example.com");
411 URLMatcherCondition m2
= factory
.CreatePathContainsCondition("foo");
413 std::set
<URLMatcherCondition
> conditions
;
414 conditions
.insert(m1
);
415 conditions
.insert(m2
);
417 scoped_refptr
<URLMatcherConditionSet
> condition_set(
418 new URLMatcherConditionSet(1, conditions
));
419 EXPECT_EQ(1, condition_set
->id());
420 EXPECT_EQ(2u, condition_set
->conditions().size());
423 TEST(URLMatcherConditionSetTest
, Matching
) {
424 GURL
url1("http://www.example.com/foo?bar=1");
425 GURL
url2("http://foo.example.com/index.html");
426 GURL
url3("http://www.example.com:80/foo?bar=1");
427 GURL
url4("http://www.example.com:8080/foo?bar=1");
429 URLMatcherConditionFactory factory
;
430 URLMatcherCondition m1
= factory
.CreateHostSuffixCondition("example.com");
431 URLMatcherCondition m2
= factory
.CreatePathContainsCondition("foo");
433 std::set
<URLMatcherCondition
> conditions
;
434 conditions
.insert(m1
);
435 conditions
.insert(m2
);
437 scoped_refptr
<URLMatcherConditionSet
> condition_set(
438 new URLMatcherConditionSet(1, conditions
));
439 EXPECT_EQ(1, condition_set
->id());
440 EXPECT_EQ(2u, condition_set
->conditions().size());
442 std::set
<StringPattern::ID
> matching_patterns
;
443 matching_patterns
.insert(m1
.string_pattern()->id());
444 EXPECT_FALSE(condition_set
->IsMatch(matching_patterns
, url1
));
446 matching_patterns
.insert(m2
.string_pattern()->id());
447 EXPECT_TRUE(condition_set
->IsMatch(matching_patterns
, url1
));
448 EXPECT_FALSE(condition_set
->IsMatch(matching_patterns
, url2
));
450 // Test scheme filters.
451 scoped_refptr
<URLMatcherConditionSet
> condition_set2(
452 new URLMatcherConditionSet(1,
454 scoped_ptr
<URLMatcherSchemeFilter
>(
455 new URLMatcherSchemeFilter("https")),
456 scoped_ptr
<URLMatcherPortFilter
>()));
457 EXPECT_FALSE(condition_set2
->IsMatch(matching_patterns
, url1
));
458 scoped_refptr
<URLMatcherConditionSet
> condition_set3(
459 new URLMatcherConditionSet(1,
461 scoped_ptr
<URLMatcherSchemeFilter
>(
462 new URLMatcherSchemeFilter("http")),
463 scoped_ptr
<URLMatcherPortFilter
>()));
464 EXPECT_TRUE(condition_set3
->IsMatch(matching_patterns
, url1
));
466 // Test port filters.
467 std::vector
<URLMatcherPortFilter::Range
> ranges
;
468 ranges
.push_back(URLMatcherPortFilter::CreateRange(80));
469 scoped_ptr
<URLMatcherPortFilter
> filter(new URLMatcherPortFilter(ranges
));
470 scoped_refptr
<URLMatcherConditionSet
> condition_set4(
471 new URLMatcherConditionSet(
472 1, conditions
, scoped_ptr
<URLMatcherSchemeFilter
>(), filter
.Pass()));
473 EXPECT_TRUE(condition_set4
->IsMatch(matching_patterns
, url1
));
474 EXPECT_TRUE(condition_set4
->IsMatch(matching_patterns
, url3
));
475 EXPECT_FALSE(condition_set4
->IsMatch(matching_patterns
, url4
));
477 // Test regex patterns.
478 matching_patterns
.clear();
479 URLMatcherCondition r1
= factory
.CreateURLMatchesCondition("/fo?oo");
480 std::set
<URLMatcherCondition
> regex_conditions
;
481 regex_conditions
.insert(r1
);
482 scoped_refptr
<URLMatcherConditionSet
> condition_set5(
483 new URLMatcherConditionSet(1, regex_conditions
));
484 EXPECT_FALSE(condition_set5
->IsMatch(matching_patterns
, url1
));
485 matching_patterns
.insert(r1
.string_pattern()->id());
486 EXPECT_TRUE(condition_set5
->IsMatch(matching_patterns
, url1
));
488 regex_conditions
.insert(m1
);
489 scoped_refptr
<URLMatcherConditionSet
> condition_set6(
490 new URLMatcherConditionSet(1, regex_conditions
));
491 EXPECT_FALSE(condition_set6
->IsMatch(matching_patterns
, url1
));
492 matching_patterns
.insert(m1
.string_pattern()->id());
493 EXPECT_TRUE(condition_set6
->IsMatch(matching_patterns
, url1
));
495 matching_patterns
.clear();
496 regex_conditions
.clear();
497 URLMatcherCondition r2
= factory
.CreateOriginAndPathMatchesCondition("b[a]r");
498 regex_conditions
.insert(r2
);
499 scoped_refptr
<URLMatcherConditionSet
> condition_set7(
500 new URLMatcherConditionSet(1, regex_conditions
));
501 EXPECT_FALSE(condition_set7
->IsMatch(matching_patterns
, url1
));
502 matching_patterns
.insert(r2
.string_pattern()->id());
503 EXPECT_TRUE(condition_set7
->IsMatch(matching_patterns
, url1
));
509 const std::string
& url_query
,
510 const std::string
& key
,
511 URLQueryElementMatcherCondition::QueryElementType query_element_type
,
512 const std::string
& value
,
513 URLQueryElementMatcherCondition::QueryValueMatchType query_value_match_type
,
514 URLQueryElementMatcherCondition::Type match_type
) {
515 URLMatcherConditionFactory factory
;
517 URLMatcherCondition m1
= factory
.CreateHostSuffixCondition("example.com");
518 URLMatcherCondition m2
= factory
.CreatePathContainsCondition("foo");
519 URLMatcherConditionSet::Conditions conditions
;
520 conditions
.insert(m1
);
521 conditions
.insert(m2
);
523 URLQueryElementMatcherCondition
q1(key
,
525 query_value_match_type
,
529 URLMatcherConditionSet::QueryConditions query_conditions
;
530 query_conditions
.insert(q1
);
532 scoped_ptr
<URLMatcherSchemeFilter
> scheme_filter
;
533 scoped_ptr
<URLMatcherPortFilter
> port_filter
;
535 scoped_refptr
<URLMatcherConditionSet
> condition_set(
536 new URLMatcherConditionSet(1,
539 scheme_filter
.Pass(),
540 port_filter
.Pass()));
542 GURL
url("http://www.example.com/foo?" + url_query
);
545 URLMatcherConditionSet::Vector vector
;
546 vector
.push_back(condition_set
);
547 matcher
.AddConditionSets(vector
);
549 return matcher
.MatchURL(url
).size() == 1;
554 TEST(URLMatcherConditionSetTest
, QueryMatching
) {
556 IsQueryMatch("a=foo&b=foo&a=barr",
558 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE
,
560 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX
,
561 URLQueryElementMatcherCondition::MATCH_ANY
));
563 IsQueryMatch("a=foo&b=foo&a=barr",
565 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE
,
567 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT
,
568 URLQueryElementMatcherCondition::MATCH_ANY
));
570 IsQueryMatch("a=foo&b=foo&a=barr",
572 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY
,
574 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX
,
575 URLQueryElementMatcherCondition::MATCH_ANY
));
577 IsQueryMatch("a=foo&b=foo&a=barr",
579 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY
,
581 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT
,
582 URLQueryElementMatcherCondition::MATCH_ANY
));
584 IsQueryMatch("a&b=foo&a=barr",
586 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY
,
588 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT
,
589 URLQueryElementMatcherCondition::MATCH_ANY
));
591 IsQueryMatch("a=foo&b=foo&a=barr",
593 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY
,
595 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT
,
596 URLQueryElementMatcherCondition::MATCH_ANY
));
599 IsQueryMatch("a=foo&b=foo&a=bar",
601 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE
,
603 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT
,
604 URLQueryElementMatcherCondition::MATCH_ALL
));
606 IsQueryMatch("a=bar&b=foo&a=bar",
608 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE
,
610 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT
,
611 URLQueryElementMatcherCondition::MATCH_ALL
));
613 IsQueryMatch("a=bar&b=foo&a=bar",
615 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE
,
617 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT
,
618 URLQueryElementMatcherCondition::MATCH_ALL
));
620 IsQueryMatch("a=bar&b=foo&a=bar",
622 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE
,
624 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT
,
625 URLQueryElementMatcherCondition::MATCH_ALL
));
627 IsQueryMatch("a=bar&b=foo&a=bar",
629 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE
,
631 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT
,
632 URLQueryElementMatcherCondition::MATCH_ALL
));
634 IsQueryMatch("a=foo1&b=foo&a=foo2",
636 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE
,
638 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX
,
639 URLQueryElementMatcherCondition::MATCH_ALL
));
641 IsQueryMatch("a=foo1&b=foo&a=fo02",
643 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE
,
645 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX
,
646 URLQueryElementMatcherCondition::MATCH_ALL
));
648 IsQueryMatch("a&b=foo&a",
650 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY
,
652 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX
,
653 URLQueryElementMatcherCondition::MATCH_ALL
));
655 IsQueryMatch("alt&b=foo",
657 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY
,
659 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX
,
660 URLQueryElementMatcherCondition::MATCH_ALL
));
662 IsQueryMatch("b=foo&a",
664 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY
,
666 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX
,
667 URLQueryElementMatcherCondition::MATCH_ALL
));
669 IsQueryMatch("b=foo",
671 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY
,
673 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX
,
674 URLQueryElementMatcherCondition::MATCH_ALL
));
676 IsQueryMatch("b=foo&a",
678 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY
,
680 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT
,
681 URLQueryElementMatcherCondition::MATCH_ALL
));
684 IsQueryMatch("a=foo&b=foo&a=bar",
686 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE
,
688 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT
,
689 URLQueryElementMatcherCondition::MATCH_FIRST
));
691 IsQueryMatch("a=foo&b=foo&a=bar",
693 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE
,
695 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT
,
696 URLQueryElementMatcherCondition::MATCH_FIRST
));
698 IsQueryMatch("a=foo1&b=foo&a=bar",
700 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE
,
702 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX
,
703 URLQueryElementMatcherCondition::MATCH_FIRST
));
705 IsQueryMatch("a=foo1&b=foo&a=bar",
707 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE
,
709 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT
,
710 URLQueryElementMatcherCondition::MATCH_FIRST
));
712 IsQueryMatch("a&b=foo&a=bar",
714 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY
,
716 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT
,
717 URLQueryElementMatcherCondition::MATCH_FIRST
));
719 IsQueryMatch("alt&b=foo&a=bar",
721 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY
,
723 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX
,
724 URLQueryElementMatcherCondition::MATCH_FIRST
));
726 IsQueryMatch("alt&b=foo&a=bar",
728 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY
,
730 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT
,
731 URLQueryElementMatcherCondition::MATCH_FIRST
));
734 IsQueryMatch("a=foo&b=foo&a=bar",
736 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE
,
738 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT
,
739 URLQueryElementMatcherCondition::MATCH_LAST
));
741 IsQueryMatch("a=foo&b=foo&a=bar",
743 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE
,
745 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT
,
746 URLQueryElementMatcherCondition::MATCH_LAST
));
748 IsQueryMatch("a=foo1&b=foo&a=bar",
750 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE
,
752 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX
,
753 URLQueryElementMatcherCondition::MATCH_LAST
));
755 IsQueryMatch("a=foo1&b=foo&a=bar1",
757 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE
,
759 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX
,
760 URLQueryElementMatcherCondition::MATCH_LAST
));
762 IsQueryMatch("a&b=foo&a=bar",
764 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY
,
766 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT
,
767 URLQueryElementMatcherCondition::MATCH_LAST
));
769 IsQueryMatch("b=foo&alt",
771 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY
,
773 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX
,
774 URLQueryElementMatcherCondition::MATCH_LAST
));
776 IsQueryMatch("b=foo&alt",
778 URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY
,
780 URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT
,
781 URLQueryElementMatcherCondition::MATCH_LAST
));
788 TEST(URLMatcherTest
, FullTest
) {
789 GURL
url1("http://www.example.com/foo?bar=1");
790 GURL
url2("http://foo.example.com/index.html");
793 URLMatcherConditionFactory
* factory
= matcher
.condition_factory();
796 URLMatcherConditionSet::Conditions conditions1
;
797 conditions1
.insert(factory
->CreateHostSuffixCondition("example.com"));
798 conditions1
.insert(factory
->CreatePathContainsCondition("foo"));
800 const int kConditionSetId1
= 1;
801 URLMatcherConditionSet::Vector insert1
;
802 insert1
.push_back(make_scoped_refptr(
803 new URLMatcherConditionSet(kConditionSetId1
, conditions1
)));
804 matcher
.AddConditionSets(insert1
);
805 EXPECT_EQ(1u, matcher
.MatchURL(url1
).size());
806 EXPECT_EQ(0u, matcher
.MatchURL(url2
).size());
809 URLMatcherConditionSet::Conditions conditions2
;
810 conditions2
.insert(factory
->CreateHostSuffixCondition("example.com"));
812 const int kConditionSetId2
= 2;
813 URLMatcherConditionSet::Vector insert2
;
814 insert2
.push_back(make_scoped_refptr(
815 new URLMatcherConditionSet(kConditionSetId2
, conditions2
)));
816 matcher
.AddConditionSets(insert2
);
817 EXPECT_EQ(2u, matcher
.MatchURL(url1
).size());
818 EXPECT_EQ(1u, matcher
.MatchURL(url2
).size());
820 // This should be the cached singleton.
821 int patternId1
= factory
->CreateHostSuffixCondition(
822 "example.com").string_pattern()->id();
825 URLMatcherConditionSet::Conditions conditions3
;
826 conditions3
.insert(factory
->CreateHostSuffixCondition("example.com"));
827 conditions3
.insert(factory
->CreateURLMatchesCondition("x.*[0-9]"));
829 const int kConditionSetId3
= 3;
830 URLMatcherConditionSet::Vector insert3
;
831 insert3
.push_back(make_scoped_refptr(
832 new URLMatcherConditionSet(kConditionSetId3
, conditions3
)));
833 matcher
.AddConditionSets(insert3
);
834 EXPECT_EQ(3u, matcher
.MatchURL(url1
).size());
835 EXPECT_EQ(1u, matcher
.MatchURL(url2
).size());
837 // Removal of third insert.
838 std::vector
<URLMatcherConditionSet::ID
> remove3
;
839 remove3
.push_back(kConditionSetId3
);
840 matcher
.RemoveConditionSets(remove3
);
841 EXPECT_EQ(2u, matcher
.MatchURL(url1
).size());
842 EXPECT_EQ(1u, matcher
.MatchURL(url2
).size());
844 // Removal of second insert.
845 std::vector
<URLMatcherConditionSet::ID
> remove2
;
846 remove2
.push_back(kConditionSetId2
);
847 matcher
.RemoveConditionSets(remove2
);
848 EXPECT_EQ(1u, matcher
.MatchURL(url1
).size());
849 EXPECT_EQ(0u, matcher
.MatchURL(url2
).size());
851 // Removal of first insert.
852 std::vector
<URLMatcherConditionSet::ID
> remove1
;
853 remove1
.push_back(kConditionSetId1
);
854 matcher
.RemoveConditionSets(remove1
);
855 EXPECT_EQ(0u, matcher
.MatchURL(url1
).size());
856 EXPECT_EQ(0u, matcher
.MatchURL(url2
).size());
858 EXPECT_TRUE(matcher
.IsEmpty());
860 // The cached singleton in matcher.condition_factory_ should be destroyed to
862 int patternId2
= factory
->CreateHostSuffixCondition(
863 "example.com").string_pattern()->id();
864 // If patternId1 and patternId2 are different that indicates that
865 // matcher.condition_factory_ does not leak memory by holding onto
867 EXPECT_NE(patternId1
, patternId2
);
870 TEST(URLMatcherTest
, TestComponentsImplyContains
) {
871 // Due to a different implementation of component (prefix, suffix and equals)
872 // and *Contains conditions we need to check that when a pattern matches a
873 // given part of a URL as equal, prefix or suffix, it also matches it in the
875 GURL
url("https://www.google.com:1234/webhp?test=val&a=b");
878 URLMatcherConditionFactory
* factory
= matcher
.condition_factory();
880 URLMatcherConditionSet::Conditions conditions
;
882 // First insert all the matching equals => contains pairs.
883 conditions
.insert(factory
->CreateHostEqualsCondition("www.google.com"));
884 conditions
.insert(factory
->CreateHostContainsCondition("www.google.com"));
886 conditions
.insert(factory
->CreateHostPrefixCondition("www."));
887 conditions
.insert(factory
->CreateHostContainsCondition("www."));
889 conditions
.insert(factory
->CreateHostSuffixCondition("com"));
890 conditions
.insert(factory
->CreateHostContainsCondition("com"));
892 conditions
.insert(factory
->CreatePathEqualsCondition("/webhp"));
893 conditions
.insert(factory
->CreatePathContainsCondition("/webhp"));
895 conditions
.insert(factory
->CreatePathPrefixCondition("/we"));
896 conditions
.insert(factory
->CreatePathContainsCondition("/we"));
898 conditions
.insert(factory
->CreatePathSuffixCondition("hp"));
899 conditions
.insert(factory
->CreatePathContainsCondition("hp"));
901 conditions
.insert(factory
->CreateQueryEqualsCondition("test=val&a=b"));
902 conditions
.insert(factory
->CreateQueryContainsCondition("test=val&a=b"));
904 conditions
.insert(factory
->CreateQueryPrefixCondition("test=v"));
905 conditions
.insert(factory
->CreateQueryContainsCondition("test=v"));
907 conditions
.insert(factory
->CreateQuerySuffixCondition("l&a=b"));
908 conditions
.insert(factory
->CreateQueryContainsCondition("l&a=b"));
910 // The '?' for equality is just ignored.
911 conditions
.insert(factory
->CreateQueryEqualsCondition("?test=val&a=b"));
912 // Due to '?' the condition created here is a prefix-testing condition.
913 conditions
.insert(factory
->CreateQueryContainsCondition("?test=val&a=b"));
915 const int kConditionSetId
= 1;
916 URLMatcherConditionSet::Vector insert
;
917 insert
.push_back(make_scoped_refptr(
918 new URLMatcherConditionSet(kConditionSetId
, conditions
)));
919 matcher
.AddConditionSets(insert
);
920 EXPECT_EQ(1u, matcher
.MatchURL(url
).size());
923 // Check that matches in everything but the query are found.
924 TEST(URLMatcherTest
, TestOriginAndPathRegExPositive
) {
925 GURL
url("https://www.google.com:1234/webhp?test=val&a=b");
928 URLMatcherConditionFactory
* factory
= matcher
.condition_factory();
930 URLMatcherConditionSet::Conditions conditions
;
932 conditions
.insert(factory
->CreateOriginAndPathMatchesCondition("w..hp"));
933 const int kConditionSetId
= 1;
934 URLMatcherConditionSet::Vector insert
;
935 insert
.push_back(make_scoped_refptr(
936 new URLMatcherConditionSet(kConditionSetId
, conditions
)));
937 matcher
.AddConditionSets(insert
);
938 EXPECT_EQ(1u, matcher
.MatchURL(url
).size());
941 // Check that matches in the query are ignored.
942 TEST(URLMatcherTest
, TestOriginAndPathRegExNegative
) {
943 GURL
url("https://www.google.com:1234/webhp?test=val&a=b");
946 URLMatcherConditionFactory
* factory
= matcher
.condition_factory();
948 URLMatcherConditionSet::Conditions conditions
;
950 conditions
.insert(factory
->CreateOriginAndPathMatchesCondition("val"));
951 const int kConditionSetId
= 1;
952 URLMatcherConditionSet::Vector insert
;
953 insert
.push_back(make_scoped_refptr(
954 new URLMatcherConditionSet(kConditionSetId
, conditions
)));
955 matcher
.AddConditionSets(insert
);
956 EXPECT_EQ(0u, matcher
.MatchURL(url
).size());
959 } // namespace url_matcher