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 "testing/gtest/include/gtest/gtest.h" 6 #include "webkit/browser/appcache/appcache.h" 7 #include "webkit/browser/appcache/appcache_host.h" 8 #include "webkit/browser/appcache/mock_appcache_service.h" 9 10 namespace appcache { 11 12 namespace { 13 14 class MockAppCacheFrontend : public AppCacheFrontend { 15 public: 16 virtual void OnCacheSelected( 17 int host_id, const appcache::AppCacheInfo& info) OVERRIDE {} 18 virtual void OnStatusChanged(const std::vector<int>& host_ids, 19 Status status) OVERRIDE {} 20 virtual void OnEventRaised(const std::vector<int>& host_ids, 21 EventID event_id) OVERRIDE {} 22 virtual void OnProgressEventRaised( 23 const std::vector<int>& host_ids, 24 const GURL& url, 25 int num_total, int num_complete) OVERRIDE {} 26 virtual void OnErrorEventRaised(const std::vector<int>& host_ids, 27 const std::string& message) OVERRIDE {} 28 virtual void OnLogMessage(int host_id, LogLevel log_level, 29 const std::string& message) OVERRIDE {} 30 virtual void OnContentBlocked( 31 int host_id, const GURL& manifest_url) OVERRIDE {} 32 }; 33 34 } // namespace 35 36 class AppCacheTest : public testing::Test { 37 }; 38 39 TEST(AppCacheTest, CleanupUnusedCache) { 40 MockAppCacheService service; 41 MockAppCacheFrontend frontend; 42 scoped_refptr<AppCache> cache(new AppCache(service.storage(), 111)); 43 cache->set_complete(true); 44 scoped_refptr<AppCacheGroup> group( 45 new AppCacheGroup(service.storage(), GURL("http://blah/manifest"), 111)); 46 group->AddCache(cache.get()); 47 48 AppCacheHost host1(1, &frontend, &service); 49 AppCacheHost host2(2, &frontend, &service); 50 51 host1.AssociateCompleteCache(cache.get()); 52 host2.AssociateCompleteCache(cache.get()); 53 54 host1.AssociateNoCache(GURL()); 55 host2.AssociateNoCache(GURL()); 56 } 57 58 TEST(AppCacheTest, AddModifyRemoveEntry) { 59 MockAppCacheService service; 60 scoped_refptr<AppCache> cache(new AppCache(service.storage(), 111)); 61 62 EXPECT_TRUE(cache->entries().empty()); 63 EXPECT_EQ(0L, cache->cache_size()); 64 65 const GURL kFooUrl("http://foo.com"); 66 const int64 kFooResponseId = 1; 67 const int64 kFooSize = 100; 68 AppCacheEntry entry1(AppCacheEntry::MASTER, kFooResponseId, kFooSize); 69 cache->AddEntry(kFooUrl, entry1); 70 EXPECT_EQ(entry1.types(), cache->GetEntry(kFooUrl)->types()); 71 EXPECT_EQ(1UL, cache->entries().size()); 72 EXPECT_EQ(kFooSize, cache->cache_size()); 73 74 const GURL kBarUrl("http://bar.com"); 75 const int64 kBarResponseId = 2; 76 const int64 kBarSize = 200; 77 AppCacheEntry entry2(AppCacheEntry::FALLBACK, kBarResponseId, kBarSize); 78 EXPECT_TRUE(cache->AddOrModifyEntry(kBarUrl, entry2)); 79 EXPECT_EQ(entry2.types(), cache->GetEntry(kBarUrl)->types()); 80 EXPECT_EQ(2UL, cache->entries().size()); 81 EXPECT_EQ(kFooSize + kBarSize, cache->cache_size()); 82 83 // Expected to return false when an existing entry is modified. 84 AppCacheEntry entry3(AppCacheEntry::EXPLICIT); 85 EXPECT_FALSE(cache->AddOrModifyEntry(kFooUrl, entry3)); 86 EXPECT_EQ((AppCacheEntry::MASTER | AppCacheEntry::EXPLICIT), 87 cache->GetEntry(kFooUrl)->types()); 88 // Only the type should be modified. 89 EXPECT_EQ(kFooResponseId, cache->GetEntry(kFooUrl)->response_id()); 90 EXPECT_EQ(kFooSize, cache->GetEntry(kFooUrl)->response_size()); 91 EXPECT_EQ(kFooSize + kBarSize, cache->cache_size()); 92 93 EXPECT_EQ(entry2.types(), cache->GetEntry(kBarUrl)->types()); // unchanged 94 95 cache->RemoveEntry(kBarUrl); 96 EXPECT_EQ(kFooSize, cache->cache_size()); 97 cache->RemoveEntry(kFooUrl); 98 EXPECT_EQ(0L, cache->cache_size()); 99 EXPECT_TRUE(cache->entries().empty()); 100 } 101 102 TEST(AppCacheTest, InitializeWithManifest) { 103 MockAppCacheService service; 104 105 scoped_refptr<AppCache> cache(new AppCache(service.storage(), 1234)); 106 EXPECT_TRUE(cache->fallback_namespaces_.empty()); 107 EXPECT_TRUE(cache->online_whitelist_namespaces_.empty()); 108 EXPECT_FALSE(cache->online_whitelist_all_); 109 110 Manifest manifest; 111 manifest.explicit_urls.insert("http://one.com"); 112 manifest.explicit_urls.insert("http://two.com"); 113 manifest.fallback_namespaces.push_back( 114 Namespace(FALLBACK_NAMESPACE, GURL("http://fb1.com"), 115 GURL("http://fbone.com"), true)); 116 manifest.online_whitelist_namespaces.push_back( 117 Namespace(NETWORK_NAMESPACE, GURL("http://w1.com"), GURL(), false)); 118 manifest.online_whitelist_namespaces.push_back( 119 Namespace(NETWORK_NAMESPACE, GURL("http://w2.com"), GURL(), false)); 120 manifest.online_whitelist_all = true; 121 122 cache->InitializeWithManifest(&manifest); 123 const std::vector<Namespace>& fallbacks = 124 cache->fallback_namespaces_; 125 size_t expected = 1; 126 EXPECT_EQ(expected, fallbacks.size()); 127 EXPECT_EQ(GURL("http://fb1.com"), fallbacks[0].namespace_url); 128 EXPECT_EQ(GURL("http://fbone.com"), fallbacks[0].target_url); 129 EXPECT_TRUE(fallbacks[0].is_pattern); 130 const NamespaceVector& whitelist = cache->online_whitelist_namespaces_; 131 expected = 2; 132 EXPECT_EQ(expected, whitelist.size()); 133 EXPECT_EQ(GURL("http://w1.com"), whitelist[0].namespace_url); 134 EXPECT_EQ(GURL("http://w2.com"), whitelist[1].namespace_url); 135 EXPECT_TRUE(cache->online_whitelist_all_); 136 137 // Ensure collections in manifest were taken over by the cache rather than 138 // copied. 139 EXPECT_TRUE(manifest.fallback_namespaces.empty()); 140 EXPECT_TRUE(manifest.online_whitelist_namespaces.empty()); 141 } 142 143 TEST(AppCacheTest, FindResponseForRequest) { 144 MockAppCacheService service; 145 146 const GURL kOnlineNamespaceUrl("http://blah/online_namespace"); 147 const GURL kFallbackEntryUrl1("http://blah/fallback_entry1"); 148 const GURL kFallbackNamespaceUrl1("http://blah/fallback_namespace/"); 149 const GURL kFallbackEntryUrl2("http://blah/fallback_entry2"); 150 const GURL kFallbackNamespaceUrl2("http://blah/fallback_namespace/longer"); 151 const GURL kManifestUrl("http://blah/manifest"); 152 const GURL kForeignExplicitEntryUrl("http://blah/foreign"); 153 const GURL kInOnlineNamespaceUrl( 154 "http://blah/online_namespace/network"); 155 const GURL kExplicitInOnlineNamespaceUrl( 156 "http://blah/online_namespace/explicit"); 157 const GURL kFallbackTestUrl1("http://blah/fallback_namespace/1"); 158 const GURL kFallbackTestUrl2("http://blah/fallback_namespace/longer2"); 159 const GURL kInterceptNamespace("http://blah/intercept_namespace/"); 160 const GURL kInterceptNamespaceWithinFallback( 161 "http://blah/fallback_namespace/intercept_namespace/"); 162 const GURL kInterceptNamespaceEntry("http://blah/intercept_entry"); 163 const GURL kOnlineNamespaceWithinOtherNamespaces( 164 "http://blah/fallback_namespace/intercept_namespace/1/online"); 165 166 const int64 kFallbackResponseId1 = 1; 167 const int64 kFallbackResponseId2 = 2; 168 const int64 kManifestResponseId = 3; 169 const int64 kForeignExplicitResponseId = 4; 170 const int64 kExplicitInOnlineNamespaceResponseId = 5; 171 const int64 kInterceptResponseId = 6; 172 173 Manifest manifest; 174 manifest.online_whitelist_namespaces.push_back( 175 Namespace(NETWORK_NAMESPACE, kOnlineNamespaceUrl, 176 GURL(), false)); 177 manifest.online_whitelist_namespaces.push_back( 178 Namespace(NETWORK_NAMESPACE, kOnlineNamespaceWithinOtherNamespaces, 179 GURL(), false)); 180 manifest.fallback_namespaces.push_back( 181 Namespace(FALLBACK_NAMESPACE, kFallbackNamespaceUrl1, 182 kFallbackEntryUrl1, false)); 183 manifest.fallback_namespaces.push_back( 184 Namespace(FALLBACK_NAMESPACE, kFallbackNamespaceUrl2, 185 kFallbackEntryUrl2, false)); 186 manifest.intercept_namespaces.push_back( 187 Namespace(INTERCEPT_NAMESPACE, kInterceptNamespace, 188 kInterceptNamespaceEntry, false)); 189 manifest.intercept_namespaces.push_back( 190 Namespace(INTERCEPT_NAMESPACE, kInterceptNamespaceWithinFallback, 191 kInterceptNamespaceEntry, false)); 192 193 // Create a cache with some namespaces and entries. 194 scoped_refptr<AppCache> cache(new AppCache(service.storage(), 1234)); 195 cache->InitializeWithManifest(&manifest); 196 cache->AddEntry( 197 kFallbackEntryUrl1, 198 AppCacheEntry(AppCacheEntry::FALLBACK, kFallbackResponseId1)); 199 cache->AddEntry( 200 kFallbackEntryUrl2, 201 AppCacheEntry(AppCacheEntry::FALLBACK, kFallbackResponseId2)); 202 cache->AddEntry( 203 kManifestUrl, 204 AppCacheEntry(AppCacheEntry::MANIFEST, kManifestResponseId)); 205 cache->AddEntry( 206 kForeignExplicitEntryUrl, 207 AppCacheEntry(AppCacheEntry::EXPLICIT | AppCacheEntry::FOREIGN, 208 kForeignExplicitResponseId)); 209 cache->AddEntry( 210 kExplicitInOnlineNamespaceUrl, 211 AppCacheEntry(AppCacheEntry::EXPLICIT, 212 kExplicitInOnlineNamespaceResponseId)); 213 cache->AddEntry( 214 kInterceptNamespaceEntry, 215 AppCacheEntry(AppCacheEntry::INTERCEPT, kInterceptResponseId)); 216 cache->set_complete(true); 217 218 // See that we get expected results from FindResponseForRequest 219 220 bool found = false; 221 AppCacheEntry entry; 222 AppCacheEntry fallback_entry; 223 GURL intercept_namespace; 224 GURL fallback_namespace; 225 bool network_namespace = false; 226 227 found = cache->FindResponseForRequest(GURL("http://blah/miss"), 228 &entry, &intercept_namespace, 229 &fallback_entry, &fallback_namespace, 230 &network_namespace); 231 EXPECT_FALSE(found); 232 233 found = cache->FindResponseForRequest(kForeignExplicitEntryUrl, 234 &entry, &intercept_namespace, 235 &fallback_entry, &fallback_namespace, 236 &network_namespace); 237 EXPECT_TRUE(found); 238 EXPECT_EQ(kForeignExplicitResponseId, entry.response_id()); 239 EXPECT_FALSE(fallback_entry.has_response_id()); 240 EXPECT_FALSE(network_namespace); 241 242 entry = AppCacheEntry(); // reset 243 244 found = cache->FindResponseForRequest(kManifestUrl, 245 &entry, &intercept_namespace, 246 &fallback_entry, &fallback_namespace, 247 &network_namespace); 248 EXPECT_TRUE(found); 249 EXPECT_EQ(kManifestResponseId, entry.response_id()); 250 EXPECT_FALSE(fallback_entry.has_response_id()); 251 EXPECT_FALSE(network_namespace); 252 253 entry = AppCacheEntry(); // reset 254 255 found = cache->FindResponseForRequest(kInOnlineNamespaceUrl, 256 &entry, &intercept_namespace, 257 &fallback_entry, &fallback_namespace, 258 &network_namespace); 259 EXPECT_TRUE(found); 260 EXPECT_FALSE(entry.has_response_id()); 261 EXPECT_FALSE(fallback_entry.has_response_id()); 262 EXPECT_TRUE(network_namespace); 263 264 network_namespace = false; // reset 265 266 found = cache->FindResponseForRequest(kExplicitInOnlineNamespaceUrl, 267 &entry, &intercept_namespace, 268 &fallback_entry, &fallback_namespace, 269 &network_namespace); 270 EXPECT_TRUE(found); 271 EXPECT_EQ(kExplicitInOnlineNamespaceResponseId, entry.response_id()); 272 EXPECT_FALSE(fallback_entry.has_response_id()); 273 EXPECT_FALSE(network_namespace); 274 275 entry = AppCacheEntry(); // reset 276 277 found = cache->FindResponseForRequest(kFallbackTestUrl1, 278 &entry, &intercept_namespace, 279 &fallback_entry, &fallback_namespace, 280 &network_namespace); 281 EXPECT_TRUE(found); 282 EXPECT_FALSE(entry.has_response_id()); 283 EXPECT_EQ(kFallbackResponseId1, fallback_entry.response_id()); 284 EXPECT_EQ(kFallbackEntryUrl1, 285 cache->GetFallbackEntryUrl(fallback_namespace)); 286 EXPECT_FALSE(network_namespace); 287 288 fallback_entry = AppCacheEntry(); // reset 289 290 found = cache->FindResponseForRequest(kFallbackTestUrl2, 291 &entry, &intercept_namespace, 292 &fallback_entry, &fallback_namespace, 293 &network_namespace); 294 EXPECT_TRUE(found); 295 EXPECT_FALSE(entry.has_response_id()); 296 EXPECT_EQ(kFallbackResponseId2, fallback_entry.response_id()); 297 EXPECT_EQ(kFallbackEntryUrl2, 298 cache->GetFallbackEntryUrl(fallback_namespace)); 299 EXPECT_FALSE(network_namespace); 300 301 fallback_entry = AppCacheEntry(); // reset 302 303 found = cache->FindResponseForRequest(kOnlineNamespaceWithinOtherNamespaces, 304 &entry, &intercept_namespace, 305 &fallback_entry, &fallback_namespace, 306 &network_namespace); 307 EXPECT_TRUE(found); 308 EXPECT_FALSE(entry.has_response_id()); 309 EXPECT_FALSE(fallback_entry.has_response_id()); 310 EXPECT_TRUE(network_namespace); 311 312 fallback_entry = AppCacheEntry(); // reset 313 314 found = cache->FindResponseForRequest( 315 kOnlineNamespaceWithinOtherNamespaces.Resolve("online_resource"), 316 &entry, &intercept_namespace, 317 &fallback_entry, &fallback_namespace, 318 &network_namespace); 319 EXPECT_TRUE(found); 320 EXPECT_FALSE(entry.has_response_id()); 321 EXPECT_FALSE(fallback_entry.has_response_id()); 322 EXPECT_TRUE(network_namespace); 323 324 fallback_namespace = GURL(); 325 326 found = cache->FindResponseForRequest( 327 kInterceptNamespace.Resolve("intercept_me"), 328 &entry, &intercept_namespace, 329 &fallback_entry, &fallback_namespace, 330 &network_namespace); 331 EXPECT_TRUE(found); 332 EXPECT_EQ(kInterceptResponseId, entry.response_id()); 333 EXPECT_EQ(kInterceptNamespaceEntry, 334 cache->GetInterceptEntryUrl(intercept_namespace)); 335 EXPECT_FALSE(fallback_entry.has_response_id()); 336 EXPECT_TRUE(fallback_namespace.is_empty()); 337 EXPECT_FALSE(network_namespace); 338 339 entry = AppCacheEntry(); // reset 340 341 found = cache->FindResponseForRequest( 342 kInterceptNamespaceWithinFallback.Resolve("intercept_me"), 343 &entry, &intercept_namespace, 344 &fallback_entry, &fallback_namespace, 345 &network_namespace); 346 EXPECT_TRUE(found); 347 EXPECT_EQ(kInterceptResponseId, entry.response_id()); 348 EXPECT_EQ(kInterceptNamespaceEntry, 349 cache->GetInterceptEntryUrl(intercept_namespace)); 350 EXPECT_FALSE(fallback_entry.has_response_id()); 351 EXPECT_TRUE(fallback_namespace.is_empty()); 352 EXPECT_FALSE(network_namespace); 353 } 354 355 TEST(AppCacheTest, FindInterceptPatternResponseForRequest) { 356 MockAppCacheService service; 357 358 // Setup an appcache with an intercept namespace that uses pattern matching. 359 const GURL kInterceptNamespaceBase("http://blah/intercept_namespace/"); 360 const GURL kInterceptPatternNamespace( 361 kInterceptNamespaceBase.Resolve("*.hit*")); 362 const GURL kInterceptNamespaceEntry("http://blah/intercept_resource"); 363 const int64 kInterceptResponseId = 1; 364 Manifest manifest; 365 manifest.intercept_namespaces.push_back( 366 Namespace(INTERCEPT_NAMESPACE, kInterceptPatternNamespace, 367 kInterceptNamespaceEntry, true)); 368 scoped_refptr<AppCache> cache(new AppCache(service.storage(), 1234)); 369 cache->InitializeWithManifest(&manifest); 370 cache->AddEntry( 371 kInterceptNamespaceEntry, 372 AppCacheEntry(AppCacheEntry::INTERCEPT, kInterceptResponseId)); 373 cache->set_complete(true); 374 375 // See that the pattern match works. 376 bool found = false; 377 AppCacheEntry entry; 378 AppCacheEntry fallback_entry; 379 GURL intercept_namespace; 380 GURL fallback_namespace; 381 bool network_namespace = false; 382 383 found = cache->FindResponseForRequest( 384 GURL("http://blah/miss"), 385 &entry, &intercept_namespace, 386 &fallback_entry, &fallback_namespace, 387 &network_namespace); 388 EXPECT_FALSE(found); 389 390 found = cache->FindResponseForRequest( 391 GURL("http://blah/intercept_namespace/another_miss"), 392 &entry, &intercept_namespace, 393 &fallback_entry, &fallback_namespace, 394 &network_namespace); 395 EXPECT_FALSE(found); 396 397 found = cache->FindResponseForRequest( 398 GURL("http://blah/intercept_namespace/path.hit"), 399 &entry, &intercept_namespace, 400 &fallback_entry, &fallback_namespace, 401 &network_namespace); 402 EXPECT_TRUE(found); 403 EXPECT_EQ(kInterceptResponseId, entry.response_id()); 404 EXPECT_EQ(kInterceptNamespaceEntry, 405 cache->GetInterceptEntryUrl(intercept_namespace)); 406 EXPECT_FALSE(fallback_entry.has_response_id()); 407 EXPECT_TRUE(fallback_namespace.is_empty()); 408 EXPECT_FALSE(network_namespace); 409 410 entry = AppCacheEntry(); // reset 411 412 found = cache->FindResponseForRequest( 413 GURL("http://blah/intercept_namespace/longer/path.hit?arg=ok"), 414 &entry, &intercept_namespace, 415 &fallback_entry, &fallback_namespace, 416 &network_namespace); 417 EXPECT_TRUE(found); 418 EXPECT_EQ(kInterceptResponseId, entry.response_id()); 419 EXPECT_EQ(kInterceptNamespaceEntry, 420 cache->GetInterceptEntryUrl(intercept_namespace)); 421 EXPECT_FALSE(fallback_entry.has_response_id()); 422 EXPECT_TRUE(fallback_namespace.is_empty()); 423 EXPECT_FALSE(network_namespace); 424 } 425 426 TEST(AppCacheTest, FindFallbackPatternResponseForRequest) { 427 MockAppCacheService service; 428 429 // Setup an appcache with a fallback namespace that uses pattern matching. 430 const GURL kFallbackNamespaceBase("http://blah/fallback_namespace/"); 431 const GURL kFallbackPatternNamespace( 432 kFallbackNamespaceBase.Resolve("*.hit*")); 433 const GURL kFallbackNamespaceEntry("http://blah/fallback_resource"); 434 const int64 kFallbackResponseId = 1; 435 Manifest manifest; 436 manifest.fallback_namespaces.push_back( 437 Namespace(FALLBACK_NAMESPACE, kFallbackPatternNamespace, 438 kFallbackNamespaceEntry, true)); 439 scoped_refptr<AppCache> cache(new AppCache(service.storage(), 1234)); 440 cache->InitializeWithManifest(&manifest); 441 cache->AddEntry( 442 kFallbackNamespaceEntry, 443 AppCacheEntry(AppCacheEntry::FALLBACK, kFallbackResponseId)); 444 cache->set_complete(true); 445 446 // See that the pattern match works. 447 bool found = false; 448 AppCacheEntry entry; 449 AppCacheEntry fallback_entry; 450 GURL intercept_namespace; 451 GURL fallback_namespace; 452 bool network_namespace = false; 453 454 found = cache->FindResponseForRequest( 455 GURL("http://blah/miss"), 456 &entry, &intercept_namespace, 457 &fallback_entry, &fallback_namespace, 458 &network_namespace); 459 EXPECT_FALSE(found); 460 461 found = cache->FindResponseForRequest( 462 GURL("http://blah/fallback_namespace/another_miss"), 463 &entry, &intercept_namespace, 464 &fallback_entry, &fallback_namespace, 465 &network_namespace); 466 EXPECT_FALSE(found); 467 468 found = cache->FindResponseForRequest( 469 GURL("http://blah/fallback_namespace/path.hit"), 470 &entry, &intercept_namespace, 471 &fallback_entry, &fallback_namespace, 472 &network_namespace); 473 EXPECT_TRUE(found); 474 EXPECT_FALSE(entry.has_response_id()); 475 EXPECT_EQ(kFallbackResponseId, fallback_entry.response_id()); 476 EXPECT_EQ(kFallbackNamespaceEntry, 477 cache->GetFallbackEntryUrl(fallback_namespace)); 478 EXPECT_FALSE(network_namespace); 479 480 fallback_entry = AppCacheEntry(); 481 fallback_namespace = GURL(); 482 483 found = cache->FindResponseForRequest( 484 GURL("http://blah/fallback_namespace/longer/path.hit?arg=ok"), 485 &entry, &intercept_namespace, 486 &fallback_entry, &fallback_namespace, 487 &network_namespace); 488 EXPECT_TRUE(found); 489 EXPECT_FALSE(entry.has_response_id()); 490 EXPECT_EQ(kFallbackResponseId, fallback_entry.response_id()); 491 EXPECT_EQ(kFallbackNamespaceEntry, 492 cache->GetFallbackEntryUrl(fallback_namespace)); 493 EXPECT_TRUE(intercept_namespace.is_empty()); 494 EXPECT_FALSE(network_namespace); 495 } 496 497 498 TEST(AppCacheTest, FindNetworkNamespacePatternResponseForRequest) { 499 MockAppCacheService service; 500 501 // Setup an appcache with a network namespace that uses pattern matching. 502 const GURL kNetworkNamespaceBase("http://blah/network_namespace/"); 503 const GURL kNetworkPatternNamespace( 504 kNetworkNamespaceBase.Resolve("*.hit*")); 505 Manifest manifest; 506 manifest.online_whitelist_namespaces.push_back( 507 Namespace(NETWORK_NAMESPACE, kNetworkPatternNamespace, 508 GURL(), true)); 509 manifest.online_whitelist_all = false; 510 scoped_refptr<AppCache> cache(new AppCache(service.storage(), 1234)); 511 cache->InitializeWithManifest(&manifest); 512 cache->set_complete(true); 513 514 // See that the pattern match works. 515 bool found = false; 516 AppCacheEntry entry; 517 AppCacheEntry fallback_entry; 518 GURL intercept_namespace; 519 GURL fallback_namespace; 520 bool network_namespace = false; 521 522 found = cache->FindResponseForRequest( 523 GURL("http://blah/miss"), 524 &entry, &intercept_namespace, 525 &fallback_entry, &fallback_namespace, 526 &network_namespace); 527 EXPECT_FALSE(found); 528 529 found = cache->FindResponseForRequest( 530 GURL("http://blah/network_namespace/path.hit"), 531 &entry, &intercept_namespace, 532 &fallback_entry, &fallback_namespace, 533 &network_namespace); 534 EXPECT_TRUE(found); 535 EXPECT_TRUE(network_namespace); 536 EXPECT_FALSE(entry.has_response_id()); 537 EXPECT_FALSE(fallback_entry.has_response_id()); 538 } 539 540 TEST(AppCacheTest, ToFromDatabaseRecords) { 541 // Setup a cache with some entries. 542 const int64 kCacheId = 1234; 543 const int64 kGroupId = 4321; 544 const GURL kManifestUrl("http://foo.com/manifest"); 545 const GURL kInterceptUrl("http://foo.com/intercept.html"); 546 const GURL kFallbackUrl("http://foo.com/fallback.html"); 547 const GURL kWhitelistUrl("http://foo.com/whitelist*"); 548 const std::string kData( 549 "CACHE MANIFEST\r" 550 "CHROMIUM-INTERCEPT:\r" 551 "/intercept return /intercept.html\r" 552 "FALLBACK:\r" 553 "/ /fallback.html\r" 554 "NETWORK:\r" 555 "/whitelist* isPattern\r" 556 "*\r"); 557 MockAppCacheService service; 558 scoped_refptr<AppCacheGroup> group = 559 new AppCacheGroup(service.storage(), kManifestUrl, kGroupId); 560 scoped_refptr<AppCache> cache(new AppCache(service.storage(), kCacheId)); 561 Manifest manifest; 562 EXPECT_TRUE( 563 ParseManifest(kManifestUrl, kData.c_str(), kData.length(), manifest)); 564 cache->InitializeWithManifest(&manifest); 565 EXPECT_EQ(NETWORK_NAMESPACE, cache->online_whitelist_namespaces_[0].type); 566 EXPECT_TRUE(cache->online_whitelist_namespaces_[0].is_pattern); 567 EXPECT_EQ(kWhitelistUrl, 568 cache->online_whitelist_namespaces_[0].namespace_url); 569 cache->AddEntry( 570 kManifestUrl, 571 AppCacheEntry(AppCacheEntry::MANIFEST, 1, 1)); 572 cache->AddEntry( 573 kInterceptUrl, 574 AppCacheEntry(AppCacheEntry::INTERCEPT, 3, 3)); 575 cache->AddEntry( 576 kFallbackUrl, 577 AppCacheEntry(AppCacheEntry::FALLBACK, 2, 2)); 578 579 // Get it to produce database records and verify them. 580 AppCacheDatabase::CacheRecord cache_record; 581 std::vector<AppCacheDatabase::EntryRecord> entries; 582 std::vector<AppCacheDatabase::NamespaceRecord> intercepts; 583 std::vector<AppCacheDatabase::NamespaceRecord> fallbacks; 584 std::vector<AppCacheDatabase::OnlineWhiteListRecord> whitelists; 585 cache->ToDatabaseRecords(group.get(), 586 &cache_record, 587 &entries, 588 &intercepts, 589 &fallbacks, 590 &whitelists); 591 EXPECT_EQ(kCacheId, cache_record.cache_id); 592 EXPECT_EQ(kGroupId, cache_record.group_id); 593 EXPECT_TRUE(cache_record.online_wildcard); 594 EXPECT_EQ(1 + 2 + 3, cache_record.cache_size); 595 EXPECT_EQ(3u, entries.size()); 596 EXPECT_EQ(1u, intercepts.size()); 597 EXPECT_EQ(1u, fallbacks.size()); 598 EXPECT_EQ(1u, whitelists.size()); 599 cache = NULL; 600 601 // Create a new AppCache and populate it with those records and verify. 602 cache = new AppCache(service.storage(), kCacheId); 603 cache->InitializeWithDatabaseRecords( 604 cache_record, entries, intercepts, 605 fallbacks, whitelists); 606 EXPECT_TRUE(cache->online_whitelist_all_); 607 EXPECT_EQ(3u, cache->entries().size()); 608 EXPECT_TRUE(cache->GetEntry(kManifestUrl)); 609 EXPECT_TRUE(cache->GetEntry(kInterceptUrl)); 610 EXPECT_TRUE(cache->GetEntry(kFallbackUrl)); 611 EXPECT_EQ(kInterceptUrl, 612 cache->GetInterceptEntryUrl(GURL("http://foo.com/intercept"))); 613 EXPECT_EQ(kFallbackUrl, 614 cache->GetFallbackEntryUrl(GURL("http://foo.com/"))); 615 EXPECT_EQ(1 + 2 + 3, cache->cache_size()); 616 EXPECT_EQ(NETWORK_NAMESPACE, cache->online_whitelist_namespaces_[0].type); 617 EXPECT_TRUE(cache->online_whitelist_namespaces_[0].is_pattern); 618 EXPECT_EQ(kWhitelistUrl, 619 cache->online_whitelist_namespaces_[0].namespace_url); 620 } 621 622 TEST(AppCacheTest, IsNamespaceMatch) { 623 Namespace prefix; 624 prefix.namespace_url = GURL("http://foo.com/prefix"); 625 prefix.is_pattern = false; 626 EXPECT_TRUE(prefix.IsMatch( 627 GURL("http://foo.com/prefix_and_anothing_goes"))); 628 EXPECT_FALSE(prefix.IsMatch( 629 GURL("http://foo.com/nope"))); 630 631 Namespace bar_no_star; 632 bar_no_star.namespace_url = GURL("http://foo.com/bar"); 633 bar_no_star.is_pattern = true; 634 EXPECT_TRUE(bar_no_star.IsMatch( 635 GURL("http://foo.com/bar"))); 636 EXPECT_FALSE(bar_no_star.IsMatch( 637 GURL("http://foo.com/bar/nope"))); 638 639 Namespace bar_star; 640 bar_star.namespace_url = GURL("http://foo.com/bar/*"); 641 bar_star.is_pattern = true; 642 EXPECT_TRUE(bar_star.IsMatch( 643 GURL("http://foo.com/bar/"))); 644 EXPECT_TRUE(bar_star.IsMatch( 645 GURL("http://foo.com/bar/should_match"))); 646 EXPECT_FALSE(bar_star.IsMatch( 647 GURL("http://foo.com/not_bar/should_not_match"))); 648 649 Namespace star_bar_star; 650 star_bar_star.namespace_url = GURL("http://foo.com/*/bar/*"); 651 star_bar_star.is_pattern = true; 652 EXPECT_TRUE(star_bar_star.IsMatch( 653 GURL("http://foo.com/any/bar/should_match"))); 654 EXPECT_TRUE(star_bar_star.IsMatch( 655 GURL("http://foo.com/any/bar/"))); 656 EXPECT_FALSE(star_bar_star.IsMatch( 657 GURL("http://foo.com/any/not_bar/no_match"))); 658 659 Namespace query_star_edit; 660 query_star_edit.namespace_url = GURL("http://foo.com/query?id=*&verb=edit*"); 661 query_star_edit.is_pattern = true; 662 EXPECT_TRUE(query_star_edit.IsMatch( 663 GURL("http://foo.com/query?id=1234&verb=edit&option=blue"))); 664 EXPECT_TRUE(query_star_edit.IsMatch( 665 GURL("http://foo.com/query?id=12345&option=blue&verb=edit"))); 666 EXPECT_FALSE(query_star_edit.IsMatch( 667 GURL("http://foo.com/query?id=12345&option=blue&verb=print"))); 668 EXPECT_TRUE(query_star_edit.IsMatch( 669 GURL("http://foo.com/query?id=123&verb=print&verb=edit"))); 670 671 Namespace star_greediness; 672 star_greediness.namespace_url = GURL("http://foo.com/*/b"); 673 star_greediness.is_pattern = true; 674 EXPECT_TRUE(star_greediness.IsMatch( 675 GURL("http://foo.com/a/b"))); 676 EXPECT_TRUE(star_greediness.IsMatch( 677 GURL("http://foo.com/a/wxy/z/b"))); 678 EXPECT_TRUE(star_greediness.IsMatch( 679 GURL("http://foo.com/a/b/b"))); 680 EXPECT_TRUE(star_greediness.IsMatch( 681 GURL("http://foo.com/b/b"))); 682 EXPECT_TRUE(star_greediness.IsMatch( 683 GURL("http://foo.com/a/b/b/b/b/b"))); 684 EXPECT_TRUE(star_greediness.IsMatch( 685 GURL("http://foo.com/a/b/b/b/a/b"))); 686 EXPECT_TRUE(star_greediness.IsMatch( 687 GURL("http://foo.com/a/b/01234567890abcdef/b"))); 688 EXPECT_TRUE(star_greediness.IsMatch( 689 GURL("http://foo.com/a/b/01234567890abcdef/b01234567890abcdef/b"))); 690 EXPECT_TRUE(star_greediness.IsMatch( 691 GURL("http://foo.com/a/b/01234567890abcdef_eat_some_more_characters_" 692 "/and_even_more_for_the_heck_of_it/01234567890abcdef/b"))); 693 } 694 695 } // namespace appacache 696