| Index: chrome/common/extensions/matcher/url_matcher_factory_unittest.cc
|
| diff --git a/chrome/common/extensions/matcher/url_matcher_factory_unittest.cc b/chrome/common/extensions/matcher/url_matcher_factory_unittest.cc
|
| index aa2a76ca0ed2a920c2fa8cb11270d3868e4d5345..71f6ced121e82a8e2d73851bef9df39daec59346 100644
|
| --- a/chrome/common/extensions/matcher/url_matcher_factory_unittest.cc
|
| +++ b/chrome/common/extensions/matcher/url_matcher_factory_unittest.cc
|
| @@ -4,6 +4,8 @@
|
|
|
| #include "chrome/common/extensions/matcher/url_matcher_factory.h"
|
|
|
| +#include "base/format_macros.h"
|
| +#include "base/stringprintf.h"
|
| #include "base/values.h"
|
| #include "chrome/common/extensions/matcher/url_matcher_constants.h"
|
| #include "googleurl/src/gurl.h"
|
| @@ -99,4 +101,151 @@ TEST(URLMatcherFactoryTest, CreateFromURLFilterDictionary) {
|
| EXPECT_EQ(0u, matcher.MatchURL(GURL("http://mail.example.com:81")).size());
|
| }
|
|
|
| +// This class wraps a case sensitivity test for a single UrlFilter condition.
|
| +class UrlConditionCaseTest {
|
| + public:
|
| + // The condition is identified by the key |condition_key|. If that key is
|
| + // associated with string values, then |use_list_of_strings| should be false,
|
| + // if the key is associated with list-of-string values, then
|
| + // |use_list_of_strings| should be true. In |url| is the URL to test against.
|
| + UrlConditionCaseTest(const char* condition_key,
|
| + const bool use_list_of_strings,
|
| + const std::string& expected_value,
|
| + const std::string& incorrect_case_value,
|
| + const bool case_sensitive,
|
| + const GURL& url)
|
| + : condition_key_(condition_key),
|
| + use_list_of_strings_(use_list_of_strings),
|
| + expected_value_(expected_value),
|
| + incorrect_case_value_(incorrect_case_value),
|
| + case_sensitive_(case_sensitive),
|
| + url_(url) {}
|
| +
|
| + ~UrlConditionCaseTest() {}
|
| +
|
| + // Match the condition against |url_|. Checks via EXPECT_* macros that
|
| + // |expected_value_| matches always, and that |incorrect_case_value_| matches
|
| + // iff |case_sensitive_| is false.
|
| + void Test() const;
|
| +
|
| + private:
|
| + // Check, via EXPECT_* macros, that the the condition |condition_key_|=|value|
|
| + // fails against |url_| iff |should_fail| is true. This check is expensive,
|
| + // its value should be cached if needed multiple times.
|
| + void CheckCondition(const std::string& value, bool should_fail) const;
|
| +
|
| + const char* condition_key_;
|
| + const bool use_list_of_strings_;
|
| + const std::string& expected_value_;
|
| + const std::string& incorrect_case_value_;
|
| + const bool case_sensitive_;
|
| + const GURL& url_;
|
| +
|
| + // Allow implicit copy and assign, because a public copy constructor is
|
| + // needed, but never used (!), for the definition of arrays of this class.
|
| +};
|
| +
|
| +void UrlConditionCaseTest::Test() const {
|
| + CheckCondition(expected_value_, false);
|
| + CheckCondition(incorrect_case_value_, case_sensitive_);
|
| +}
|
| +
|
| +void UrlConditionCaseTest::CheckCondition(const std::string& value,
|
| + bool should_fail) const {
|
| + DictionaryValue condition;
|
| + if (use_list_of_strings_) {
|
| + ListValue* list = new ListValue();
|
| + list->Append(Value::CreateStringValue(value));
|
| + condition.SetWithoutPathExpansion(condition_key_, list);
|
| + } else {
|
| + condition.SetStringWithoutPathExpansion(condition_key_, value);
|
| + }
|
| +
|
| + URLMatcher matcher;
|
| + std::string error;
|
| + scoped_refptr<URLMatcherConditionSet> result;
|
| +
|
| + result = URLMatcherFactory::CreateFromURLFilterDictionary(
|
| + matcher.condition_factory(), &condition, 1, &error);
|
| + EXPECT_EQ("", error);
|
| + ASSERT_TRUE(result.get());
|
| +
|
| + URLMatcherConditionSet::Vector conditions;
|
| + conditions.push_back(result);
|
| + matcher.AddConditionSets(conditions);
|
| + EXPECT_EQ((should_fail ? 0u : 1u), matcher.MatchURL(url_).size())
|
| + << "while matching condition " << condition_key_ << " with value "
|
| + << value << " against url " << url_;
|
| +}
|
| +
|
| +// This tests that the UrlFilter handles case sensitivity on various parts of
|
| +// URLs correctly.
|
| +TEST(URLMatcherFactoryTest, CaseSensitivity) {
|
| + const std::string kScheme("https");
|
| + const std::string kSchemeUpper("HTTPS");
|
| + const std::string kHost("www.example.com");
|
| + const std::string kHostUpper("WWW.EXAMPLE.COM");
|
| + const std::string kPath("/path");
|
| + const std::string kPathUpper("/PATH");
|
| + const std::string kQuery("?option=value&A=B");
|
| + const std::string kQueryUpper("?OPTION=VALUE&A=B");
|
| + const std::string kUrl(kScheme + "://" + kHost + ":1234" + kPath + kQuery);
|
| + const std::string kUrlUpper(
|
| + kSchemeUpper + "://" + kHostUpper + ":1234" + kPathUpper + kQueryUpper);
|
| + const GURL url(kUrl);
|
| + // Note: according to RFC 3986, and RFC 1034, schema and host, respectively
|
| + // should be case insensitive. See crbug.com/160702, comments 6 and 7, for why
|
| + // we still require them to be case sensitive in UrlFilter.
|
| + const bool kIsSchemeCaseSensitive = true;
|
| + const bool kIsHostCaseSensitive = true;
|
| + const bool kIsPathCaseSensitive = true;
|
| + const bool kIsQueryCaseSensitive = true;
|
| + const bool kIsUrlCaseSensitive = kIsSchemeCaseSensitive ||
|
| + kIsHostCaseSensitive || kIsPathCaseSensitive || kIsQueryCaseSensitive;
|
| +
|
| + const UrlConditionCaseTest case_tests[] = {
|
| + UrlConditionCaseTest(keys::kSchemesKey, true, kScheme, kSchemeUpper,
|
| + kIsSchemeCaseSensitive, url),
|
| + UrlConditionCaseTest(keys::kHostContainsKey, false, kHost, kHostUpper,
|
| + kIsHostCaseSensitive, url),
|
| + UrlConditionCaseTest(keys::kHostEqualsKey, false, kHost, kHostUpper,
|
| + kIsHostCaseSensitive, url),
|
| + UrlConditionCaseTest(keys::kHostPrefixKey, false, kHost, kHostUpper,
|
| + kIsHostCaseSensitive, url),
|
| + UrlConditionCaseTest(keys::kHostSuffixKey, false, kHost, kHostUpper,
|
| + kIsHostCaseSensitive, url),
|
| + UrlConditionCaseTest(keys::kPathContainsKey, false, kPath, kPathUpper,
|
| + kIsPathCaseSensitive, url),
|
| + UrlConditionCaseTest(keys::kPathEqualsKey, false, kPath, kPathUpper,
|
| + kIsPathCaseSensitive, url),
|
| + UrlConditionCaseTest(keys::kPathPrefixKey, false, kPath, kPathUpper,
|
| + kIsPathCaseSensitive, url),
|
| + UrlConditionCaseTest(keys::kPathSuffixKey, false, kPath, kPathUpper,
|
| + kIsPathCaseSensitive, url),
|
| + UrlConditionCaseTest(keys::kQueryContainsKey, false, kQuery, kQueryUpper,
|
| + kIsQueryCaseSensitive, url),
|
| + UrlConditionCaseTest(keys::kQueryEqualsKey, false, kQuery, kQueryUpper,
|
| + kIsQueryCaseSensitive, url),
|
| + UrlConditionCaseTest(keys::kQueryPrefixKey, false, kQuery, kQueryUpper,
|
| + kIsQueryCaseSensitive, url),
|
| + UrlConditionCaseTest(keys::kQuerySuffixKey, false, kQuery, kQueryUpper,
|
| + kIsQueryCaseSensitive, url),
|
| + // Excluding kURLMatchesKey because case sensitivity can be specified in the
|
| + // RE2 expression.
|
| + UrlConditionCaseTest(keys::kURLContainsKey, false, kUrl, kUrlUpper,
|
| + kIsUrlCaseSensitive, url),
|
| + UrlConditionCaseTest(keys::kURLEqualsKey, false, kUrl, kUrlUpper,
|
| + kIsUrlCaseSensitive, url),
|
| + UrlConditionCaseTest(keys::kURLPrefixKey, false, kUrl, kUrlUpper,
|
| + kIsUrlCaseSensitive, url),
|
| + UrlConditionCaseTest(keys::kURLSuffixKey, false, kUrl, kUrlUpper,
|
| + kIsUrlCaseSensitive, url),
|
| + };
|
| +
|
| + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(case_tests); ++i) {
|
| + SCOPED_TRACE(base::StringPrintf("Iteration: %" PRIuS, i));
|
| + case_tests[i].Test();
|
| + }
|
| +}
|
| +
|
| } // namespace extensions
|
|
|