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.
5 #include "extensions/common/url_pattern_set.h"
9 #include "base/values.h"
10 #include "testing/gtest/include/gtest/gtest.h"
13 namespace extensions
{
17 void AddPattern(URLPatternSet
* set
, const std::string
& pattern
) {
18 int schemes
= URLPattern::SCHEME_ALL
;
19 set
->AddPattern(URLPattern(schemes
, pattern
));
22 URLPatternSet
Patterns(const std::string
& pattern
) {
24 AddPattern(&set
, pattern
);
28 URLPatternSet
Patterns(const std::string
& pattern1
,
29 const std::string
& pattern2
) {
31 AddPattern(&set
, pattern1
);
32 AddPattern(&set
, pattern2
);
38 TEST(URLPatternSetTest
, Empty
) {
40 EXPECT_FALSE(set
.MatchesURL(GURL("http://www.foo.com/bar")));
41 EXPECT_FALSE(set
.MatchesURL(GURL()));
42 EXPECT_FALSE(set
.MatchesURL(GURL("invalid")));
45 TEST(URLPatternSetTest
, One
) {
47 AddPattern(&set
, "http://www.google.com/*");
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/")));
55 TEST(URLPatternSetTest
, Two
) {
57 AddPattern(&set
, "http://www.google.com/*");
58 AddPattern(&set
, "http://www.yahoo.com/*");
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")));
65 TEST(URLPatternSetTest
, StreamOperatorEmpty
) {
68 std::ostringstream stream
;
70 EXPECT_EQ("{ }", stream
.str());
73 TEST(URLPatternSetTest
, StreamOperatorOne
) {
75 AddPattern(&set
, "http://www.google.com/*");
77 std::ostringstream stream
;
79 EXPECT_EQ("{ \"http://www.google.com/*\" }", stream
.str());
82 TEST(URLPatternSetTest
, StreamOperatorTwo
) {
84 AddPattern(&set
, "http://www.google.com/*");
85 AddPattern(&set
, "http://www.yahoo.com/*");
87 std::ostringstream stream
;
89 EXPECT_EQ("{ \"http://www.google.com/*\", \"http://www.yahoo.com/*\" }",
93 TEST(URLPatternSetTest
, OverlapsWith
) {
95 AddPattern(&set1
, "http://www.google.com/f*");
96 AddPattern(&set1
, "http://www.yahoo.com/b*");
99 AddPattern(&set2
, "http://www.reddit.com/f*");
100 AddPattern(&set2
, "http://www.yahoo.com/z*");
103 AddPattern(&set3
, "http://www.google.com/q/*");
104 AddPattern(&set3
, "http://www.yahoo.com/b/*");
106 EXPECT_FALSE(set1
.OverlapsWith(set2
));
107 EXPECT_FALSE(set2
.OverlapsWith(set1
));
109 EXPECT_TRUE(set1
.OverlapsWith(set3
));
110 EXPECT_TRUE(set3
.OverlapsWith(set1
));
113 TEST(URLPatternSetTest
, CreateDifference
) {
114 URLPatternSet expected
;
117 AddPattern(&set1
, "http://www.google.com/f*");
118 AddPattern(&set1
, "http://www.yahoo.com/b*");
120 // Subtract an empty set.
121 URLPatternSet result
= URLPatternSet::CreateDifference(set1
, set2
);
122 EXPECT_EQ(set1
, result
);
124 // Subtract a real set.
125 AddPattern(&set2
, "http://www.reddit.com/f*");
126 AddPattern(&set2
, "http://www.yahoo.com/z*");
127 AddPattern(&set2
, "http://www.google.com/f*");
129 AddPattern(&expected
, "http://www.yahoo.com/b*");
131 result
= URLPatternSet::CreateDifference(set1
, set2
);
132 EXPECT_EQ(expected
, result
);
133 EXPECT_FALSE(result
.is_empty());
134 EXPECT_TRUE(set1
.Contains(result
));
135 EXPECT_FALSE(result
.Contains(set2
));
136 EXPECT_FALSE(set2
.Contains(result
));
138 URLPatternSet intersection
= URLPatternSet::CreateIntersection(result
, set2
);
139 EXPECT_TRUE(intersection
.is_empty());
142 TEST(URLPatternSetTest
, CreateIntersection
) {
143 URLPatternSet empty_set
;
144 URLPatternSet expected
;
146 AddPattern(&set1
, "http://www.google.com/f*");
147 AddPattern(&set1
, "http://www.yahoo.com/b*");
149 // Intersection with an empty set.
150 URLPatternSet result
= URLPatternSet::CreateIntersection(set1
, empty_set
);
151 EXPECT_EQ(expected
, result
);
152 EXPECT_TRUE(result
.is_empty());
153 EXPECT_TRUE(empty_set
.Contains(result
));
154 EXPECT_TRUE(result
.Contains(empty_set
));
155 EXPECT_TRUE(set1
.Contains(result
));
157 // Intersection with a real set.
159 AddPattern(&set2
, "http://www.reddit.com/f*");
160 AddPattern(&set2
, "http://www.yahoo.com/z*");
161 AddPattern(&set2
, "http://www.google.com/f*");
163 AddPattern(&expected
, "http://www.google.com/f*");
165 result
= URLPatternSet::CreateIntersection(set1
, set2
);
166 EXPECT_EQ(expected
, result
);
167 EXPECT_FALSE(result
.is_empty());
168 EXPECT_TRUE(set1
.Contains(result
));
169 EXPECT_TRUE(set2
.Contains(result
));
172 TEST(URLPatternSetTest
, CreateSemanticIntersection
) {
175 AddPattern(&set1
, "http://*.google.com/*");
176 AddPattern(&set1
, "http://*.yahoo.com/*");
179 AddPattern(&set2
, "http://google.com/*");
181 // The semantic intersection should contain only those patterns that are in
182 // both set 1 and set 2, or "http://google.com/*".
183 URLPatternSet intersection
=
184 URLPatternSet::CreateSemanticIntersection(set1
, set2
);
185 ASSERT_EQ(1u, intersection
.size());
186 EXPECT_EQ("http://google.com/*", intersection
.begin()->GetAsString());
190 // We don't handle funny intersections, where the resultant pattern is
191 // neither of the two compared patterns. So the intersection of these two
192 // is not http://www.google.com/*, but rather nothing.
194 AddPattern(&set1
, "http://*/*");
196 AddPattern(&set2
, "*://www.google.com/*");
198 URLPatternSet::CreateSemanticIntersection(set1
, set2
).is_empty());
202 TEST(URLPatternSetTest
, CreateUnion
) {
203 URLPatternSet empty_set
;
206 AddPattern(&set1
, "http://www.google.com/f*");
207 AddPattern(&set1
, "http://www.yahoo.com/b*");
209 URLPatternSet expected
;
210 AddPattern(&expected
, "http://www.google.com/f*");
211 AddPattern(&expected
, "http://www.yahoo.com/b*");
213 // Union with an empty set.
214 URLPatternSet result
= URLPatternSet::CreateUnion(set1
, empty_set
);
215 EXPECT_EQ(expected
, result
);
217 // Union with a real set.
219 AddPattern(&set2
, "http://www.reddit.com/f*");
220 AddPattern(&set2
, "http://www.yahoo.com/z*");
221 AddPattern(&set2
, "http://www.google.com/f*");
223 AddPattern(&expected
, "http://www.reddit.com/f*");
224 AddPattern(&expected
, "http://www.yahoo.com/z*");
226 result
= URLPatternSet::CreateUnion(set1
, set2
);
227 EXPECT_EQ(expected
, result
);
230 TEST(URLPatternSetTest
, Contains
) {
233 URLPatternSet empty_set
;
235 AddPattern(&set1
, "http://www.google.com/*");
236 AddPattern(&set1
, "http://www.yahoo.com/*");
238 AddPattern(&set2
, "http://www.reddit.com/*");
240 EXPECT_FALSE(set1
.Contains(set2
));
241 EXPECT_TRUE(set1
.Contains(empty_set
));
242 EXPECT_FALSE(empty_set
.Contains(set1
));
244 AddPattern(&set2
, "http://www.yahoo.com/*");
246 EXPECT_FALSE(set1
.Contains(set2
));
247 EXPECT_FALSE(set2
.Contains(set1
));
249 AddPattern(&set2
, "http://www.google.com/*");
251 EXPECT_FALSE(set1
.Contains(set2
));
252 EXPECT_TRUE(set2
.Contains(set1
));
254 // Note that this checks if individual patterns contain other patterns, not
255 // just equality. For example:
256 AddPattern(&set1
, "http://*.reddit.com/*");
257 EXPECT_TRUE(set1
.Contains(set2
));
258 EXPECT_FALSE(set2
.Contains(set1
));
261 TEST(URLPatternSetTest
, Duplicates
) {
265 AddPattern(&set1
, "http://www.google.com/*");
266 AddPattern(&set2
, "http://www.google.com/*");
268 AddPattern(&set1
, "http://www.google.com/*");
270 // The sets should still be equal after adding a duplicate.
271 EXPECT_EQ(set2
, set1
);
274 TEST(URLPatternSetTest
, ToValueAndPopulate
) {
278 std::vector
<std::string
> patterns
;
279 patterns
.push_back("http://www.google.com/*");
280 patterns
.push_back("http://www.yahoo.com/*");
282 for (size_t i
= 0; i
< patterns
.size(); ++i
)
283 AddPattern(&set1
, patterns
[i
]);
286 bool allow_file_access
= false;
287 scoped_ptr
<base::ListValue
> value(set1
.ToValue());
288 set2
.Populate(*value
, URLPattern::SCHEME_ALL
, allow_file_access
, &error
);
289 EXPECT_EQ(set1
, set2
);
291 set2
.ClearPatterns();
292 set2
.Populate(patterns
, URLPattern::SCHEME_ALL
, allow_file_access
, &error
);
293 EXPECT_EQ(set1
, set2
);
296 TEST(URLPatternSetTest
, NwayUnion
) {
297 std::string google_a
= "http://www.google.com/a*";
298 std::string google_b
= "http://www.google.com/b*";
299 std::string google_c
= "http://www.google.com/c*";
300 std::string yahoo_a
= "http://www.yahoo.com/a*";
301 std::string yahoo_b
= "http://www.yahoo.com/b*";
302 std::string yahoo_c
= "http://www.yahoo.com/c*";
303 std::string reddit_a
= "http://www.reddit.com/a*";
304 std::string reddit_b
= "http://www.reddit.com/b*";
305 std::string reddit_c
= "http://www.reddit.com/c*";
309 std::vector
<URLPatternSet
> empty
;
311 URLPatternSet result
= URLPatternSet::CreateUnion(empty
);
313 URLPatternSet expected
;
314 EXPECT_EQ(expected
, result
);
319 std::vector
<URLPatternSet
> test
;
320 test
.push_back(Patterns(google_a
));
322 URLPatternSet result
= URLPatternSet::CreateUnion(test
);
324 URLPatternSet expected
= Patterns(google_a
);
325 EXPECT_EQ(expected
, result
);
328 // List with 2 elements.
330 std::vector
<URLPatternSet
> test
;
331 test
.push_back(Patterns(google_a
, google_b
));
332 test
.push_back(Patterns(google_b
, google_c
));
334 URLPatternSet result
= URLPatternSet::CreateUnion(test
);
336 URLPatternSet expected
;
337 AddPattern(&expected
, google_a
);
338 AddPattern(&expected
, google_b
);
339 AddPattern(&expected
, google_c
);
340 EXPECT_EQ(expected
, result
);
343 // List with 3 elements.
345 std::vector
<URLPatternSet
> test
;
346 test
.push_back(Patterns(google_a
, google_b
));
347 test
.push_back(Patterns(google_b
, google_c
));
348 test
.push_back(Patterns(yahoo_a
, yahoo_b
));
350 URLPatternSet result
= URLPatternSet::CreateUnion(test
);
352 URLPatternSet expected
;
353 AddPattern(&expected
, google_a
);
354 AddPattern(&expected
, google_b
);
355 AddPattern(&expected
, google_c
);
356 AddPattern(&expected
, yahoo_a
);
357 AddPattern(&expected
, yahoo_b
);
358 EXPECT_EQ(expected
, result
);
361 // List with 7 elements.
363 std::vector
<URLPatternSet
> test
;
364 test
.push_back(Patterns(google_a
));
365 test
.push_back(Patterns(google_b
));
366 test
.push_back(Patterns(google_c
));
367 test
.push_back(Patterns(yahoo_a
));
368 test
.push_back(Patterns(yahoo_b
));
369 test
.push_back(Patterns(yahoo_c
));
370 test
.push_back(Patterns(reddit_a
));
372 URLPatternSet result
= URLPatternSet::CreateUnion(test
);
374 URLPatternSet expected
;
375 AddPattern(&expected
, google_a
);
376 AddPattern(&expected
, google_b
);
377 AddPattern(&expected
, google_c
);
378 AddPattern(&expected
, yahoo_a
);
379 AddPattern(&expected
, yahoo_b
);
380 AddPattern(&expected
, yahoo_c
);
381 AddPattern(&expected
, reddit_a
);
382 EXPECT_EQ(expected
, result
);
385 // List with 8 elements.
387 std::vector
<URLPatternSet
> test
;
388 test
.push_back(Patterns(google_a
));
389 test
.push_back(Patterns(google_b
));
390 test
.push_back(Patterns(google_c
));
391 test
.push_back(Patterns(yahoo_a
));
392 test
.push_back(Patterns(yahoo_b
));
393 test
.push_back(Patterns(yahoo_c
));
394 test
.push_back(Patterns(reddit_a
));
395 test
.push_back(Patterns(reddit_b
));
397 URLPatternSet result
= URLPatternSet::CreateUnion(test
);
399 URLPatternSet expected
;
400 AddPattern(&expected
, google_a
);
401 AddPattern(&expected
, google_b
);
402 AddPattern(&expected
, google_c
);
403 AddPattern(&expected
, yahoo_a
);
404 AddPattern(&expected
, yahoo_b
);
405 AddPattern(&expected
, yahoo_c
);
406 AddPattern(&expected
, reddit_a
);
407 AddPattern(&expected
, reddit_b
);
408 EXPECT_EQ(expected
, result
);
411 // List with 9 elements.
413 std::vector
<URLPatternSet
> test
;
414 test
.push_back(Patterns(google_a
));
415 test
.push_back(Patterns(google_b
));
416 test
.push_back(Patterns(google_c
));
417 test
.push_back(Patterns(yahoo_a
));
418 test
.push_back(Patterns(yahoo_b
));
419 test
.push_back(Patterns(yahoo_c
));
420 test
.push_back(Patterns(reddit_a
));
421 test
.push_back(Patterns(reddit_b
));
422 test
.push_back(Patterns(reddit_c
));
424 URLPatternSet result
= URLPatternSet::CreateUnion(test
);
426 URLPatternSet expected
;
427 AddPattern(&expected
, google_a
);
428 AddPattern(&expected
, google_b
);
429 AddPattern(&expected
, google_c
);
430 AddPattern(&expected
, yahoo_a
);
431 AddPattern(&expected
, yahoo_b
);
432 AddPattern(&expected
, yahoo_c
);
433 AddPattern(&expected
, reddit_a
);
434 AddPattern(&expected
, reddit_b
);
435 AddPattern(&expected
, reddit_c
);
436 EXPECT_EQ(expected
, result
);
440 TEST(URLPatternSetTest
, AddOrigin
) {
442 EXPECT_TRUE(set
.AddOrigin(
443 URLPattern::SCHEME_ALL
, GURL("https://www.google.com/")));
444 EXPECT_TRUE(set
.MatchesURL(GURL("https://www.google.com/foo/bar")));
445 EXPECT_FALSE(set
.MatchesURL(GURL("http://www.google.com/foo/bar")));
446 EXPECT_FALSE(set
.MatchesURL(GURL("https://en.google.com/foo/bar")));
449 EXPECT_TRUE(set
.AddOrigin(
450 URLPattern::SCHEME_ALL
, GURL("https://google.com/")));
451 EXPECT_FALSE(set
.MatchesURL(GURL("https://www.google.com/foo/bar")));
452 EXPECT_TRUE(set
.MatchesURL(GURL("https://google.com/foo/bar")));
454 EXPECT_FALSE(set
.AddOrigin(
455 URLPattern::SCHEME_HTTP
, GURL("https://google.com/")));
458 } // namespace extensions