Home | History | Annotate | Download | only in url_matcher
      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 
     11 namespace url_matcher {
     12 
     13 //
     14 // URLMatcherCondition
     15 //
     16 
     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());
     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 
     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);
     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 
     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")));
     61 }
     62 
     63 TEST(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 
     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");
     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 
    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)},
    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 
    148 namespace {
    149 
    150 bool Matches(const URLMatcherCondition& condition, std::string text) {
    151   return text.find(condition.string_pattern()->pattern()) !=
    152       std::string::npos;
    153 }
    154 
    155 }  // namespace
    156 
    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(IsStringASCII(url.host()));
    163   EXPECT_TRUE(IsStringASCII(url.path()));
    164   EXPECT_TRUE(IsStringASCII(url.query()));
    165   EXPECT_FALSE(IsStringASCII(url.ref()));
    166 }
    167 
    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",
    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 
    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());
    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 
    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);
    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 
    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);
    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 
    408 TEST(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 
    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");
    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 
    511 TEST(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 
    593 TEST(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.
    647 TEST(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.
    665 TEST(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