Home | History | Annotate | Download | only in common
      1 // Copyright (c) 2012 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 "extensions/common/url_pattern_set.h"
      6 
      7 #include <sstream>
      8 
      9 #include "base/values.h"
     10 #include "testing/gtest/include/gtest/gtest.h"
     11 #include "url/gurl.h"
     12 
     13 namespace extensions {
     14 
     15 namespace {
     16 
     17 void AddPattern(URLPatternSet* set, const std::string& pattern) {
     18   int schemes = URLPattern::SCHEME_ALL;
     19   set->AddPattern(URLPattern(schemes, pattern));
     20 }
     21 
     22 URLPatternSet Patterns(const std::string& pattern) {
     23   URLPatternSet set;
     24   AddPattern(&set, pattern);
     25   return set;
     26 }
     27 
     28 URLPatternSet Patterns(const std::string& pattern1,
     29                        const std::string& pattern2) {
     30   URLPatternSet set;
     31   AddPattern(&set, pattern1);
     32   AddPattern(&set, pattern2);
     33   return set;
     34 }
     35 
     36 }  // namespace
     37 
     38 TEST(URLPatternSetTest, Empty) {
     39   URLPatternSet set;
     40   EXPECT_FALSE(set.MatchesURL(GURL("http://www.foo.com/bar")));
     41   EXPECT_FALSE(set.MatchesURL(GURL()));
     42   EXPECT_FALSE(set.MatchesURL(GURL("invalid")));
     43 }
     44 
     45 TEST(URLPatternSetTest, One) {
     46   URLPatternSet set;
     47   AddPattern(&set, "http://www.google.com/*");
     48 
     49   EXPECT_TRUE(set.MatchesURL(GURL("http://www.google.com/")));
     50   EXPECT_TRUE(set.MatchesURL(GURL("http://www.google.com/monkey")));
     51   EXPECT_FALSE(set.MatchesURL(GURL("https://www.google.com/")));
     52   EXPECT_FALSE(set.MatchesURL(GURL("https://www.microsoft.com/")));
     53 }
     54 
     55 TEST(URLPatternSetTest, Two) {
     56   URLPatternSet set;
     57   AddPattern(&set, "http://www.google.com/*");
     58   AddPattern(&set, "http://www.yahoo.com/*");
     59 
     60   EXPECT_TRUE(set.MatchesURL(GURL("http://www.google.com/monkey")));
     61   EXPECT_TRUE(set.MatchesURL(GURL("http://www.yahoo.com/monkey")));
     62   EXPECT_FALSE(set.MatchesURL(GURL("https://www.apple.com/monkey")));
     63 }
     64 
     65 TEST(URLPatternSetTest, StreamOperatorEmpty) {
     66   URLPatternSet set;
     67 
     68   std::ostringstream stream;
     69   stream << set;
     70   EXPECT_EQ("{ }", stream.str());
     71 }
     72 
     73 TEST(URLPatternSetTest, StreamOperatorOne) {
     74   URLPatternSet set;
     75   AddPattern(&set, "http://www.google.com/*");
     76 
     77   std::ostringstream stream;
     78   stream << set;
     79   EXPECT_EQ("{ \"http://www.google.com/*\" }", stream.str());
     80 }
     81 
     82 TEST(URLPatternSetTest, StreamOperatorTwo) {
     83   URLPatternSet set;
     84   AddPattern(&set, "http://www.google.com/*");
     85   AddPattern(&set, "http://www.yahoo.com/*");
     86 
     87   std::ostringstream stream;
     88   stream << set;
     89   EXPECT_EQ("{ \"http://www.google.com/*\", \"http://www.yahoo.com/*\" }",
     90             stream.str());
     91 }
     92 
     93 TEST(URLPatternSetTest, OverlapsWith) {
     94   URLPatternSet set1;
     95   AddPattern(&set1, "http://www.google.com/f*");
     96   AddPattern(&set1, "http://www.yahoo.com/b*");
     97 
     98   URLPatternSet set2;
     99   AddPattern(&set2, "http://www.reddit.com/f*");
    100   AddPattern(&set2, "http://www.yahoo.com/z*");
    101 
    102   URLPatternSet set3;
    103   AddPattern(&set3, "http://www.google.com/q/*");
    104   AddPattern(&set3, "http://www.yahoo.com/b/*");
    105 
    106   EXPECT_FALSE(set1.OverlapsWith(set2));
    107   EXPECT_FALSE(set2.OverlapsWith(set1));
    108 
    109   EXPECT_TRUE(set1.OverlapsWith(set3));
    110   EXPECT_TRUE(set3.OverlapsWith(set1));
    111 }
    112 
    113 TEST(URLPatternSetTest, CreateDifference) {
    114   URLPatternSet expected;
    115   URLPatternSet set1;
    116   URLPatternSet set2;
    117   AddPattern(&set1, "http://www.google.com/f*");
    118   AddPattern(&set1, "http://www.yahoo.com/b*");
    119 
    120   // Subtract an empty set.
    121   URLPatternSet result;
    122   URLPatternSet::CreateDifference(set1, set2, &result);
    123   EXPECT_EQ(set1, result);
    124 
    125   // Subtract a real set.
    126   AddPattern(&set2, "http://www.reddit.com/f*");
    127   AddPattern(&set2, "http://www.yahoo.com/z*");
    128   AddPattern(&set2, "http://www.google.com/f*");
    129 
    130   AddPattern(&expected, "http://www.yahoo.com/b*");
    131 
    132   result.ClearPatterns();
    133   URLPatternSet::CreateDifference(set1, set2, &result);
    134   EXPECT_EQ(expected, result);
    135   EXPECT_FALSE(result.is_empty());
    136   EXPECT_TRUE(set1.Contains(result));
    137   EXPECT_FALSE(result.Contains(set2));
    138   EXPECT_FALSE(set2.Contains(result));
    139 
    140   URLPatternSet intersection;
    141   URLPatternSet::CreateIntersection(result, set2, &intersection);
    142   EXPECT_TRUE(intersection.is_empty());
    143 }
    144 
    145 TEST(URLPatternSetTest, CreateIntersection) {
    146   URLPatternSet empty_set;
    147   URLPatternSet expected;
    148   URLPatternSet set1;
    149   AddPattern(&set1, "http://www.google.com/f*");
    150   AddPattern(&set1, "http://www.yahoo.com/b*");
    151 
    152   // Intersection with an empty set.
    153   URLPatternSet result;
    154   URLPatternSet::CreateIntersection(set1, empty_set, &result);
    155   EXPECT_EQ(expected, result);
    156   EXPECT_TRUE(result.is_empty());
    157   EXPECT_TRUE(empty_set.Contains(result));
    158   EXPECT_TRUE(result.Contains(empty_set));
    159   EXPECT_TRUE(set1.Contains(result));
    160 
    161   // Intersection with a real set.
    162   URLPatternSet set2;
    163   AddPattern(&set2, "http://www.reddit.com/f*");
    164   AddPattern(&set2, "http://www.yahoo.com/z*");
    165   AddPattern(&set2, "http://www.google.com/f*");
    166 
    167   AddPattern(&expected, "http://www.google.com/f*");
    168 
    169   result.ClearPatterns();
    170   URLPatternSet::CreateIntersection(set1, set2, &result);
    171   EXPECT_EQ(expected, result);
    172   EXPECT_FALSE(result.is_empty());
    173   EXPECT_TRUE(set1.Contains(result));
    174   EXPECT_TRUE(set2.Contains(result));
    175 }
    176 
    177 TEST(URLPatternSetTest, CreateUnion) {
    178   URLPatternSet empty_set;
    179 
    180   URLPatternSet set1;
    181   AddPattern(&set1, "http://www.google.com/f*");
    182   AddPattern(&set1, "http://www.yahoo.com/b*");
    183 
    184   URLPatternSet expected;
    185   AddPattern(&expected, "http://www.google.com/f*");
    186   AddPattern(&expected, "http://www.yahoo.com/b*");
    187 
    188   // Union with an empty set.
    189   URLPatternSet result;
    190   URLPatternSet::CreateUnion(set1, empty_set, &result);
    191   EXPECT_EQ(expected, result);
    192 
    193   // Union with a real set.
    194   URLPatternSet set2;
    195   AddPattern(&set2, "http://www.reddit.com/f*");
    196   AddPattern(&set2, "http://www.yahoo.com/z*");
    197   AddPattern(&set2, "http://www.google.com/f*");
    198 
    199   AddPattern(&expected, "http://www.reddit.com/f*");
    200   AddPattern(&expected, "http://www.yahoo.com/z*");
    201 
    202   result.ClearPatterns();
    203   URLPatternSet::CreateUnion(set1, set2, &result);
    204   EXPECT_EQ(expected, result);
    205 }
    206 
    207 TEST(URLPatternSetTest, Contains) {
    208   URLPatternSet set1;
    209   URLPatternSet set2;
    210   URLPatternSet empty_set;
    211 
    212   AddPattern(&set1, "http://www.google.com/*");
    213   AddPattern(&set1, "http://www.yahoo.com/*");
    214 
    215   AddPattern(&set2, "http://www.reddit.com/*");
    216 
    217   EXPECT_FALSE(set1.Contains(set2));
    218   EXPECT_TRUE(set1.Contains(empty_set));
    219   EXPECT_FALSE(empty_set.Contains(set1));
    220 
    221   AddPattern(&set2, "http://www.yahoo.com/*");
    222 
    223   EXPECT_FALSE(set1.Contains(set2));
    224   EXPECT_FALSE(set2.Contains(set1));
    225 
    226   AddPattern(&set2, "http://www.google.com/*");
    227 
    228   EXPECT_FALSE(set1.Contains(set2));
    229   EXPECT_TRUE(set2.Contains(set1));
    230 
    231   // Note that this checks if individual patterns contain other patterns, not
    232   // just equality. For example:
    233   AddPattern(&set1, "http://*.reddit.com/*");
    234   EXPECT_TRUE(set1.Contains(set2));
    235   EXPECT_FALSE(set2.Contains(set1));
    236 }
    237 
    238 TEST(URLPatternSetTest, Duplicates) {
    239   URLPatternSet set1;
    240   URLPatternSet set2;
    241 
    242   AddPattern(&set1, "http://www.google.com/*");
    243   AddPattern(&set2, "http://www.google.com/*");
    244 
    245   AddPattern(&set1, "http://www.google.com/*");
    246 
    247   // The sets should still be equal after adding a duplicate.
    248   EXPECT_EQ(set2, set1);
    249 }
    250 
    251 TEST(URLPatternSetTest, ToValueAndPopulate) {
    252   URLPatternSet set1;
    253   URLPatternSet set2;
    254 
    255   std::vector<std::string> patterns;
    256   patterns.push_back("http://www.google.com/*");
    257   patterns.push_back("http://www.yahoo.com/*");
    258 
    259   for (size_t i = 0; i < patterns.size(); ++i)
    260     AddPattern(&set1, patterns[i]);
    261 
    262   std::string error;
    263   bool allow_file_access = false;
    264   scoped_ptr<base::ListValue> value(set1.ToValue());
    265   set2.Populate(*value, URLPattern::SCHEME_ALL, allow_file_access, &error);
    266   EXPECT_EQ(set1, set2);
    267 
    268   set2.ClearPatterns();
    269   set2.Populate(patterns, URLPattern::SCHEME_ALL, allow_file_access, &error);
    270   EXPECT_EQ(set1, set2);
    271 }
    272 
    273 TEST(URLPatternSetTest, NwayUnion) {
    274   std::string google_a = "http://www.google.com/a*";
    275   std::string google_b = "http://www.google.com/b*";
    276   std::string google_c = "http://www.google.com/c*";
    277   std::string yahoo_a = "http://www.yahoo.com/a*";
    278   std::string yahoo_b = "http://www.yahoo.com/b*";
    279   std::string yahoo_c = "http://www.yahoo.com/c*";
    280   std::string reddit_a = "http://www.reddit.com/a*";
    281   std::string reddit_b = "http://www.reddit.com/b*";
    282   std::string reddit_c = "http://www.reddit.com/c*";
    283 
    284   // Empty list.
    285   {
    286     std::vector<URLPatternSet> empty;
    287 
    288     URLPatternSet result;
    289     URLPatternSet::CreateUnion(empty, &result);
    290 
    291     URLPatternSet expected;
    292     EXPECT_EQ(expected, result);
    293   }
    294 
    295   // Singleton list.
    296   {
    297     std::vector<URLPatternSet> test;
    298     test.push_back(Patterns(google_a));
    299 
    300     URLPatternSet result;
    301     URLPatternSet::CreateUnion(test, &result);
    302 
    303     URLPatternSet expected = Patterns(google_a);
    304     EXPECT_EQ(expected, result);
    305   }
    306 
    307   // List with 2 elements.
    308   {
    309     std::vector<URLPatternSet> test;
    310     test.push_back(Patterns(google_a, google_b));
    311     test.push_back(Patterns(google_b, google_c));
    312 
    313     URLPatternSet result;
    314     URLPatternSet::CreateUnion(test, &result);
    315 
    316     URLPatternSet expected;
    317     AddPattern(&expected, google_a);
    318     AddPattern(&expected, google_b);
    319     AddPattern(&expected, google_c);
    320     EXPECT_EQ(expected, result);
    321   }
    322 
    323   // List with 3 elements.
    324   {
    325     std::vector<URLPatternSet> test;
    326     test.push_back(Patterns(google_a, google_b));
    327     test.push_back(Patterns(google_b, google_c));
    328     test.push_back(Patterns(yahoo_a, yahoo_b));
    329 
    330     URLPatternSet result;
    331     URLPatternSet::CreateUnion(test, &result);
    332 
    333     URLPatternSet expected;
    334     AddPattern(&expected, google_a);
    335     AddPattern(&expected, google_b);
    336     AddPattern(&expected, google_c);
    337     AddPattern(&expected, yahoo_a);
    338     AddPattern(&expected, yahoo_b);
    339     EXPECT_EQ(expected, result);
    340   }
    341 
    342   // List with 7 elements.
    343   {
    344     std::vector<URLPatternSet> test;
    345     test.push_back(Patterns(google_a));
    346     test.push_back(Patterns(google_b));
    347     test.push_back(Patterns(google_c));
    348     test.push_back(Patterns(yahoo_a));
    349     test.push_back(Patterns(yahoo_b));
    350     test.push_back(Patterns(yahoo_c));
    351     test.push_back(Patterns(reddit_a));
    352 
    353     URLPatternSet result;
    354     URLPatternSet::CreateUnion(test, &result);
    355 
    356     URLPatternSet expected;
    357     AddPattern(&expected, google_a);
    358     AddPattern(&expected, google_b);
    359     AddPattern(&expected, google_c);
    360     AddPattern(&expected, yahoo_a);
    361     AddPattern(&expected, yahoo_b);
    362     AddPattern(&expected, yahoo_c);
    363     AddPattern(&expected, reddit_a);
    364     EXPECT_EQ(expected, result);
    365   }
    366 
    367   // List with 8 elements.
    368   {
    369     std::vector<URLPatternSet> test;
    370     test.push_back(Patterns(google_a));
    371     test.push_back(Patterns(google_b));
    372     test.push_back(Patterns(google_c));
    373     test.push_back(Patterns(yahoo_a));
    374     test.push_back(Patterns(yahoo_b));
    375     test.push_back(Patterns(yahoo_c));
    376     test.push_back(Patterns(reddit_a));
    377     test.push_back(Patterns(reddit_b));
    378 
    379     URLPatternSet result;
    380     URLPatternSet::CreateUnion(test, &result);
    381 
    382     URLPatternSet expected;
    383     AddPattern(&expected, google_a);
    384     AddPattern(&expected, google_b);
    385     AddPattern(&expected, google_c);
    386     AddPattern(&expected, yahoo_a);
    387     AddPattern(&expected, yahoo_b);
    388     AddPattern(&expected, yahoo_c);
    389     AddPattern(&expected, reddit_a);
    390     AddPattern(&expected, reddit_b);
    391     EXPECT_EQ(expected, result);
    392   }
    393 
    394   // List with 9 elements.
    395   {
    396     std::vector<URLPatternSet> test;
    397     test.push_back(Patterns(google_a));
    398     test.push_back(Patterns(google_b));
    399     test.push_back(Patterns(google_c));
    400     test.push_back(Patterns(yahoo_a));
    401     test.push_back(Patterns(yahoo_b));
    402     test.push_back(Patterns(yahoo_c));
    403     test.push_back(Patterns(reddit_a));
    404     test.push_back(Patterns(reddit_b));
    405     test.push_back(Patterns(reddit_c));
    406 
    407     URLPatternSet result;
    408     URLPatternSet::CreateUnion(test, &result);
    409 
    410     URLPatternSet expected;
    411     AddPattern(&expected, google_a);
    412     AddPattern(&expected, google_b);
    413     AddPattern(&expected, google_c);
    414     AddPattern(&expected, yahoo_a);
    415     AddPattern(&expected, yahoo_b);
    416     AddPattern(&expected, yahoo_c);
    417     AddPattern(&expected, reddit_a);
    418     AddPattern(&expected, reddit_b);
    419     AddPattern(&expected, reddit_c);
    420     EXPECT_EQ(expected, result);
    421   }
    422 }
    423 
    424 TEST(URLPatternSetTest, AddOrigin) {
    425   URLPatternSet set;
    426   EXPECT_TRUE(set.AddOrigin(
    427       URLPattern::SCHEME_ALL, GURL("https://www.google.com/")));
    428   EXPECT_TRUE(set.MatchesURL(GURL("https://www.google.com/foo/bar")));
    429   EXPECT_FALSE(set.MatchesURL(GURL("http://www.google.com/foo/bar")));
    430   EXPECT_FALSE(set.MatchesURL(GURL("https://en.google.com/foo/bar")));
    431   set.ClearPatterns();
    432 
    433   EXPECT_TRUE(set.AddOrigin(
    434       URLPattern::SCHEME_ALL, GURL("https://google.com/")));
    435   EXPECT_FALSE(set.MatchesURL(GURL("https://www.google.com/foo/bar")));
    436   EXPECT_TRUE(set.MatchesURL(GURL("https://google.com/foo/bar")));
    437 
    438   EXPECT_FALSE(set.AddOrigin(
    439       URLPattern::SCHEME_HTTP, GURL("https://google.com/")));
    440 }
    441 
    442 }  // namespace extensions
    443