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. 4 5#include "components/url_matcher/url_matcher.h" 6 7#include "base/strings/string_util.h" 8#include "testing/gtest/include/gtest/gtest.h" 9#include "url/gurl.h" 10 11namespace url_matcher { 12 13// 14// URLMatcherCondition 15// 16 17TEST(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()); 22 23 URLMatcherCondition m2; 24 m2 = m1; 25 EXPECT_EQ(URLMatcherCondition::HOST_SUFFIX, m2.criterion()); 26 EXPECT_EQ(&pattern, m2.string_pattern()); 27 28 URLMatcherCondition m3(m1); 29 EXPECT_EQ(URLMatcherCondition::HOST_SUFFIX, m3.criterion()); 30 EXPECT_EQ(&pattern, m3.string_pattern()); 31} 32 33TEST(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); 39 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)); 46} 47 48TEST(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"))); 61} 62 63TEST(URLMatcherConditionTest, IsFullURLCondition) { 64 StringPattern pattern("example.com", 1); 65 EXPECT_FALSE(URLMatcherCondition(URLMatcherCondition::HOST_SUFFIX, 66 &pattern).IsFullURLCondition()); 67 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()); 74 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()); 83} 84 85TEST(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"); 88 89 StringPattern pattern("example.com", 1); 90 URLMatcherCondition m1(URLMatcherCondition::HOST_SUFFIX, &pattern); 91 92 std::set<StringPattern::ID> matching_patterns; 93 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)); 97 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)); 101 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)); 108} 109 110TEST(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)}, 123 }; 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"; 129 } 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)}, 135 }; 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"; 141 } 142} 143 144// 145// URLMatcherConditionFactory 146// 147 148namespace { 149 150bool Matches(const URLMatcherCondition& condition, std::string text) { 151 return text.find(condition.string_pattern()->pattern()) != 152 std::string::npos; 153} 154 155} // namespace 156 157TEST(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(IsStringASCII(url.host())); 163 EXPECT_TRUE(IsStringASCII(url.path())); 164 EXPECT_TRUE(IsStringASCII(url.query())); 165 EXPECT_FALSE(IsStringASCII(url.ref())); 166} 167 168TEST(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", 196 "bar").criterion()); 197 EXPECT_EQ(URLMatcherCondition::HOST_EQUALS_PATH_PREFIX, 198 factory.CreateHostEqualsPathPrefixCondition("foo", 199 "bar").criterion()); 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()); 210} 211 212TEST(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()); 230 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()); 241} 242 243TEST(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); 248 249 // Test host component. 250 EXPECT_TRUE(Matches(factory.CreateHostPrefixCondition(std::string()), url)); 251 EXPECT_TRUE(Matches(factory.CreateHostPrefixCondition("www.goog"), url)); 252 EXPECT_TRUE( 253 Matches(factory.CreateHostPrefixCondition("www.google.com"), url)); 254 EXPECT_TRUE( 255 Matches(factory.CreateHostPrefixCondition(".www.google.com"), url)); 256 EXPECT_FALSE(Matches(factory.CreateHostPrefixCondition("google.com"), url)); 257 EXPECT_FALSE( 258 Matches(factory.CreateHostPrefixCondition("www.google.com/"), url)); 259 EXPECT_FALSE(Matches(factory.CreateHostPrefixCondition("webhp"), url)); 260 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)); 264 EXPECT_TRUE( 265 Matches(factory.CreateHostSuffixCondition("www.google.com"), url)); 266 EXPECT_TRUE( 267 Matches(factory.CreateHostSuffixCondition(".www.google.com"), url)); 268 EXPECT_FALSE(Matches(factory.CreateHostSuffixCondition("www"), url)); 269 EXPECT_FALSE( 270 Matches(factory.CreateHostSuffixCondition("www.google.com/"), url)); 271 EXPECT_FALSE(Matches(factory.CreateHostSuffixCondition("webhp"), url)); 272 273 EXPECT_FALSE(Matches(factory.CreateHostEqualsCondition(std::string()), url)); 274 EXPECT_FALSE(Matches(factory.CreateHostEqualsCondition("www"), url)); 275 EXPECT_TRUE( 276 Matches(factory.CreateHostEqualsCondition("www.google.com"), url)); 277 EXPECT_FALSE( 278 Matches(factory.CreateHostEqualsCondition("www.google.com/"), url)); 279 280 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)); 288 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)); 294 295 EXPECT_TRUE(Matches(factory.CreatePathEqualsCondition("/webhp"), url)); 296 EXPECT_FALSE(Matches(factory.CreatePathEqualsCondition("webhp"), url)); 297 EXPECT_FALSE(Matches(factory.CreatePathEqualsCondition("/webhp?"), url)); 298 EXPECT_FALSE( 299 Matches(factory.CreatePathEqualsCondition("www.google.com"), url)); 300 301 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)); 307 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)); 316 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)); 326 EXPECT_FALSE( 327 Matches(factory.CreateQueryEqualsCondition("www.google.com"), url)); 328 329 330 // Test adjacent components 331 EXPECT_TRUE(Matches(factory.CreateHostSuffixPathPrefixCondition( 332 "google.com", "/webhp"), url)); 333 EXPECT_TRUE(Matches( 334 factory.CreateHostSuffixPathPrefixCondition(std::string(), "/webhp"), 335 url)); 336 EXPECT_TRUE(Matches( 337 factory.CreateHostSuffixPathPrefixCondition("google.com", std::string()), 338 url)); 339 EXPECT_FALSE(Matches( 340 factory.CreateHostSuffixPathPrefixCondition("www", std::string()), url)); 341 342 EXPECT_TRUE(Matches(factory.CreateHostEqualsPathPrefixCondition( 343 "www.google.com", "/webhp"), url)); 344 EXPECT_FALSE(Matches( 345 factory.CreateHostEqualsPathPrefixCondition(std::string(), "/webhp"), 346 url)); 347 EXPECT_TRUE(Matches(factory.CreateHostEqualsPathPrefixCondition( 348 "www.google.com", std::string()), 349 url)); 350 EXPECT_FALSE(Matches( 351 factory.CreateHostEqualsPathPrefixCondition("google.com", std::string()), 352 url)); 353} 354 355TEST(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); 361 362 EXPECT_TRUE(Matches(factory.CreateURLPrefixCondition(std::string()), url)); 363 EXPECT_TRUE( 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)); 372 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)); 376 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)); 387 388 EXPECT_TRUE(Matches(factory.CreateURLEqualsCondition( 389 "https://www.google.com/webhp?sourceid=chrome-instant&ie=UTF-8&ion=1"), 390 url)); 391 EXPECT_FALSE( 392 Matches(factory.CreateURLEqualsCondition("https://www.google.com"), url)); 393 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" 397 "awesome"); 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)); 402} 403 404// 405// URLMatcherConditionSet 406// 407 408TEST(URLMatcherConditionSetTest, Constructor) { 409 URLMatcherConditionFactory factory; 410 URLMatcherCondition m1 = factory.CreateHostSuffixCondition("example.com"); 411 URLMatcherCondition m2 = factory.CreatePathContainsCondition("foo"); 412 413 std::set<URLMatcherCondition> conditions; 414 conditions.insert(m1); 415 conditions.insert(m2); 416 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()); 421} 422 423TEST(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"); 428 429 URLMatcherConditionFactory factory; 430 URLMatcherCondition m1 = factory.CreateHostSuffixCondition("example.com"); 431 URLMatcherCondition m2 = factory.CreatePathContainsCondition("foo"); 432 433 std::set<URLMatcherCondition> conditions; 434 conditions.insert(m1); 435 conditions.insert(m2); 436 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()); 441 442 std::set<StringPattern::ID> matching_patterns; 443 matching_patterns.insert(m1.string_pattern()->id()); 444 EXPECT_FALSE(condition_set->IsMatch(matching_patterns, url1)); 445 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)); 449 450 // Test scheme filters. 451 scoped_refptr<URLMatcherConditionSet> condition_set2( 452 new URLMatcherConditionSet(1, 453 conditions, 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, 460 conditions, 461 scoped_ptr<URLMatcherSchemeFilter>( 462 new URLMatcherSchemeFilter("http")), 463 scoped_ptr<URLMatcherPortFilter>())); 464 EXPECT_TRUE(condition_set3->IsMatch(matching_patterns, url1)); 465 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)); 476 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)); 487 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)); 494 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)); 504} 505 506 507// 508// URLMatcher 509// 510 511TEST(URLMatcherTest, FullTest) { 512 GURL url1("http://www.example.com/foo?bar=1"); 513 GURL url2("http://foo.example.com/index.html"); 514 515 URLMatcher matcher; 516 URLMatcherConditionFactory* factory = matcher.condition_factory(); 517 518 // First insert. 519 URLMatcherConditionSet::Conditions conditions1; 520 conditions1.insert(factory->CreateHostSuffixCondition("example.com")); 521 conditions1.insert(factory->CreatePathContainsCondition("foo")); 522 523 const int kConditionSetId1 = 1; 524 URLMatcherConditionSet::Vector insert1; 525 insert1.push_back(make_scoped_refptr( 526 new URLMatcherConditionSet(kConditionSetId1, conditions1))); 527 matcher.AddConditionSets(insert1); 528 EXPECT_EQ(1u, matcher.MatchURL(url1).size()); 529 EXPECT_EQ(0u, matcher.MatchURL(url2).size()); 530 531 // Second insert. 532 URLMatcherConditionSet::Conditions conditions2; 533 conditions2.insert(factory->CreateHostSuffixCondition("example.com")); 534 535 const int kConditionSetId2 = 2; 536 URLMatcherConditionSet::Vector insert2; 537 insert2.push_back(make_scoped_refptr( 538 new URLMatcherConditionSet(kConditionSetId2, conditions2))); 539 matcher.AddConditionSets(insert2); 540 EXPECT_EQ(2u, matcher.MatchURL(url1).size()); 541 EXPECT_EQ(1u, matcher.MatchURL(url2).size()); 542 543 // This should be the cached singleton. 544 int patternId1 = factory->CreateHostSuffixCondition( 545 "example.com").string_pattern()->id(); 546 547 // Third insert. 548 URLMatcherConditionSet::Conditions conditions3; 549 conditions3.insert(factory->CreateHostSuffixCondition("example.com")); 550 conditions3.insert(factory->CreateURLMatchesCondition("x.*[0-9]")); 551 552 const int kConditionSetId3 = 3; 553 URLMatcherConditionSet::Vector insert3; 554 insert3.push_back(make_scoped_refptr( 555 new URLMatcherConditionSet(kConditionSetId3, conditions3))); 556 matcher.AddConditionSets(insert3); 557 EXPECT_EQ(3u, matcher.MatchURL(url1).size()); 558 EXPECT_EQ(1u, matcher.MatchURL(url2).size()); 559 560 // Removal of third insert. 561 std::vector<URLMatcherConditionSet::ID> remove3; 562 remove3.push_back(kConditionSetId3); 563 matcher.RemoveConditionSets(remove3); 564 EXPECT_EQ(2u, matcher.MatchURL(url1).size()); 565 EXPECT_EQ(1u, matcher.MatchURL(url2).size()); 566 567 // Removal of second insert. 568 std::vector<URLMatcherConditionSet::ID> remove2; 569 remove2.push_back(kConditionSetId2); 570 matcher.RemoveConditionSets(remove2); 571 EXPECT_EQ(1u, matcher.MatchURL(url1).size()); 572 EXPECT_EQ(0u, matcher.MatchURL(url2).size()); 573 574 // Removal of first insert. 575 std::vector<URLMatcherConditionSet::ID> remove1; 576 remove1.push_back(kConditionSetId1); 577 matcher.RemoveConditionSets(remove1); 578 EXPECT_EQ(0u, matcher.MatchURL(url1).size()); 579 EXPECT_EQ(0u, matcher.MatchURL(url2).size()); 580 581 EXPECT_TRUE(matcher.IsEmpty()); 582 583 // The cached singleton in matcher.condition_factory_ should be destroyed to 584 // free memory. 585 int patternId2 = factory->CreateHostSuffixCondition( 586 "example.com").string_pattern()->id(); 587 // If patternId1 and patternId2 are different that indicates that 588 // matcher.condition_factory_ does not leak memory by holding onto 589 // unused patterns. 590 EXPECT_NE(patternId1, patternId2); 591} 592 593TEST(URLMatcherTest, TestComponentsImplyContains) { 594 // Due to a different implementation of component (prefix, suffix and equals) 595 // and *Contains conditions we need to check that when a pattern matches a 596 // given part of a URL as equal, prefix or suffix, it also matches it in the 597 // "contains" test. 598 GURL url("https://www.google.com:1234/webhp?test=val&a=b"); 599 600 URLMatcher matcher; 601 URLMatcherConditionFactory* factory = matcher.condition_factory(); 602 603 URLMatcherConditionSet::Conditions conditions; 604 605 // First insert all the matching equals => contains pairs. 606 conditions.insert(factory->CreateHostEqualsCondition("www.google.com")); 607 conditions.insert(factory->CreateHostContainsCondition("www.google.com")); 608 609 conditions.insert(factory->CreateHostPrefixCondition("www.")); 610 conditions.insert(factory->CreateHostContainsCondition("www.")); 611 612 conditions.insert(factory->CreateHostSuffixCondition("com")); 613 conditions.insert(factory->CreateHostContainsCondition("com")); 614 615 conditions.insert(factory->CreatePathEqualsCondition("/webhp")); 616 conditions.insert(factory->CreatePathContainsCondition("/webhp")); 617 618 conditions.insert(factory->CreatePathPrefixCondition("/we")); 619 conditions.insert(factory->CreatePathContainsCondition("/we")); 620 621 conditions.insert(factory->CreatePathSuffixCondition("hp")); 622 conditions.insert(factory->CreatePathContainsCondition("hp")); 623 624 conditions.insert(factory->CreateQueryEqualsCondition("test=val&a=b")); 625 conditions.insert(factory->CreateQueryContainsCondition("test=val&a=b")); 626 627 conditions.insert(factory->CreateQueryPrefixCondition("test=v")); 628 conditions.insert(factory->CreateQueryContainsCondition("test=v")); 629 630 conditions.insert(factory->CreateQuerySuffixCondition("l&a=b")); 631 conditions.insert(factory->CreateQueryContainsCondition("l&a=b")); 632 633 // The '?' for equality is just ignored. 634 conditions.insert(factory->CreateQueryEqualsCondition("?test=val&a=b")); 635 // Due to '?' the condition created here is a prefix-testing condition. 636 conditions.insert(factory->CreateQueryContainsCondition("?test=val&a=b")); 637 638 const int kConditionSetId = 1; 639 URLMatcherConditionSet::Vector insert; 640 insert.push_back(make_scoped_refptr( 641 new URLMatcherConditionSet(kConditionSetId, conditions))); 642 matcher.AddConditionSets(insert); 643 EXPECT_EQ(1u, matcher.MatchURL(url).size()); 644} 645 646// Check that matches in everything but the query are found. 647TEST(URLMatcherTest, TestOriginAndPathRegExPositive) { 648 GURL url("https://www.google.com:1234/webhp?test=val&a=b"); 649 650 URLMatcher matcher; 651 URLMatcherConditionFactory* factory = matcher.condition_factory(); 652 653 URLMatcherConditionSet::Conditions conditions; 654 655 conditions.insert(factory->CreateOriginAndPathMatchesCondition("w..hp")); 656 const int kConditionSetId = 1; 657 URLMatcherConditionSet::Vector insert; 658 insert.push_back(make_scoped_refptr( 659 new URLMatcherConditionSet(kConditionSetId, conditions))); 660 matcher.AddConditionSets(insert); 661 EXPECT_EQ(1u, matcher.MatchURL(url).size()); 662} 663 664// Check that matches in the query are ignored. 665TEST(URLMatcherTest, TestOriginAndPathRegExNegative) { 666 GURL url("https://www.google.com:1234/webhp?test=val&a=b"); 667 668 URLMatcher matcher; 669 URLMatcherConditionFactory* factory = matcher.condition_factory(); 670 671 URLMatcherConditionSet::Conditions conditions; 672 673 conditions.insert(factory->CreateOriginAndPathMatchesCondition("val")); 674 const int kConditionSetId = 1; 675 URLMatcherConditionSet::Vector insert; 676 insert.push_back(make_scoped_refptr( 677 new URLMatcherConditionSet(kConditionSetId, conditions))); 678 matcher.AddConditionSets(insert); 679 EXPECT_EQ(0u, matcher.MatchURL(url).size()); 680} 681 682} // namespace url_matcher 683