• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
AddPattern(URLPatternSet * set,const std::string & pattern)17 void AddPattern(URLPatternSet* set, const std::string& pattern) {
18   int schemes = URLPattern::SCHEME_ALL;
19   set->AddPattern(URLPattern(schemes, pattern));
20 }
21 
Patterns(const std::string & pattern)22 URLPatternSet Patterns(const std::string& pattern) {
23   URLPatternSet set;
24   AddPattern(&set, pattern);
25   return set;
26 }
27 
Patterns(const std::string & pattern1,const std::string & pattern2)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 
TEST(URLPatternSetTest,Empty)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 
TEST(URLPatternSetTest,One)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 
TEST(URLPatternSetTest,Two)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 
TEST(URLPatternSetTest,StreamOperatorEmpty)65 TEST(URLPatternSetTest, StreamOperatorEmpty) {
66   URLPatternSet set;
67 
68   std::ostringstream stream;
69   stream << set;
70   EXPECT_EQ("{ }", stream.str());
71 }
72 
TEST(URLPatternSetTest,StreamOperatorOne)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 
TEST(URLPatternSetTest,StreamOperatorTwo)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 
TEST(URLPatternSetTest,OverlapsWith)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 
TEST(URLPatternSetTest,CreateDifference)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 
TEST(URLPatternSetTest,CreateIntersection)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 
TEST(URLPatternSetTest,CreateUnion)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 
TEST(URLPatternSetTest,Contains)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 
TEST(URLPatternSetTest,Duplicates)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 
TEST(URLPatternSetTest,ToValueAndPopulate)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 
TEST(URLPatternSetTest,NwayUnion)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 
TEST(URLPatternSetTest,AddOrigin)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