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