1 // Copyright 2014 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 "content/browser/appcache/mock_appcache_service.h"
6 #include "testing/gtest/include/gtest/gtest.h"
7 #include "webkit/browser/appcache/appcache.h"
8 #include "webkit/browser/appcache/appcache_host.h"
10 using appcache::AppCache;
11 using appcache::AppCacheDatabase;
12 using appcache::AppCacheEntry;
13 using appcache::AppCacheFrontend;
14 using appcache::AppCacheGroup;
15 using appcache::AppCacheHost;
16 using appcache::AppCacheInfo;
17 using appcache::ErrorDetails;
18 using appcache::EventID;
19 using appcache::FALLBACK_NAMESPACE;
20 using appcache::INTERCEPT_NAMESPACE;
21 using appcache::LogLevel;
22 using appcache::Manifest;
23 using appcache::Namespace;
24 using appcache::NamespaceVector;
25 using appcache::NETWORK_NAMESPACE;
26 using appcache::PARSE_MANIFEST_ALLOWING_INTERCEPTS;
27 using appcache::PARSE_MANIFEST_PER_STANDARD;
28 using appcache::Status;
34 class MockAppCacheFrontend : public AppCacheFrontend {
36 virtual void OnCacheSelected(int host_id, const AppCacheInfo& info) OVERRIDE {
38 virtual void OnStatusChanged(const std::vector<int>& host_ids,
39 Status status) OVERRIDE {}
40 virtual void OnEventRaised(const std::vector<int>& host_ids,
41 EventID event_id) OVERRIDE {}
42 virtual void OnProgressEventRaised(
43 const std::vector<int>& host_ids,
45 int num_total, int num_complete) OVERRIDE {}
46 virtual void OnErrorEventRaised(const std::vector<int>& host_ids,
47 const ErrorDetails& details) OVERRIDE {}
48 virtual void OnLogMessage(int host_id, LogLevel log_level,
49 const std::string& message) OVERRIDE {}
50 virtual void OnContentBlocked(
51 int host_id, const GURL& manifest_url) OVERRIDE {}
56 class AppCacheTest : public testing::Test {
59 TEST(AppCacheTest, CleanupUnusedCache) {
60 MockAppCacheService service;
61 MockAppCacheFrontend frontend;
62 scoped_refptr<AppCache> cache(new AppCache(service.storage(), 111));
63 cache->set_complete(true);
64 scoped_refptr<AppCacheGroup> group(
65 new AppCacheGroup(service.storage(), GURL("http://blah/manifest"), 111));
66 group->AddCache(cache.get());
68 AppCacheHost host1(1, &frontend, &service);
69 AppCacheHost host2(2, &frontend, &service);
71 host1.AssociateCompleteCache(cache.get());
72 host2.AssociateCompleteCache(cache.get());
74 host1.AssociateNoCache(GURL());
75 host2.AssociateNoCache(GURL());
78 TEST(AppCacheTest, AddModifyRemoveEntry) {
79 MockAppCacheService service;
80 scoped_refptr<AppCache> cache(new AppCache(service.storage(), 111));
82 EXPECT_TRUE(cache->entries().empty());
83 EXPECT_EQ(0L, cache->cache_size());
85 const GURL kFooUrl("http://foo.com");
86 const int64 kFooResponseId = 1;
87 const int64 kFooSize = 100;
88 AppCacheEntry entry1(AppCacheEntry::MASTER, kFooResponseId, kFooSize);
89 cache->AddEntry(kFooUrl, entry1);
90 EXPECT_EQ(entry1.types(), cache->GetEntry(kFooUrl)->types());
91 EXPECT_EQ(1UL, cache->entries().size());
92 EXPECT_EQ(kFooSize, cache->cache_size());
94 const GURL kBarUrl("http://bar.com");
95 const int64 kBarResponseId = 2;
96 const int64 kBarSize = 200;
97 AppCacheEntry entry2(AppCacheEntry::FALLBACK, kBarResponseId, kBarSize);
98 EXPECT_TRUE(cache->AddOrModifyEntry(kBarUrl, entry2));
99 EXPECT_EQ(entry2.types(), cache->GetEntry(kBarUrl)->types());
100 EXPECT_EQ(2UL, cache->entries().size());
101 EXPECT_EQ(kFooSize + kBarSize, cache->cache_size());
103 // Expected to return false when an existing entry is modified.
104 AppCacheEntry entry3(AppCacheEntry::EXPLICIT);
105 EXPECT_FALSE(cache->AddOrModifyEntry(kFooUrl, entry3));
106 EXPECT_EQ((AppCacheEntry::MASTER | AppCacheEntry::EXPLICIT),
107 cache->GetEntry(kFooUrl)->types());
108 // Only the type should be modified.
109 EXPECT_EQ(kFooResponseId, cache->GetEntry(kFooUrl)->response_id());
110 EXPECT_EQ(kFooSize, cache->GetEntry(kFooUrl)->response_size());
111 EXPECT_EQ(kFooSize + kBarSize, cache->cache_size());
113 EXPECT_EQ(entry2.types(), cache->GetEntry(kBarUrl)->types()); // unchanged
115 cache->RemoveEntry(kBarUrl);
116 EXPECT_EQ(kFooSize, cache->cache_size());
117 cache->RemoveEntry(kFooUrl);
118 EXPECT_EQ(0L, cache->cache_size());
119 EXPECT_TRUE(cache->entries().empty());
122 TEST(AppCacheTest, InitializeWithManifest) {
123 MockAppCacheService service;
125 scoped_refptr<AppCache> cache(new AppCache(service.storage(), 1234));
126 EXPECT_TRUE(cache->fallback_namespaces_.empty());
127 EXPECT_TRUE(cache->online_whitelist_namespaces_.empty());
128 EXPECT_FALSE(cache->online_whitelist_all_);
131 manifest.explicit_urls.insert("http://one.com");
132 manifest.explicit_urls.insert("http://two.com");
133 manifest.fallback_namespaces.push_back(
134 Namespace(FALLBACK_NAMESPACE, GURL("http://fb1.com"),
135 GURL("http://fbone.com"), true));
136 manifest.online_whitelist_namespaces.push_back(
137 Namespace(NETWORK_NAMESPACE, GURL("http://w1.com"), GURL(), false));
138 manifest.online_whitelist_namespaces.push_back(
139 Namespace(NETWORK_NAMESPACE, GURL("http://w2.com"), GURL(), false));
140 manifest.online_whitelist_all = true;
142 cache->InitializeWithManifest(&manifest);
143 const std::vector<Namespace>& fallbacks =
144 cache->fallback_namespaces_;
146 EXPECT_EQ(expected, fallbacks.size());
147 EXPECT_EQ(GURL("http://fb1.com"), fallbacks[0].namespace_url);
148 EXPECT_EQ(GURL("http://fbone.com"), fallbacks[0].target_url);
149 EXPECT_TRUE(fallbacks[0].is_pattern);
150 const NamespaceVector& whitelist = cache->online_whitelist_namespaces_;
152 EXPECT_EQ(expected, whitelist.size());
153 EXPECT_EQ(GURL("http://w1.com"), whitelist[0].namespace_url);
154 EXPECT_EQ(GURL("http://w2.com"), whitelist[1].namespace_url);
155 EXPECT_TRUE(cache->online_whitelist_all_);
157 // Ensure collections in manifest were taken over by the cache rather than
159 EXPECT_TRUE(manifest.fallback_namespaces.empty());
160 EXPECT_TRUE(manifest.online_whitelist_namespaces.empty());
163 TEST(AppCacheTest, FindResponseForRequest) {
164 MockAppCacheService service;
166 const GURL kOnlineNamespaceUrl("http://blah/online_namespace");
167 const GURL kFallbackEntryUrl1("http://blah/fallback_entry1");
168 const GURL kFallbackNamespaceUrl1("http://blah/fallback_namespace/");
169 const GURL kFallbackEntryUrl2("http://blah/fallback_entry2");
170 const GURL kFallbackNamespaceUrl2("http://blah/fallback_namespace/longer");
171 const GURL kManifestUrl("http://blah/manifest");
172 const GURL kForeignExplicitEntryUrl("http://blah/foreign");
173 const GURL kInOnlineNamespaceUrl(
174 "http://blah/online_namespace/network");
175 const GURL kExplicitInOnlineNamespaceUrl(
176 "http://blah/online_namespace/explicit");
177 const GURL kFallbackTestUrl1("http://blah/fallback_namespace/1");
178 const GURL kFallbackTestUrl2("http://blah/fallback_namespace/longer2");
179 const GURL kInterceptNamespace("http://blah/intercept_namespace/");
180 const GURL kInterceptNamespaceWithinFallback(
181 "http://blah/fallback_namespace/intercept_namespace/");
182 const GURL kInterceptNamespaceEntry("http://blah/intercept_entry");
183 const GURL kOnlineNamespaceWithinOtherNamespaces(
184 "http://blah/fallback_namespace/intercept_namespace/1/online");
186 const int64 kFallbackResponseId1 = 1;
187 const int64 kFallbackResponseId2 = 2;
188 const int64 kManifestResponseId = 3;
189 const int64 kForeignExplicitResponseId = 4;
190 const int64 kExplicitInOnlineNamespaceResponseId = 5;
191 const int64 kInterceptResponseId = 6;
194 manifest.online_whitelist_namespaces.push_back(
195 Namespace(NETWORK_NAMESPACE, kOnlineNamespaceUrl,
197 manifest.online_whitelist_namespaces.push_back(
198 Namespace(NETWORK_NAMESPACE, kOnlineNamespaceWithinOtherNamespaces,
200 manifest.fallback_namespaces.push_back(
201 Namespace(FALLBACK_NAMESPACE, kFallbackNamespaceUrl1,
202 kFallbackEntryUrl1, false));
203 manifest.fallback_namespaces.push_back(
204 Namespace(FALLBACK_NAMESPACE, kFallbackNamespaceUrl2,
205 kFallbackEntryUrl2, false));
206 manifest.intercept_namespaces.push_back(
207 Namespace(INTERCEPT_NAMESPACE, kInterceptNamespace,
208 kInterceptNamespaceEntry, false));
209 manifest.intercept_namespaces.push_back(
210 Namespace(INTERCEPT_NAMESPACE, kInterceptNamespaceWithinFallback,
211 kInterceptNamespaceEntry, false));
213 // Create a cache with some namespaces and entries.
214 scoped_refptr<AppCache> cache(new AppCache(service.storage(), 1234));
215 cache->InitializeWithManifest(&manifest);
218 AppCacheEntry(AppCacheEntry::FALLBACK, kFallbackResponseId1));
221 AppCacheEntry(AppCacheEntry::FALLBACK, kFallbackResponseId2));
224 AppCacheEntry(AppCacheEntry::MANIFEST, kManifestResponseId));
226 kForeignExplicitEntryUrl,
227 AppCacheEntry(AppCacheEntry::EXPLICIT | AppCacheEntry::FOREIGN,
228 kForeignExplicitResponseId));
230 kExplicitInOnlineNamespaceUrl,
231 AppCacheEntry(AppCacheEntry::EXPLICIT,
232 kExplicitInOnlineNamespaceResponseId));
234 kInterceptNamespaceEntry,
235 AppCacheEntry(AppCacheEntry::INTERCEPT, kInterceptResponseId));
236 cache->set_complete(true);
238 // See that we get expected results from FindResponseForRequest
242 AppCacheEntry fallback_entry;
243 GURL intercept_namespace;
244 GURL fallback_namespace;
245 bool network_namespace = false;
247 found = cache->FindResponseForRequest(GURL("http://blah/miss"),
248 &entry, &intercept_namespace,
249 &fallback_entry, &fallback_namespace,
253 found = cache->FindResponseForRequest(kForeignExplicitEntryUrl,
254 &entry, &intercept_namespace,
255 &fallback_entry, &fallback_namespace,
258 EXPECT_EQ(kForeignExplicitResponseId, entry.response_id());
259 EXPECT_FALSE(fallback_entry.has_response_id());
260 EXPECT_FALSE(network_namespace);
262 entry = AppCacheEntry(); // reset
264 found = cache->FindResponseForRequest(kManifestUrl,
265 &entry, &intercept_namespace,
266 &fallback_entry, &fallback_namespace,
269 EXPECT_EQ(kManifestResponseId, entry.response_id());
270 EXPECT_FALSE(fallback_entry.has_response_id());
271 EXPECT_FALSE(network_namespace);
273 entry = AppCacheEntry(); // reset
275 found = cache->FindResponseForRequest(kInOnlineNamespaceUrl,
276 &entry, &intercept_namespace,
277 &fallback_entry, &fallback_namespace,
280 EXPECT_FALSE(entry.has_response_id());
281 EXPECT_FALSE(fallback_entry.has_response_id());
282 EXPECT_TRUE(network_namespace);
284 network_namespace = false; // reset
286 found = cache->FindResponseForRequest(kExplicitInOnlineNamespaceUrl,
287 &entry, &intercept_namespace,
288 &fallback_entry, &fallback_namespace,
291 EXPECT_EQ(kExplicitInOnlineNamespaceResponseId, entry.response_id());
292 EXPECT_FALSE(fallback_entry.has_response_id());
293 EXPECT_FALSE(network_namespace);
295 entry = AppCacheEntry(); // reset
297 found = cache->FindResponseForRequest(kFallbackTestUrl1,
298 &entry, &intercept_namespace,
299 &fallback_entry, &fallback_namespace,
302 EXPECT_FALSE(entry.has_response_id());
303 EXPECT_EQ(kFallbackResponseId1, fallback_entry.response_id());
304 EXPECT_EQ(kFallbackEntryUrl1,
305 cache->GetFallbackEntryUrl(fallback_namespace));
306 EXPECT_FALSE(network_namespace);
308 fallback_entry = AppCacheEntry(); // reset
310 found = cache->FindResponseForRequest(kFallbackTestUrl2,
311 &entry, &intercept_namespace,
312 &fallback_entry, &fallback_namespace,
315 EXPECT_FALSE(entry.has_response_id());
316 EXPECT_EQ(kFallbackResponseId2, fallback_entry.response_id());
317 EXPECT_EQ(kFallbackEntryUrl2,
318 cache->GetFallbackEntryUrl(fallback_namespace));
319 EXPECT_FALSE(network_namespace);
321 fallback_entry = AppCacheEntry(); // reset
323 found = cache->FindResponseForRequest(kOnlineNamespaceWithinOtherNamespaces,
324 &entry, &intercept_namespace,
325 &fallback_entry, &fallback_namespace,
328 EXPECT_FALSE(entry.has_response_id());
329 EXPECT_FALSE(fallback_entry.has_response_id());
330 EXPECT_TRUE(network_namespace);
332 fallback_entry = AppCacheEntry(); // reset
334 found = cache->FindResponseForRequest(
335 kOnlineNamespaceWithinOtherNamespaces.Resolve("online_resource"),
336 &entry, &intercept_namespace,
337 &fallback_entry, &fallback_namespace,
340 EXPECT_FALSE(entry.has_response_id());
341 EXPECT_FALSE(fallback_entry.has_response_id());
342 EXPECT_TRUE(network_namespace);
344 fallback_namespace = GURL();
346 found = cache->FindResponseForRequest(
347 kInterceptNamespace.Resolve("intercept_me"),
348 &entry, &intercept_namespace,
349 &fallback_entry, &fallback_namespace,
352 EXPECT_EQ(kInterceptResponseId, entry.response_id());
353 EXPECT_EQ(kInterceptNamespaceEntry,
354 cache->GetInterceptEntryUrl(intercept_namespace));
355 EXPECT_FALSE(fallback_entry.has_response_id());
356 EXPECT_TRUE(fallback_namespace.is_empty());
357 EXPECT_FALSE(network_namespace);
359 entry = AppCacheEntry(); // reset
361 found = cache->FindResponseForRequest(
362 kInterceptNamespaceWithinFallback.Resolve("intercept_me"),
363 &entry, &intercept_namespace,
364 &fallback_entry, &fallback_namespace,
367 EXPECT_EQ(kInterceptResponseId, entry.response_id());
368 EXPECT_EQ(kInterceptNamespaceEntry,
369 cache->GetInterceptEntryUrl(intercept_namespace));
370 EXPECT_FALSE(fallback_entry.has_response_id());
371 EXPECT_TRUE(fallback_namespace.is_empty());
372 EXPECT_FALSE(network_namespace);
375 TEST(AppCacheTest, FindInterceptPatternResponseForRequest) {
376 MockAppCacheService service;
378 // Setup an appcache with an intercept namespace that uses pattern matching.
379 const GURL kInterceptNamespaceBase("http://blah/intercept_namespace/");
380 const GURL kInterceptPatternNamespace(
381 kInterceptNamespaceBase.Resolve("*.hit*"));
382 const GURL kInterceptNamespaceEntry("http://blah/intercept_resource");
383 const int64 kInterceptResponseId = 1;
385 manifest.intercept_namespaces.push_back(
386 Namespace(INTERCEPT_NAMESPACE, kInterceptPatternNamespace,
387 kInterceptNamespaceEntry, true));
388 scoped_refptr<AppCache> cache(new AppCache(service.storage(), 1234));
389 cache->InitializeWithManifest(&manifest);
391 kInterceptNamespaceEntry,
392 AppCacheEntry(AppCacheEntry::INTERCEPT, kInterceptResponseId));
393 cache->set_complete(true);
395 // See that the pattern match works.
398 AppCacheEntry fallback_entry;
399 GURL intercept_namespace;
400 GURL fallback_namespace;
401 bool network_namespace = false;
403 found = cache->FindResponseForRequest(
404 GURL("http://blah/miss"),
405 &entry, &intercept_namespace,
406 &fallback_entry, &fallback_namespace,
410 found = cache->FindResponseForRequest(
411 GURL("http://blah/intercept_namespace/another_miss"),
412 &entry, &intercept_namespace,
413 &fallback_entry, &fallback_namespace,
417 found = cache->FindResponseForRequest(
418 GURL("http://blah/intercept_namespace/path.hit"),
419 &entry, &intercept_namespace,
420 &fallback_entry, &fallback_namespace,
423 EXPECT_EQ(kInterceptResponseId, entry.response_id());
424 EXPECT_EQ(kInterceptNamespaceEntry,
425 cache->GetInterceptEntryUrl(intercept_namespace));
426 EXPECT_FALSE(fallback_entry.has_response_id());
427 EXPECT_TRUE(fallback_namespace.is_empty());
428 EXPECT_FALSE(network_namespace);
430 entry = AppCacheEntry(); // reset
432 found = cache->FindResponseForRequest(
433 GURL("http://blah/intercept_namespace/longer/path.hit?arg=ok"),
434 &entry, &intercept_namespace,
435 &fallback_entry, &fallback_namespace,
438 EXPECT_EQ(kInterceptResponseId, entry.response_id());
439 EXPECT_EQ(kInterceptNamespaceEntry,
440 cache->GetInterceptEntryUrl(intercept_namespace));
441 EXPECT_FALSE(fallback_entry.has_response_id());
442 EXPECT_TRUE(fallback_namespace.is_empty());
443 EXPECT_FALSE(network_namespace);
446 TEST(AppCacheTest, FindFallbackPatternResponseForRequest) {
447 MockAppCacheService service;
449 // Setup an appcache with a fallback namespace that uses pattern matching.
450 const GURL kFallbackNamespaceBase("http://blah/fallback_namespace/");
451 const GURL kFallbackPatternNamespace(
452 kFallbackNamespaceBase.Resolve("*.hit*"));
453 const GURL kFallbackNamespaceEntry("http://blah/fallback_resource");
454 const int64 kFallbackResponseId = 1;
456 manifest.fallback_namespaces.push_back(
457 Namespace(FALLBACK_NAMESPACE, kFallbackPatternNamespace,
458 kFallbackNamespaceEntry, true));
459 scoped_refptr<AppCache> cache(new AppCache(service.storage(), 1234));
460 cache->InitializeWithManifest(&manifest);
462 kFallbackNamespaceEntry,
463 AppCacheEntry(AppCacheEntry::FALLBACK, kFallbackResponseId));
464 cache->set_complete(true);
466 // See that the pattern match works.
469 AppCacheEntry fallback_entry;
470 GURL intercept_namespace;
471 GURL fallback_namespace;
472 bool network_namespace = false;
474 found = cache->FindResponseForRequest(
475 GURL("http://blah/miss"),
476 &entry, &intercept_namespace,
477 &fallback_entry, &fallback_namespace,
481 found = cache->FindResponseForRequest(
482 GURL("http://blah/fallback_namespace/another_miss"),
483 &entry, &intercept_namespace,
484 &fallback_entry, &fallback_namespace,
488 found = cache->FindResponseForRequest(
489 GURL("http://blah/fallback_namespace/path.hit"),
490 &entry, &intercept_namespace,
491 &fallback_entry, &fallback_namespace,
494 EXPECT_FALSE(entry.has_response_id());
495 EXPECT_EQ(kFallbackResponseId, fallback_entry.response_id());
496 EXPECT_EQ(kFallbackNamespaceEntry,
497 cache->GetFallbackEntryUrl(fallback_namespace));
498 EXPECT_FALSE(network_namespace);
500 fallback_entry = AppCacheEntry();
501 fallback_namespace = GURL();
503 found = cache->FindResponseForRequest(
504 GURL("http://blah/fallback_namespace/longer/path.hit?arg=ok"),
505 &entry, &intercept_namespace,
506 &fallback_entry, &fallback_namespace,
509 EXPECT_FALSE(entry.has_response_id());
510 EXPECT_EQ(kFallbackResponseId, fallback_entry.response_id());
511 EXPECT_EQ(kFallbackNamespaceEntry,
512 cache->GetFallbackEntryUrl(fallback_namespace));
513 EXPECT_TRUE(intercept_namespace.is_empty());
514 EXPECT_FALSE(network_namespace);
518 TEST(AppCacheTest, FindNetworkNamespacePatternResponseForRequest) {
519 MockAppCacheService service;
521 // Setup an appcache with a network namespace that uses pattern matching.
522 const GURL kNetworkNamespaceBase("http://blah/network_namespace/");
523 const GURL kNetworkPatternNamespace(
524 kNetworkNamespaceBase.Resolve("*.hit*"));
526 manifest.online_whitelist_namespaces.push_back(
527 Namespace(NETWORK_NAMESPACE, kNetworkPatternNamespace,
529 manifest.online_whitelist_all = false;
530 scoped_refptr<AppCache> cache(new AppCache(service.storage(), 1234));
531 cache->InitializeWithManifest(&manifest);
532 cache->set_complete(true);
534 // See that the pattern match works.
537 AppCacheEntry fallback_entry;
538 GURL intercept_namespace;
539 GURL fallback_namespace;
540 bool network_namespace = false;
542 found = cache->FindResponseForRequest(
543 GURL("http://blah/miss"),
544 &entry, &intercept_namespace,
545 &fallback_entry, &fallback_namespace,
549 found = cache->FindResponseForRequest(
550 GURL("http://blah/network_namespace/path.hit"),
551 &entry, &intercept_namespace,
552 &fallback_entry, &fallback_namespace,
555 EXPECT_TRUE(network_namespace);
556 EXPECT_FALSE(entry.has_response_id());
557 EXPECT_FALSE(fallback_entry.has_response_id());
560 TEST(AppCacheTest, ToFromDatabaseRecords) {
561 // Setup a cache with some entries.
562 const int64 kCacheId = 1234;
563 const int64 kGroupId = 4321;
564 const GURL kManifestUrl("http://foo.com/manifest");
565 const GURL kInterceptUrl("http://foo.com/intercept.html");
566 const GURL kFallbackUrl("http://foo.com/fallback.html");
567 const GURL kWhitelistUrl("http://foo.com/whitelist*");
568 const std::string kData(
570 "CHROMIUM-INTERCEPT:\r"
571 "/intercept return /intercept.html\r"
575 "/whitelist* isPattern\r"
577 MockAppCacheService service;
578 scoped_refptr<AppCacheGroup> group =
579 new AppCacheGroup(service.storage(), kManifestUrl, kGroupId);
580 scoped_refptr<AppCache> cache(new AppCache(service.storage(), kCacheId));
582 EXPECT_TRUE(ParseManifest(kManifestUrl, kData.c_str(), kData.length(),
583 PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest));
584 cache->InitializeWithManifest(&manifest);
585 EXPECT_EQ(NETWORK_NAMESPACE, cache->online_whitelist_namespaces_[0].type);
586 EXPECT_TRUE(cache->online_whitelist_namespaces_[0].is_pattern);
587 EXPECT_EQ(kWhitelistUrl,
588 cache->online_whitelist_namespaces_[0].namespace_url);
591 AppCacheEntry(AppCacheEntry::MANIFEST, 1, 1));
594 AppCacheEntry(AppCacheEntry::INTERCEPT, 3, 3));
597 AppCacheEntry(AppCacheEntry::FALLBACK, 2, 2));
599 // Get it to produce database records and verify them.
600 AppCacheDatabase::CacheRecord cache_record;
601 std::vector<AppCacheDatabase::EntryRecord> entries;
602 std::vector<AppCacheDatabase::NamespaceRecord> intercepts;
603 std::vector<AppCacheDatabase::NamespaceRecord> fallbacks;
604 std::vector<AppCacheDatabase::OnlineWhiteListRecord> whitelists;
605 cache->ToDatabaseRecords(group.get(),
611 EXPECT_EQ(kCacheId, cache_record.cache_id);
612 EXPECT_EQ(kGroupId, cache_record.group_id);
613 EXPECT_TRUE(cache_record.online_wildcard);
614 EXPECT_EQ(1 + 2 + 3, cache_record.cache_size);
615 EXPECT_EQ(3u, entries.size());
616 EXPECT_EQ(1u, intercepts.size());
617 EXPECT_EQ(1u, fallbacks.size());
618 EXPECT_EQ(1u, whitelists.size());
621 // Create a new AppCache and populate it with those records and verify.
622 cache = new AppCache(service.storage(), kCacheId);
623 cache->InitializeWithDatabaseRecords(
624 cache_record, entries, intercepts,
625 fallbacks, whitelists);
626 EXPECT_TRUE(cache->online_whitelist_all_);
627 EXPECT_EQ(3u, cache->entries().size());
628 EXPECT_TRUE(cache->GetEntry(kManifestUrl));
629 EXPECT_TRUE(cache->GetEntry(kInterceptUrl));
630 EXPECT_TRUE(cache->GetEntry(kFallbackUrl));
631 EXPECT_EQ(kInterceptUrl,
632 cache->GetInterceptEntryUrl(GURL("http://foo.com/intercept")));
633 EXPECT_EQ(kFallbackUrl,
634 cache->GetFallbackEntryUrl(GURL("http://foo.com/")));
635 EXPECT_EQ(1 + 2 + 3, cache->cache_size());
636 EXPECT_EQ(NETWORK_NAMESPACE, cache->online_whitelist_namespaces_[0].type);
637 EXPECT_TRUE(cache->online_whitelist_namespaces_[0].is_pattern);
638 EXPECT_EQ(kWhitelistUrl,
639 cache->online_whitelist_namespaces_[0].namespace_url);
642 TEST(AppCacheTest, IsNamespaceMatch) {
644 prefix.namespace_url = GURL("http://foo.com/prefix");
645 prefix.is_pattern = false;
646 EXPECT_TRUE(prefix.IsMatch(
647 GURL("http://foo.com/prefix_and_anothing_goes")));
648 EXPECT_FALSE(prefix.IsMatch(
649 GURL("http://foo.com/nope")));
651 Namespace bar_no_star;
652 bar_no_star.namespace_url = GURL("http://foo.com/bar");
653 bar_no_star.is_pattern = true;
654 EXPECT_TRUE(bar_no_star.IsMatch(
655 GURL("http://foo.com/bar")));
656 EXPECT_FALSE(bar_no_star.IsMatch(
657 GURL("http://foo.com/bar/nope")));
660 bar_star.namespace_url = GURL("http://foo.com/bar/*");
661 bar_star.is_pattern = true;
662 EXPECT_TRUE(bar_star.IsMatch(
663 GURL("http://foo.com/bar/")));
664 EXPECT_TRUE(bar_star.IsMatch(
665 GURL("http://foo.com/bar/should_match")));
666 EXPECT_FALSE(bar_star.IsMatch(
667 GURL("http://foo.com/not_bar/should_not_match")));
669 Namespace star_bar_star;
670 star_bar_star.namespace_url = GURL("http://foo.com/*/bar/*");
671 star_bar_star.is_pattern = true;
672 EXPECT_TRUE(star_bar_star.IsMatch(
673 GURL("http://foo.com/any/bar/should_match")));
674 EXPECT_TRUE(star_bar_star.IsMatch(
675 GURL("http://foo.com/any/bar/")));
676 EXPECT_FALSE(star_bar_star.IsMatch(
677 GURL("http://foo.com/any/not_bar/no_match")));
679 Namespace query_star_edit;
680 query_star_edit.namespace_url = GURL("http://foo.com/query?id=*&verb=edit*");
681 query_star_edit.is_pattern = true;
682 EXPECT_TRUE(query_star_edit.IsMatch(
683 GURL("http://foo.com/query?id=1234&verb=edit&option=blue")));
684 EXPECT_TRUE(query_star_edit.IsMatch(
685 GURL("http://foo.com/query?id=12345&option=blue&verb=edit")));
686 EXPECT_FALSE(query_star_edit.IsMatch(
687 GURL("http://foo.com/query?id=12345&option=blue&verb=print")));
688 EXPECT_TRUE(query_star_edit.IsMatch(
689 GURL("http://foo.com/query?id=123&verb=print&verb=edit")));
691 Namespace star_greediness;
692 star_greediness.namespace_url = GURL("http://foo.com/*/b");
693 star_greediness.is_pattern = true;
694 EXPECT_TRUE(star_greediness.IsMatch(
695 GURL("http://foo.com/a/b")));
696 EXPECT_TRUE(star_greediness.IsMatch(
697 GURL("http://foo.com/a/wxy/z/b")));
698 EXPECT_TRUE(star_greediness.IsMatch(
699 GURL("http://foo.com/a/b/b")));
700 EXPECT_TRUE(star_greediness.IsMatch(
701 GURL("http://foo.com/b/b")));
702 EXPECT_TRUE(star_greediness.IsMatch(
703 GURL("http://foo.com/a/b/b/b/b/b")));
704 EXPECT_TRUE(star_greediness.IsMatch(
705 GURL("http://foo.com/a/b/b/b/a/b")));
706 EXPECT_TRUE(star_greediness.IsMatch(
707 GURL("http://foo.com/a/b/01234567890abcdef/b")));
708 EXPECT_TRUE(star_greediness.IsMatch(
709 GURL("http://foo.com/a/b/01234567890abcdef/b01234567890abcdef/b")));
710 EXPECT_TRUE(star_greediness.IsMatch(
711 GURL("http://foo.com/a/b/01234567890abcdef_eat_some_more_characters_"
712 "/and_even_more_for_the_heck_of_it/01234567890abcdef/b")));
715 } // namespace content