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 13namespace extensions { 14 15namespace { 16 17void AddPattern(URLPatternSet* set, const std::string& pattern) { 18 int schemes = URLPattern::SCHEME_ALL; 19 set->AddPattern(URLPattern(schemes, pattern)); 20} 21 22URLPatternSet Patterns(const std::string& pattern) { 23 URLPatternSet set; 24 AddPattern(&set, pattern); 25 return set; 26} 27 28URLPatternSet 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 38TEST(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 45TEST(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 55TEST(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 65TEST(URLPatternSetTest, StreamOperatorEmpty) { 66 URLPatternSet set; 67 68 std::ostringstream stream; 69 stream << set; 70 EXPECT_EQ("{ }", stream.str()); 71} 72 73TEST(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 82TEST(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 93TEST(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 113TEST(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 145TEST(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 177TEST(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 207TEST(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 238TEST(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 251TEST(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 273TEST(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 424TEST(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