Home | History | Annotate | Download | only in appcache
      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