diff options
author | joaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-13 20:36:53 +0000 |
---|---|---|
committer | joaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-13 20:36:53 +0000 |
commit | 716c016d95025a8f4d42baab6639b9dc90498f2d (patch) | |
tree | 9efb703e070ecbfb1b73bfac9b350a3b81af14f6 /components/url_matcher/url_matcher_unittest.cc | |
parent | 32c90a98f03fa68da4ba3d97a8e56ca70e92a07d (diff) | |
download | chromium_src-716c016d95025a8f4d42baab6639b9dc90498f2d.zip chromium_src-716c016d95025a8f4d42baab6639b9dc90498f2d.tar.gz chromium_src-716c016d95025a8f4d42baab6639b9dc90498f2d.tar.bz2 |
Move extensions/common/matcher into components/url_matcher.
This allows using that code in builds that don't include extensions without
having to introduce layering exceptions. This is meant for inclusion on the
iOS build.
BUG=271392
TBR=brettw@chromium.org
Review URL: https://codereview.chromium.org/113903002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@240736 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'components/url_matcher/url_matcher_unittest.cc')
-rw-r--r-- | components/url_matcher/url_matcher_unittest.cc | 682 |
1 files changed, 682 insertions, 0 deletions
diff --git a/components/url_matcher/url_matcher_unittest.cc b/components/url_matcher/url_matcher_unittest.cc new file mode 100644 index 0000000..748d310 --- /dev/null +++ b/components/url_matcher/url_matcher_unittest.cc @@ -0,0 +1,682 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/url_matcher/url_matcher.h" + +#include "base/strings/string_util.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace url_matcher { + +// +// URLMatcherCondition +// + +TEST(URLMatcherConditionTest, Constructors) { + StringPattern pattern("example.com", 1); + URLMatcherCondition m1(URLMatcherCondition::HOST_SUFFIX, &pattern); + EXPECT_EQ(URLMatcherCondition::HOST_SUFFIX, m1.criterion()); + EXPECT_EQ(&pattern, m1.string_pattern()); + + URLMatcherCondition m2; + m2 = m1; + EXPECT_EQ(URLMatcherCondition::HOST_SUFFIX, m2.criterion()); + EXPECT_EQ(&pattern, m2.string_pattern()); + + URLMatcherCondition m3(m1); + EXPECT_EQ(URLMatcherCondition::HOST_SUFFIX, m3.criterion()); + EXPECT_EQ(&pattern, m3.string_pattern()); +} + +TEST(URLMatcherSchemeFilter, TestMatching) { + URLMatcherSchemeFilter filter1("https"); + std::vector<std::string> filter2_content; + filter2_content.push_back("http"); + filter2_content.push_back("https"); + URLMatcherSchemeFilter filter2(filter2_content); + + GURL matching_url("https://www.foobar.com"); + GURL non_matching_url("http://www.foobar.com"); + EXPECT_TRUE(filter1.IsMatch(matching_url)); + EXPECT_FALSE(filter1.IsMatch(non_matching_url)); + EXPECT_TRUE(filter2.IsMatch(matching_url)); + EXPECT_TRUE(filter2.IsMatch(non_matching_url)); +} + +TEST(URLMatcherPortFilter, TestMatching) { + std::vector<URLMatcherPortFilter::Range> ranges; + ranges.push_back(URLMatcherPortFilter::CreateRange(80, 90)); + ranges.push_back(URLMatcherPortFilter::CreateRange(8080)); + URLMatcherPortFilter filter(ranges); + EXPECT_TRUE(filter.IsMatch(GURL("http://www.example.com"))); + EXPECT_TRUE(filter.IsMatch(GURL("http://www.example.com:80"))); + EXPECT_TRUE(filter.IsMatch(GURL("http://www.example.com:81"))); + EXPECT_TRUE(filter.IsMatch(GURL("http://www.example.com:90"))); + EXPECT_TRUE(filter.IsMatch(GURL("http://www.example.com:8080"))); + EXPECT_FALSE(filter.IsMatch(GURL("http://www.example.com:79"))); + EXPECT_FALSE(filter.IsMatch(GURL("http://www.example.com:91"))); + EXPECT_FALSE(filter.IsMatch(GURL("https://www.example.com"))); +} + +TEST(URLMatcherConditionTest, IsFullURLCondition) { + StringPattern pattern("example.com", 1); + EXPECT_FALSE(URLMatcherCondition(URLMatcherCondition::HOST_SUFFIX, + &pattern).IsFullURLCondition()); + + EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::HOST_CONTAINS, + &pattern).IsFullURLCondition()); + EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::PATH_CONTAINS, + &pattern).IsFullURLCondition()); + EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::QUERY_CONTAINS, + &pattern).IsFullURLCondition()); + + EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::URL_PREFIX, + &pattern).IsFullURLCondition()); + EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::URL_SUFFIX, + &pattern).IsFullURLCondition()); + EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::URL_CONTAINS, + &pattern).IsFullURLCondition()); + EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::URL_EQUALS, + &pattern).IsFullURLCondition()); +} + +TEST(URLMatcherConditionTest, IsMatch) { + GURL url1("http://www.example.com/www.foobar.com/index.html"); + GURL url2("http://www.foobar.com/example.com/index.html"); + + StringPattern pattern("example.com", 1); + URLMatcherCondition m1(URLMatcherCondition::HOST_SUFFIX, &pattern); + + std::set<StringPattern::ID> matching_patterns; + + // matches = {0} --> matcher did not indicate that m1 was a match. + matching_patterns.insert(0); + EXPECT_FALSE(m1.IsMatch(matching_patterns, url1)); + + // matches = {0, 1} --> matcher did indicate that m1 was a match. + matching_patterns.insert(1); + EXPECT_TRUE(m1.IsMatch(matching_patterns, url1)); + + // For m2 we use a HOST_CONTAINS test, which requires a post-validation + // whether the match reported by the SubstringSetMatcher occurs really + // in the correct url component. + URLMatcherCondition m2(URLMatcherCondition::HOST_CONTAINS, &pattern); + EXPECT_TRUE(m2.IsMatch(matching_patterns, url1)); + EXPECT_FALSE(m2.IsMatch(matching_patterns, url2)); +} + +TEST(URLMatcherConditionTest, Comparison) { + StringPattern p1("foobar.com", 1); + StringPattern p2("foobar.com", 2); + // The first component of each test is expected to be < than the second. + URLMatcherCondition test_smaller[][2] = { + {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, &p1), + URLMatcherCondition(URLMatcherCondition::HOST_SUFFIX, &p1)}, + {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, &p1), + URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, &p2)}, + {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, NULL), + URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, &p2)}, + {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, &p1), + URLMatcherCondition(URLMatcherCondition::HOST_SUFFIX, NULL)}, + }; + for (size_t i = 0; i < arraysize(test_smaller); ++i) { + EXPECT_TRUE(test_smaller[i][0] < test_smaller[i][1]) + << "Test " << i << " of test_smaller failed"; + EXPECT_FALSE(test_smaller[i][1] < test_smaller[i][0]) + << "Test " << i << " of test_smaller failed"; + } + URLMatcherCondition test_equal[][2] = { + {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, &p1), + URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, &p1)}, + {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, NULL), + URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, NULL)}, + }; + for (size_t i = 0; i < arraysize(test_equal); ++i) { + EXPECT_FALSE(test_equal[i][0] < test_equal[i][1]) + << "Test " << i << " of test_equal failed"; + EXPECT_FALSE(test_equal[i][1] < test_equal[i][0]) + << "Test " << i << " of test_equal failed"; + } +} + +// +// URLMatcherConditionFactory +// + +namespace { + +bool Matches(const URLMatcherCondition& condition, std::string text) { + return text.find(condition.string_pattern()->pattern()) != + std::string::npos; +} + +} // namespace + +TEST(URLMatcherConditionFactoryTest, GURLCharacterSet) { + // GURL guarantees that neither domain, nor path, nor query may contain + // non ASCII-7 characters. We test this here, because a change to this + // guarantee breaks this implementation horribly. + GURL url("http://www.föö.com/föö?föö#föö"); + EXPECT_TRUE(IsStringASCII(url.host())); + EXPECT_TRUE(IsStringASCII(url.path())); + EXPECT_TRUE(IsStringASCII(url.query())); + EXPECT_FALSE(IsStringASCII(url.ref())); +} + +TEST(URLMatcherConditionFactoryTest, Criteria) { + URLMatcherConditionFactory factory; + EXPECT_EQ(URLMatcherCondition::HOST_PREFIX, + factory.CreateHostPrefixCondition("foo").criterion()); + EXPECT_EQ(URLMatcherCondition::HOST_SUFFIX, + factory.CreateHostSuffixCondition("foo").criterion()); + EXPECT_EQ(URLMatcherCondition::HOST_CONTAINS, + factory.CreateHostContainsCondition("foo").criterion()); + EXPECT_EQ(URLMatcherCondition::HOST_EQUALS, + factory.CreateHostEqualsCondition("foo").criterion()); + EXPECT_EQ(URLMatcherCondition::PATH_PREFIX, + factory.CreatePathPrefixCondition("foo").criterion()); + EXPECT_EQ(URLMatcherCondition::PATH_SUFFIX, + factory.CreatePathSuffixCondition("foo").criterion()); + EXPECT_EQ(URLMatcherCondition::PATH_CONTAINS, + factory.CreatePathContainsCondition("foo").criterion()); + EXPECT_EQ(URLMatcherCondition::PATH_EQUALS, + factory.CreatePathEqualsCondition("foo").criterion()); + EXPECT_EQ(URLMatcherCondition::QUERY_PREFIX, + factory.CreateQueryPrefixCondition("foo").criterion()); + EXPECT_EQ(URLMatcherCondition::QUERY_SUFFIX, + factory.CreateQuerySuffixCondition("foo").criterion()); + EXPECT_EQ(URLMatcherCondition::QUERY_CONTAINS, + factory.CreateQueryContainsCondition("foo").criterion()); + EXPECT_EQ(URLMatcherCondition::QUERY_EQUALS, + factory.CreateQueryEqualsCondition("foo").criterion()); + EXPECT_EQ(URLMatcherCondition::HOST_SUFFIX_PATH_PREFIX, + factory.CreateHostSuffixPathPrefixCondition("foo", + "bar").criterion()); + EXPECT_EQ(URLMatcherCondition::HOST_EQUALS_PATH_PREFIX, + factory.CreateHostEqualsPathPrefixCondition("foo", + "bar").criterion()); + EXPECT_EQ(URLMatcherCondition::URL_PREFIX, + factory.CreateURLPrefixCondition("foo").criterion()); + EXPECT_EQ(URLMatcherCondition::URL_SUFFIX, + factory.CreateURLSuffixCondition("foo").criterion()); + EXPECT_EQ(URLMatcherCondition::URL_CONTAINS, + factory.CreateURLContainsCondition("foo").criterion()); + EXPECT_EQ(URLMatcherCondition::URL_EQUALS, + factory.CreateURLEqualsCondition("foo").criterion()); + EXPECT_EQ(URLMatcherCondition::URL_MATCHES, + factory.CreateURLMatchesCondition("foo").criterion()); +} + +TEST(URLMatcherConditionFactoryTest, TestSingletonProperty) { + URLMatcherConditionFactory factory; + URLMatcherCondition c1 = factory.CreateHostEqualsCondition("www.google.com"); + URLMatcherCondition c2 = factory.CreateHostEqualsCondition("www.google.com"); + EXPECT_EQ(c1.criterion(), c2.criterion()); + EXPECT_EQ(c1.string_pattern(), c2.string_pattern()); + URLMatcherCondition c3 = factory.CreateHostEqualsCondition("www.google.de"); + EXPECT_EQ(c2.criterion(), c3.criterion()); + EXPECT_NE(c2.string_pattern(), c3.string_pattern()); + EXPECT_NE(c2.string_pattern()->id(), c3.string_pattern()->id()); + EXPECT_NE(c2.string_pattern()->pattern(), + c3.string_pattern()->pattern()); + URLMatcherCondition c4 = factory.CreateURLMatchesCondition("www.google.com"); + URLMatcherCondition c5 = factory.CreateURLContainsCondition("www.google.com"); + // Regex patterns and substring patterns do not share IDs. + EXPECT_EQ(c5.string_pattern()->pattern(), c4.string_pattern()->pattern()); + EXPECT_NE(c5.string_pattern(), c4.string_pattern()); + EXPECT_NE(c5.string_pattern()->id(), c4.string_pattern()->id()); + + // Check that all StringPattern singletons are freed if we call + // ForgetUnusedPatterns. + StringPattern::ID old_id_1 = c1.string_pattern()->id(); + StringPattern::ID old_id_4 = c4.string_pattern()->id(); + factory.ForgetUnusedPatterns(std::set<StringPattern::ID>()); + EXPECT_TRUE(factory.IsEmpty()); + URLMatcherCondition c6 = factory.CreateHostEqualsCondition("www.google.com"); + EXPECT_NE(old_id_1, c6.string_pattern()->id()); + URLMatcherCondition c7 = factory.CreateURLMatchesCondition("www.google.com"); + EXPECT_NE(old_id_4, c7.string_pattern()->id()); +} + +TEST(URLMatcherConditionFactoryTest, TestComponentSearches) { + GURL gurl("https://www.google.com:1234/webhp?sourceid=chrome-instant&ie=UTF-8" + "&ion=1#hl=en&output=search&sclient=psy-ab&q=chrome%20is%20awesome"); + URLMatcherConditionFactory factory; + std::string url = factory.CanonicalizeURLForComponentSearches(gurl); + + // Test host component. + EXPECT_TRUE(Matches(factory.CreateHostPrefixCondition(std::string()), url)); + EXPECT_TRUE(Matches(factory.CreateHostPrefixCondition("www.goog"), url)); + EXPECT_TRUE( + Matches(factory.CreateHostPrefixCondition("www.google.com"), url)); + EXPECT_TRUE( + Matches(factory.CreateHostPrefixCondition(".www.google.com"), url)); + EXPECT_FALSE(Matches(factory.CreateHostPrefixCondition("google.com"), url)); + EXPECT_FALSE( + Matches(factory.CreateHostPrefixCondition("www.google.com/"), url)); + EXPECT_FALSE(Matches(factory.CreateHostPrefixCondition("webhp"), url)); + + EXPECT_TRUE(Matches(factory.CreateHostSuffixCondition(std::string()), url)); + EXPECT_TRUE(Matches(factory.CreateHostSuffixCondition("com"), url)); + EXPECT_TRUE(Matches(factory.CreateHostSuffixCondition(".com"), url)); + EXPECT_TRUE( + Matches(factory.CreateHostSuffixCondition("www.google.com"), url)); + EXPECT_TRUE( + Matches(factory.CreateHostSuffixCondition(".www.google.com"), url)); + EXPECT_FALSE(Matches(factory.CreateHostSuffixCondition("www"), url)); + EXPECT_FALSE( + Matches(factory.CreateHostSuffixCondition("www.google.com/"), url)); + EXPECT_FALSE(Matches(factory.CreateHostSuffixCondition("webhp"), url)); + + EXPECT_FALSE(Matches(factory.CreateHostEqualsCondition(std::string()), url)); + EXPECT_FALSE(Matches(factory.CreateHostEqualsCondition("www"), url)); + EXPECT_TRUE( + Matches(factory.CreateHostEqualsCondition("www.google.com"), url)); + EXPECT_FALSE( + Matches(factory.CreateHostEqualsCondition("www.google.com/"), url)); + + + // Test path component. + EXPECT_TRUE(Matches(factory.CreatePathPrefixCondition(std::string()), url)); + EXPECT_TRUE(Matches(factory.CreatePathPrefixCondition("/web"), url)); + EXPECT_TRUE(Matches(factory.CreatePathPrefixCondition("/webhp"), url)); + EXPECT_FALSE(Matches(factory.CreatePathPrefixCondition("webhp"), url)); + EXPECT_FALSE(Matches(factory.CreatePathPrefixCondition("/webhp?"), url)); + EXPECT_FALSE(Matches(factory.CreatePathPrefixCondition("?sourceid"), url)); + + EXPECT_TRUE(Matches(factory.CreatePathSuffixCondition(std::string()), url)); + EXPECT_TRUE(Matches(factory.CreatePathSuffixCondition("webhp"), url)); + EXPECT_TRUE(Matches(factory.CreatePathSuffixCondition("/webhp"), url)); + EXPECT_FALSE(Matches(factory.CreatePathSuffixCondition("/web"), url)); + EXPECT_FALSE(Matches(factory.CreatePathSuffixCondition("/webhp?"), url)); + + EXPECT_TRUE(Matches(factory.CreatePathEqualsCondition("/webhp"), url)); + EXPECT_FALSE(Matches(factory.CreatePathEqualsCondition("webhp"), url)); + EXPECT_FALSE(Matches(factory.CreatePathEqualsCondition("/webhp?"), url)); + EXPECT_FALSE( + Matches(factory.CreatePathEqualsCondition("www.google.com"), url)); + + + // Test query component. + EXPECT_TRUE(Matches(factory.CreateQueryPrefixCondition(std::string()), url)); + EXPECT_TRUE(Matches(factory.CreateQueryPrefixCondition("sourceid"), url)); + // The '?' at the beginning is just ignored. + EXPECT_TRUE(Matches(factory.CreateQueryPrefixCondition("?sourceid"), url)); + + EXPECT_TRUE(Matches(factory.CreateQuerySuffixCondition(std::string()), url)); + EXPECT_TRUE(Matches(factory.CreateQuerySuffixCondition("ion=1"), url)); + EXPECT_FALSE(Matches(factory.CreateQuerySuffixCondition("www"), url)); + // "Suffix" condition + pattern starting with '?' = "equals" condition. + EXPECT_FALSE(Matches(factory.CreateQuerySuffixCondition( + "?sourceid=chrome-instant&ie=UTF-8&ion="), url)); + EXPECT_TRUE(Matches(factory.CreateQuerySuffixCondition( + "?sourceid=chrome-instant&ie=UTF-8&ion=1"), url)); + + EXPECT_FALSE(Matches(factory.CreateQueryEqualsCondition( + "?sourceid=chrome-instant&ie=UTF-8&ion="), url)); + EXPECT_FALSE(Matches(factory.CreateQueryEqualsCondition( + "sourceid=chrome-instant&ie=UTF-8&ion="), url)); + EXPECT_TRUE(Matches(factory.CreateQueryEqualsCondition( + "sourceid=chrome-instant&ie=UTF-8&ion=1"), url)); + // The '?' at the beginning is just ignored. + EXPECT_TRUE(Matches(factory.CreateQueryEqualsCondition( + "?sourceid=chrome-instant&ie=UTF-8&ion=1"), url)); + EXPECT_FALSE( + Matches(factory.CreateQueryEqualsCondition("www.google.com"), url)); + + + // Test adjacent components + EXPECT_TRUE(Matches(factory.CreateHostSuffixPathPrefixCondition( + "google.com", "/webhp"), url)); + EXPECT_TRUE(Matches( + factory.CreateHostSuffixPathPrefixCondition(std::string(), "/webhp"), + url)); + EXPECT_TRUE(Matches( + factory.CreateHostSuffixPathPrefixCondition("google.com", std::string()), + url)); + EXPECT_FALSE(Matches( + factory.CreateHostSuffixPathPrefixCondition("www", std::string()), url)); + + EXPECT_TRUE(Matches(factory.CreateHostEqualsPathPrefixCondition( + "www.google.com", "/webhp"), url)); + EXPECT_FALSE(Matches( + factory.CreateHostEqualsPathPrefixCondition(std::string(), "/webhp"), + url)); + EXPECT_TRUE(Matches(factory.CreateHostEqualsPathPrefixCondition( + "www.google.com", std::string()), + url)); + EXPECT_FALSE(Matches( + factory.CreateHostEqualsPathPrefixCondition("google.com", std::string()), + url)); +} + +TEST(URLMatcherConditionFactoryTest, TestFullSearches) { + // The Port 443 is stripped because it is the default port for https. + GURL gurl("https://www.google.com:443/webhp?sourceid=chrome-instant&ie=UTF-8" + "&ion=1#hl=en&output=search&sclient=psy-ab&q=chrome%20is%20awesome"); + URLMatcherConditionFactory factory; + std::string url = factory.CanonicalizeURLForFullSearches(gurl); + + EXPECT_TRUE(Matches(factory.CreateURLPrefixCondition(std::string()), url)); + EXPECT_TRUE( + Matches(factory.CreateURLPrefixCondition("https://www.goog"), url)); + EXPECT_TRUE(Matches(factory.CreateURLPrefixCondition( + "https://www.google.com"), url)); + EXPECT_TRUE(Matches(factory.CreateURLPrefixCondition( + "https://www.google.com/webhp?"), url)); + EXPECT_FALSE(Matches(factory.CreateURLPrefixCondition( + "http://www.google.com"), url)); + EXPECT_FALSE(Matches(factory.CreateURLPrefixCondition("webhp"), url)); + + EXPECT_TRUE(Matches(factory.CreateURLSuffixCondition(std::string()), url)); + EXPECT_TRUE(Matches(factory.CreateURLSuffixCondition("ion=1"), url)); + EXPECT_FALSE(Matches(factory.CreateURLSuffixCondition("www"), url)); + + EXPECT_TRUE(Matches(factory.CreateURLContainsCondition(std::string()), url)); + EXPECT_TRUE(Matches(factory.CreateURLContainsCondition("www.goog"), url)); + EXPECT_TRUE(Matches(factory.CreateURLContainsCondition("webhp"), url)); + EXPECT_TRUE(Matches(factory.CreateURLContainsCondition("?"), url)); + EXPECT_TRUE(Matches(factory.CreateURLContainsCondition("sourceid"), url)); + EXPECT_TRUE(Matches(factory.CreateURLContainsCondition("ion=1"), url)); + EXPECT_FALSE(Matches(factory.CreateURLContainsCondition(".www.goog"), url)); + EXPECT_FALSE(Matches(factory.CreateURLContainsCondition("foobar"), url)); + EXPECT_FALSE(Matches(factory.CreateURLContainsCondition("search"), url)); + EXPECT_FALSE(Matches(factory.CreateURLContainsCondition(":443"), url)); + + EXPECT_TRUE(Matches(factory.CreateURLEqualsCondition( + "https://www.google.com/webhp?sourceid=chrome-instant&ie=UTF-8&ion=1"), + url)); + EXPECT_FALSE( + Matches(factory.CreateURLEqualsCondition("https://www.google.com"), url)); + + // Same as above but this time with a non-standard port. + gurl = GURL("https://www.google.com:1234/webhp?sourceid=chrome-instant&" + "ie=UTF-8&ion=1#hl=en&output=search&sclient=psy-ab&q=chrome%20is%20" + "awesome"); + url = factory.CanonicalizeURLForFullSearches(gurl); + EXPECT_TRUE(Matches(factory.CreateURLPrefixCondition( + "https://www.google.com:1234/webhp?"), url)); + EXPECT_TRUE(Matches(factory.CreateURLContainsCondition(":1234"), url)); +} + +// +// URLMatcherConditionSet +// + +TEST(URLMatcherConditionSetTest, Constructor) { + URLMatcherConditionFactory factory; + URLMatcherCondition m1 = factory.CreateHostSuffixCondition("example.com"); + URLMatcherCondition m2 = factory.CreatePathContainsCondition("foo"); + + std::set<URLMatcherCondition> conditions; + conditions.insert(m1); + conditions.insert(m2); + + scoped_refptr<URLMatcherConditionSet> condition_set( + new URLMatcherConditionSet(1, conditions)); + EXPECT_EQ(1, condition_set->id()); + EXPECT_EQ(2u, condition_set->conditions().size()); +} + +TEST(URLMatcherConditionSetTest, Matching) { + GURL url1("http://www.example.com/foo?bar=1"); + GURL url2("http://foo.example.com/index.html"); + GURL url3("http://www.example.com:80/foo?bar=1"); + GURL url4("http://www.example.com:8080/foo?bar=1"); + + URLMatcherConditionFactory factory; + URLMatcherCondition m1 = factory.CreateHostSuffixCondition("example.com"); + URLMatcherCondition m2 = factory.CreatePathContainsCondition("foo"); + + std::set<URLMatcherCondition> conditions; + conditions.insert(m1); + conditions.insert(m2); + + scoped_refptr<URLMatcherConditionSet> condition_set( + new URLMatcherConditionSet(1, conditions)); + EXPECT_EQ(1, condition_set->id()); + EXPECT_EQ(2u, condition_set->conditions().size()); + + std::set<StringPattern::ID> matching_patterns; + matching_patterns.insert(m1.string_pattern()->id()); + EXPECT_FALSE(condition_set->IsMatch(matching_patterns, url1)); + + matching_patterns.insert(m2.string_pattern()->id()); + EXPECT_TRUE(condition_set->IsMatch(matching_patterns, url1)); + EXPECT_FALSE(condition_set->IsMatch(matching_patterns, url2)); + + // Test scheme filters. + scoped_refptr<URLMatcherConditionSet> condition_set2( + new URLMatcherConditionSet(1, + conditions, + scoped_ptr<URLMatcherSchemeFilter>( + new URLMatcherSchemeFilter("https")), + scoped_ptr<URLMatcherPortFilter>())); + EXPECT_FALSE(condition_set2->IsMatch(matching_patterns, url1)); + scoped_refptr<URLMatcherConditionSet> condition_set3( + new URLMatcherConditionSet(1, + conditions, + scoped_ptr<URLMatcherSchemeFilter>( + new URLMatcherSchemeFilter("http")), + scoped_ptr<URLMatcherPortFilter>())); + EXPECT_TRUE(condition_set3->IsMatch(matching_patterns, url1)); + + // Test port filters. + std::vector<URLMatcherPortFilter::Range> ranges; + ranges.push_back(URLMatcherPortFilter::CreateRange(80)); + scoped_ptr<URLMatcherPortFilter> filter(new URLMatcherPortFilter(ranges)); + scoped_refptr<URLMatcherConditionSet> condition_set4( + new URLMatcherConditionSet( + 1, conditions, scoped_ptr<URLMatcherSchemeFilter>(), filter.Pass())); + EXPECT_TRUE(condition_set4->IsMatch(matching_patterns, url1)); + EXPECT_TRUE(condition_set4->IsMatch(matching_patterns, url3)); + EXPECT_FALSE(condition_set4->IsMatch(matching_patterns, url4)); + + // Test regex patterns. + matching_patterns.clear(); + URLMatcherCondition r1 = factory.CreateURLMatchesCondition("/fo?oo"); + std::set<URLMatcherCondition> regex_conditions; + regex_conditions.insert(r1); + scoped_refptr<URLMatcherConditionSet> condition_set5( + new URLMatcherConditionSet(1, regex_conditions)); + EXPECT_FALSE(condition_set5->IsMatch(matching_patterns, url1)); + matching_patterns.insert(r1.string_pattern()->id()); + EXPECT_TRUE(condition_set5->IsMatch(matching_patterns, url1)); + + regex_conditions.insert(m1); + scoped_refptr<URLMatcherConditionSet> condition_set6( + new URLMatcherConditionSet(1, regex_conditions)); + EXPECT_FALSE(condition_set6->IsMatch(matching_patterns, url1)); + matching_patterns.insert(m1.string_pattern()->id()); + EXPECT_TRUE(condition_set6->IsMatch(matching_patterns, url1)); + + matching_patterns.clear(); + regex_conditions.clear(); + URLMatcherCondition r2 = factory.CreateOriginAndPathMatchesCondition("b[a]r"); + regex_conditions.insert(r2); + scoped_refptr<URLMatcherConditionSet> condition_set7( + new URLMatcherConditionSet(1, regex_conditions)); + EXPECT_FALSE(condition_set7->IsMatch(matching_patterns, url1)); + matching_patterns.insert(r2.string_pattern()->id()); + EXPECT_TRUE(condition_set7->IsMatch(matching_patterns, url1)); +} + + +// +// URLMatcher +// + +TEST(URLMatcherTest, FullTest) { + GURL url1("http://www.example.com/foo?bar=1"); + GURL url2("http://foo.example.com/index.html"); + + URLMatcher matcher; + URLMatcherConditionFactory* factory = matcher.condition_factory(); + + // First insert. + URLMatcherConditionSet::Conditions conditions1; + conditions1.insert(factory->CreateHostSuffixCondition("example.com")); + conditions1.insert(factory->CreatePathContainsCondition("foo")); + + const int kConditionSetId1 = 1; + URLMatcherConditionSet::Vector insert1; + insert1.push_back(make_scoped_refptr( + new URLMatcherConditionSet(kConditionSetId1, conditions1))); + matcher.AddConditionSets(insert1); + EXPECT_EQ(1u, matcher.MatchURL(url1).size()); + EXPECT_EQ(0u, matcher.MatchURL(url2).size()); + + // Second insert. + URLMatcherConditionSet::Conditions conditions2; + conditions2.insert(factory->CreateHostSuffixCondition("example.com")); + + const int kConditionSetId2 = 2; + URLMatcherConditionSet::Vector insert2; + insert2.push_back(make_scoped_refptr( + new URLMatcherConditionSet(kConditionSetId2, conditions2))); + matcher.AddConditionSets(insert2); + EXPECT_EQ(2u, matcher.MatchURL(url1).size()); + EXPECT_EQ(1u, matcher.MatchURL(url2).size()); + + // This should be the cached singleton. + int patternId1 = factory->CreateHostSuffixCondition( + "example.com").string_pattern()->id(); + + // Third insert. + URLMatcherConditionSet::Conditions conditions3; + conditions3.insert(factory->CreateHostSuffixCondition("example.com")); + conditions3.insert(factory->CreateURLMatchesCondition("x.*[0-9]")); + + const int kConditionSetId3 = 3; + URLMatcherConditionSet::Vector insert3; + insert3.push_back(make_scoped_refptr( + new URLMatcherConditionSet(kConditionSetId3, conditions3))); + matcher.AddConditionSets(insert3); + EXPECT_EQ(3u, matcher.MatchURL(url1).size()); + EXPECT_EQ(1u, matcher.MatchURL(url2).size()); + + // Removal of third insert. + std::vector<URLMatcherConditionSet::ID> remove3; + remove3.push_back(kConditionSetId3); + matcher.RemoveConditionSets(remove3); + EXPECT_EQ(2u, matcher.MatchURL(url1).size()); + EXPECT_EQ(1u, matcher.MatchURL(url2).size()); + + // Removal of second insert. + std::vector<URLMatcherConditionSet::ID> remove2; + remove2.push_back(kConditionSetId2); + matcher.RemoveConditionSets(remove2); + EXPECT_EQ(1u, matcher.MatchURL(url1).size()); + EXPECT_EQ(0u, matcher.MatchURL(url2).size()); + + // Removal of first insert. + std::vector<URLMatcherConditionSet::ID> remove1; + remove1.push_back(kConditionSetId1); + matcher.RemoveConditionSets(remove1); + EXPECT_EQ(0u, matcher.MatchURL(url1).size()); + EXPECT_EQ(0u, matcher.MatchURL(url2).size()); + + EXPECT_TRUE(matcher.IsEmpty()); + + // The cached singleton in matcher.condition_factory_ should be destroyed to + // free memory. + int patternId2 = factory->CreateHostSuffixCondition( + "example.com").string_pattern()->id(); + // If patternId1 and patternId2 are different that indicates that + // matcher.condition_factory_ does not leak memory by holding onto + // unused patterns. + EXPECT_NE(patternId1, patternId2); +} + +TEST(URLMatcherTest, TestComponentsImplyContains) { + // Due to a different implementation of component (prefix, suffix and equals) + // and *Contains conditions we need to check that when a pattern matches a + // given part of a URL as equal, prefix or suffix, it also matches it in the + // "contains" test. + GURL url("https://www.google.com:1234/webhp?test=val&a=b"); + + URLMatcher matcher; + URLMatcherConditionFactory* factory = matcher.condition_factory(); + + URLMatcherConditionSet::Conditions conditions; + + // First insert all the matching equals => contains pairs. + conditions.insert(factory->CreateHostEqualsCondition("www.google.com")); + conditions.insert(factory->CreateHostContainsCondition("www.google.com")); + + conditions.insert(factory->CreateHostPrefixCondition("www.")); + conditions.insert(factory->CreateHostContainsCondition("www.")); + + conditions.insert(factory->CreateHostSuffixCondition("com")); + conditions.insert(factory->CreateHostContainsCondition("com")); + + conditions.insert(factory->CreatePathEqualsCondition("/webhp")); + conditions.insert(factory->CreatePathContainsCondition("/webhp")); + + conditions.insert(factory->CreatePathPrefixCondition("/we")); + conditions.insert(factory->CreatePathContainsCondition("/we")); + + conditions.insert(factory->CreatePathSuffixCondition("hp")); + conditions.insert(factory->CreatePathContainsCondition("hp")); + + conditions.insert(factory->CreateQueryEqualsCondition("test=val&a=b")); + conditions.insert(factory->CreateQueryContainsCondition("test=val&a=b")); + + conditions.insert(factory->CreateQueryPrefixCondition("test=v")); + conditions.insert(factory->CreateQueryContainsCondition("test=v")); + + conditions.insert(factory->CreateQuerySuffixCondition("l&a=b")); + conditions.insert(factory->CreateQueryContainsCondition("l&a=b")); + + // The '?' for equality is just ignored. + conditions.insert(factory->CreateQueryEqualsCondition("?test=val&a=b")); + // Due to '?' the condition created here is a prefix-testing condition. + conditions.insert(factory->CreateQueryContainsCondition("?test=val&a=b")); + + const int kConditionSetId = 1; + URLMatcherConditionSet::Vector insert; + insert.push_back(make_scoped_refptr( + new URLMatcherConditionSet(kConditionSetId, conditions))); + matcher.AddConditionSets(insert); + EXPECT_EQ(1u, matcher.MatchURL(url).size()); +} + +// Check that matches in everything but the query are found. +TEST(URLMatcherTest, TestOriginAndPathRegExPositive) { + GURL url("https://www.google.com:1234/webhp?test=val&a=b"); + + URLMatcher matcher; + URLMatcherConditionFactory* factory = matcher.condition_factory(); + + URLMatcherConditionSet::Conditions conditions; + + conditions.insert(factory->CreateOriginAndPathMatchesCondition("w..hp")); + const int kConditionSetId = 1; + URLMatcherConditionSet::Vector insert; + insert.push_back(make_scoped_refptr( + new URLMatcherConditionSet(kConditionSetId, conditions))); + matcher.AddConditionSets(insert); + EXPECT_EQ(1u, matcher.MatchURL(url).size()); +} + +// Check that matches in the query are ignored. +TEST(URLMatcherTest, TestOriginAndPathRegExNegative) { + GURL url("https://www.google.com:1234/webhp?test=val&a=b"); + + URLMatcher matcher; + URLMatcherConditionFactory* factory = matcher.condition_factory(); + + URLMatcherConditionSet::Conditions conditions; + + conditions.insert(factory->CreateOriginAndPathMatchesCondition("val")); + const int kConditionSetId = 1; + URLMatcherConditionSet::Vector insert; + insert.push_back(make_scoped_refptr( + new URLMatcherConditionSet(kConditionSetId, conditions))); + matcher.AddConditionSets(insert); + EXPECT_EQ(0u, matcher.MatchURL(url).size()); +} + +} // namespace url_matcher |