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