Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / browser / appcache / appcache_host_unittest.cc
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.
4
5 #include "base/bind.h"
6 #include "base/bind_helpers.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/message_loop/message_loop.h"
9 #include "content/browser/appcache/appcache.h"
10 #include "content/browser/appcache/appcache_backend_impl.h"
11 #include "content/browser/appcache/appcache_group.h"
12 #include "content/browser/appcache/appcache_host.h"
13 #include "content/browser/appcache/mock_appcache_policy.h"
14 #include "content/browser/appcache/mock_appcache_service.h"
15 #include "net/url_request/url_request.h"
16 #include "storage/browser/quota/quota_manager.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 namespace content {
20
21 class AppCacheHostTest : public testing::Test {
22  public:
23   AppCacheHostTest() {
24     get_status_callback_ =
25         base::Bind(&AppCacheHostTest::GetStatusCallback,
26                    base::Unretained(this));
27     start_update_callback_ =
28         base::Bind(&AppCacheHostTest::StartUpdateCallback,
29                    base::Unretained(this));
30     swap_cache_callback_ =
31         base::Bind(&AppCacheHostTest::SwapCacheCallback,
32                    base::Unretained(this));
33   }
34
35   class MockFrontend : public AppCacheFrontend {
36    public:
37     MockFrontend()
38         : last_host_id_(-222), last_cache_id_(-222),
39           last_status_(APPCACHE_STATUS_OBSOLETE),
40           last_status_changed_(APPCACHE_STATUS_OBSOLETE),
41           last_event_id_(APPCACHE_OBSOLETE_EVENT),
42           content_blocked_(false) {
43     }
44
45     virtual void OnCacheSelected(
46         int host_id, const AppCacheInfo& info) OVERRIDE {
47       last_host_id_ = host_id;
48       last_cache_id_ = info.cache_id;
49       last_status_ = info.status;
50     }
51
52     virtual void OnStatusChanged(const std::vector<int>& host_ids,
53                                  AppCacheStatus status) OVERRIDE {
54       last_status_changed_ = status;
55     }
56
57     virtual void OnEventRaised(const std::vector<int>& host_ids,
58                                AppCacheEventID event_id) OVERRIDE {
59       last_event_id_ = event_id;
60     }
61
62     virtual void OnErrorEventRaised(
63         const std::vector<int>& host_ids,
64         const AppCacheErrorDetails& details) OVERRIDE {
65       last_event_id_ = APPCACHE_ERROR_EVENT;
66     }
67
68     virtual void OnProgressEventRaised(const std::vector<int>& host_ids,
69                                        const GURL& url,
70                                        int num_total,
71                                        int num_complete) OVERRIDE {
72       last_event_id_ = APPCACHE_PROGRESS_EVENT;
73     }
74
75     virtual void OnLogMessage(int host_id,
76                               AppCacheLogLevel log_level,
77                               const std::string& message) OVERRIDE {
78     }
79
80     virtual void OnContentBlocked(int host_id,
81                                   const GURL& manifest_url) OVERRIDE {
82       content_blocked_ = true;
83     }
84
85     int last_host_id_;
86     int64 last_cache_id_;
87     AppCacheStatus last_status_;
88     AppCacheStatus last_status_changed_;
89     AppCacheEventID last_event_id_;
90     bool content_blocked_;
91   };
92
93   class MockQuotaManagerProxy : public storage::QuotaManagerProxy {
94    public:
95     MockQuotaManagerProxy() : QuotaManagerProxy(NULL, NULL) {}
96
97     // Not needed for our tests.
98     virtual void RegisterClient(storage::QuotaClient* client) OVERRIDE {}
99     virtual void NotifyStorageAccessed(storage::QuotaClient::ID client_id,
100                                        const GURL& origin,
101                                        storage::StorageType type) OVERRIDE {}
102     virtual void NotifyStorageModified(storage::QuotaClient::ID client_id,
103                                        const GURL& origin,
104                                        storage::StorageType type,
105                                        int64 delta) OVERRIDE {}
106     virtual void SetUsageCacheEnabled(storage::QuotaClient::ID client_id,
107                                       const GURL& origin,
108                                       storage::StorageType type,
109                                       bool enabled) OVERRIDE {}
110     virtual void GetUsageAndQuota(
111         base::SequencedTaskRunner* original_task_runner,
112         const GURL& origin,
113         storage::StorageType type,
114         const GetUsageAndQuotaCallback& callback) OVERRIDE {}
115
116     virtual void NotifyOriginInUse(const GURL& origin) OVERRIDE {
117       inuse_[origin] += 1;
118     }
119
120     virtual void NotifyOriginNoLongerInUse(const GURL& origin) OVERRIDE {
121       inuse_[origin] -= 1;
122     }
123
124     int GetInUseCount(const GURL& origin) {
125       return inuse_[origin];
126     }
127
128     void reset() {
129       inuse_.clear();
130     }
131
132     // Map from origin to count of inuse notifications.
133     std::map<GURL, int> inuse_;
134
135    protected:
136     virtual ~MockQuotaManagerProxy() {}
137   };
138
139   void GetStatusCallback(AppCacheStatus status, void* param) {
140     last_status_result_ = status;
141     last_callback_param_ = param;
142   }
143
144   void StartUpdateCallback(bool result, void* param) {
145     last_start_result_ = result;
146     last_callback_param_ = param;
147   }
148
149   void SwapCacheCallback(bool result, void* param) {
150     last_swap_result_ = result;
151     last_callback_param_ = param;
152   }
153
154   base::MessageLoop message_loop_;
155
156   // Mock classes for the 'host' to work with
157   MockAppCacheService service_;
158   MockFrontend mock_frontend_;
159
160   // Mock callbacks we expect to receive from the 'host'
161   content::GetStatusCallback get_status_callback_;
162   content::StartUpdateCallback start_update_callback_;
163   content::SwapCacheCallback swap_cache_callback_;
164
165   AppCacheStatus last_status_result_;
166   bool last_swap_result_;
167   bool last_start_result_;
168   void* last_callback_param_;
169 };
170
171 TEST_F(AppCacheHostTest, Basic) {
172   // Construct a host and test what state it appears to be in.
173   AppCacheHost host(1, &mock_frontend_, &service_);
174   EXPECT_EQ(1, host.host_id());
175   EXPECT_EQ(&service_, host.service());
176   EXPECT_EQ(&mock_frontend_, host.frontend());
177   EXPECT_EQ(NULL, host.associated_cache());
178   EXPECT_FALSE(host.is_selection_pending());
179
180   // See that the callbacks are delivered immediately
181   // and respond as if there is no cache selected.
182   last_status_result_ = APPCACHE_STATUS_OBSOLETE;
183   host.GetStatusWithCallback(get_status_callback_, reinterpret_cast<void*>(1));
184   EXPECT_EQ(APPCACHE_STATUS_UNCACHED, last_status_result_);
185   EXPECT_EQ(reinterpret_cast<void*>(1), last_callback_param_);
186
187   last_start_result_ = true;
188   host.StartUpdateWithCallback(start_update_callback_,
189                                reinterpret_cast<void*>(2));
190   EXPECT_FALSE(last_start_result_);
191   EXPECT_EQ(reinterpret_cast<void*>(2), last_callback_param_);
192
193   last_swap_result_ = true;
194   host.SwapCacheWithCallback(swap_cache_callback_, reinterpret_cast<void*>(3));
195   EXPECT_FALSE(last_swap_result_);
196   EXPECT_EQ(reinterpret_cast<void*>(3), last_callback_param_);
197 }
198
199 TEST_F(AppCacheHostTest, SelectNoCache) {
200   scoped_refptr<MockQuotaManagerProxy> mock_quota_proxy(
201       new MockQuotaManagerProxy);
202   service_.set_quota_manager_proxy(mock_quota_proxy.get());
203
204   // Reset our mock frontend
205   mock_frontend_.last_cache_id_ = -333;
206   mock_frontend_.last_host_id_ = -333;
207   mock_frontend_.last_status_ = APPCACHE_STATUS_OBSOLETE;
208
209   const GURL kDocAndOriginUrl(GURL("http://whatever/").GetOrigin());
210   {
211     AppCacheHost host(1, &mock_frontend_, &service_);
212     host.SelectCache(kDocAndOriginUrl, kAppCacheNoCacheId, GURL());
213     EXPECT_EQ(1, mock_quota_proxy->GetInUseCount(kDocAndOriginUrl));
214
215     // We should have received an OnCacheSelected msg
216     EXPECT_EQ(1, mock_frontend_.last_host_id_);
217     EXPECT_EQ(kAppCacheNoCacheId, mock_frontend_.last_cache_id_);
218     EXPECT_EQ(APPCACHE_STATUS_UNCACHED, mock_frontend_.last_status_);
219
220     // Otherwise, see that it respond as if there is no cache selected.
221     EXPECT_EQ(1, host.host_id());
222     EXPECT_EQ(&service_, host.service());
223     EXPECT_EQ(&mock_frontend_, host.frontend());
224     EXPECT_EQ(NULL, host.associated_cache());
225     EXPECT_FALSE(host.is_selection_pending());
226     EXPECT_TRUE(host.preferred_manifest_url().is_empty());
227   }
228   EXPECT_EQ(0, mock_quota_proxy->GetInUseCount(kDocAndOriginUrl));
229   service_.set_quota_manager_proxy(NULL);
230 }
231
232 TEST_F(AppCacheHostTest, ForeignEntry) {
233   // Reset our mock frontend
234   mock_frontend_.last_cache_id_ = -333;
235   mock_frontend_.last_host_id_ = -333;
236   mock_frontend_.last_status_ = APPCACHE_STATUS_OBSOLETE;
237
238   // Precondition, a cache with an entry that is not marked as foreign.
239   const int kCacheId = 22;
240   const GURL kDocumentURL("http://origin/document");
241   scoped_refptr<AppCache> cache = new AppCache(service_.storage(), kCacheId);
242   cache->AddEntry(kDocumentURL, AppCacheEntry(AppCacheEntry::EXPLICIT));
243
244   AppCacheHost host(1, &mock_frontend_, &service_);
245   host.MarkAsForeignEntry(kDocumentURL, kCacheId);
246
247   // We should have received an OnCacheSelected msg for kAppCacheNoCacheId.
248   EXPECT_EQ(1, mock_frontend_.last_host_id_);
249   EXPECT_EQ(kAppCacheNoCacheId, mock_frontend_.last_cache_id_);
250   EXPECT_EQ(APPCACHE_STATUS_UNCACHED, mock_frontend_.last_status_);
251
252   // See that it respond as if there is no cache selected.
253   EXPECT_EQ(1, host.host_id());
254   EXPECT_EQ(&service_, host.service());
255   EXPECT_EQ(&mock_frontend_, host.frontend());
256   EXPECT_EQ(NULL, host.associated_cache());
257   EXPECT_FALSE(host.is_selection_pending());
258
259   // See that the entry was marked as foreign.
260   EXPECT_TRUE(cache->GetEntry(kDocumentURL)->IsForeign());
261 }
262
263 TEST_F(AppCacheHostTest, ForeignFallbackEntry) {
264   // Reset our mock frontend
265   mock_frontend_.last_cache_id_ = -333;
266   mock_frontend_.last_host_id_ = -333;
267   mock_frontend_.last_status_ = APPCACHE_STATUS_OBSOLETE;
268
269   // Precondition, a cache with a fallback entry that is not marked as foreign.
270   const int kCacheId = 22;
271   const GURL kFallbackURL("http://origin/fallback_resource");
272   scoped_refptr<AppCache> cache = new AppCache(service_.storage(), kCacheId);
273   cache->AddEntry(kFallbackURL, AppCacheEntry(AppCacheEntry::FALLBACK));
274
275   AppCacheHost host(1, &mock_frontend_, &service_);
276   host.NotifyMainResourceIsNamespaceEntry(kFallbackURL);
277   host.MarkAsForeignEntry(GURL("http://origin/missing_document"), kCacheId);
278
279   // We should have received an OnCacheSelected msg for kAppCacheNoCacheId.
280   EXPECT_EQ(1, mock_frontend_.last_host_id_);
281   EXPECT_EQ(kAppCacheNoCacheId, mock_frontend_.last_cache_id_);
282   EXPECT_EQ(APPCACHE_STATUS_UNCACHED, mock_frontend_.last_status_);
283
284   // See that the fallback entry was marked as foreign.
285   EXPECT_TRUE(cache->GetEntry(kFallbackURL)->IsForeign());
286 }
287
288 TEST_F(AppCacheHostTest, FailedCacheLoad) {
289   // Reset our mock frontend
290   mock_frontend_.last_cache_id_ = -333;
291   mock_frontend_.last_host_id_ = -333;
292   mock_frontend_.last_status_ = APPCACHE_STATUS_OBSOLETE;
293
294   AppCacheHost host(1, &mock_frontend_, &service_);
295   EXPECT_FALSE(host.is_selection_pending());
296
297   const int kMockCacheId = 333;
298
299   // Put it in a state where we're waiting on a cache
300   // load prior to finishing cache selection.
301   host.pending_selected_cache_id_ = kMockCacheId;
302   EXPECT_TRUE(host.is_selection_pending());
303
304   // The callback should not occur until we finish cache selection.
305   last_status_result_ = APPCACHE_STATUS_OBSOLETE;
306   last_callback_param_ = reinterpret_cast<void*>(-1);
307   host.GetStatusWithCallback(get_status_callback_, reinterpret_cast<void*>(1));
308   EXPECT_EQ(APPCACHE_STATUS_OBSOLETE, last_status_result_);
309   EXPECT_EQ(reinterpret_cast<void*>(-1), last_callback_param_);
310
311   // Satisfy the load with NULL, a failure.
312   host.OnCacheLoaded(NULL, kMockCacheId);
313
314   // Cache selection should have finished
315   EXPECT_FALSE(host.is_selection_pending());
316   EXPECT_EQ(1, mock_frontend_.last_host_id_);
317   EXPECT_EQ(kAppCacheNoCacheId, mock_frontend_.last_cache_id_);
318   EXPECT_EQ(APPCACHE_STATUS_UNCACHED, mock_frontend_.last_status_);
319
320   // Callback should have fired upon completing the cache load too.
321   EXPECT_EQ(APPCACHE_STATUS_UNCACHED, last_status_result_);
322   EXPECT_EQ(reinterpret_cast<void*>(1), last_callback_param_);
323 }
324
325 TEST_F(AppCacheHostTest, FailedGroupLoad) {
326   AppCacheHost host(1, &mock_frontend_, &service_);
327
328   const GURL kMockManifestUrl("http://foo.bar/baz");
329
330   // Put it in a state where we're waiting on a cache
331   // load prior to finishing cache selection.
332   host.pending_selected_manifest_url_ = kMockManifestUrl;
333   EXPECT_TRUE(host.is_selection_pending());
334
335   // The callback should not occur until we finish cache selection.
336   last_status_result_ = APPCACHE_STATUS_OBSOLETE;
337   last_callback_param_ = reinterpret_cast<void*>(-1);
338   host.GetStatusWithCallback(get_status_callback_, reinterpret_cast<void*>(1));
339   EXPECT_EQ(APPCACHE_STATUS_OBSOLETE, last_status_result_);
340   EXPECT_EQ(reinterpret_cast<void*>(-1), last_callback_param_);
341
342   // Satisfy the load will NULL, a failure.
343   host.OnGroupLoaded(NULL, kMockManifestUrl);
344
345   // Cache selection should have finished
346   EXPECT_FALSE(host.is_selection_pending());
347   EXPECT_EQ(1, mock_frontend_.last_host_id_);
348   EXPECT_EQ(kAppCacheNoCacheId, mock_frontend_.last_cache_id_);
349   EXPECT_EQ(APPCACHE_STATUS_UNCACHED, mock_frontend_.last_status_);
350
351   // Callback should have fired upon completing the group load.
352   EXPECT_EQ(APPCACHE_STATUS_UNCACHED, last_status_result_);
353   EXPECT_EQ(reinterpret_cast<void*>(1), last_callback_param_);
354 }
355
356 TEST_F(AppCacheHostTest, SetSwappableCache) {
357   AppCacheHost host(1, &mock_frontend_, &service_);
358   host.SetSwappableCache(NULL);
359   EXPECT_FALSE(host.swappable_cache_.get());
360
361   scoped_refptr<AppCacheGroup> group1(new AppCacheGroup(
362       service_.storage(), GURL(), service_.storage()->NewGroupId()));
363   host.SetSwappableCache(group1.get());
364   EXPECT_FALSE(host.swappable_cache_.get());
365
366   AppCache* cache1 = new AppCache(service_.storage(), 111);
367   cache1->set_complete(true);
368   group1->AddCache(cache1);
369   host.SetSwappableCache(group1.get());
370   EXPECT_EQ(cache1, host.swappable_cache_.get());
371
372   mock_frontend_.last_host_id_ = -222;  // to verify we received OnCacheSelected
373
374   host.AssociateCompleteCache(cache1);
375   EXPECT_FALSE(host.swappable_cache_.get());  // was same as associated cache
376   EXPECT_EQ(APPCACHE_STATUS_IDLE, host.GetStatus());
377   // verify OnCacheSelected was called
378   EXPECT_EQ(host.host_id(), mock_frontend_.last_host_id_);
379   EXPECT_EQ(cache1->cache_id(), mock_frontend_.last_cache_id_);
380   EXPECT_EQ(APPCACHE_STATUS_IDLE, mock_frontend_.last_status_);
381
382   AppCache* cache2 = new AppCache(service_.storage(), 222);
383   cache2->set_complete(true);
384   group1->AddCache(cache2);
385   EXPECT_EQ(cache2, host.swappable_cache_.get());  // updated to newest
386
387   scoped_refptr<AppCacheGroup> group2(
388       new AppCacheGroup(service_.storage(), GURL("http://foo.com"),
389                         service_.storage()->NewGroupId()));
390   AppCache* cache3 = new AppCache(service_.storage(), 333);
391   cache3->set_complete(true);
392   group2->AddCache(cache3);
393
394   AppCache* cache4 = new AppCache(service_.storage(), 444);
395   cache4->set_complete(true);
396   group2->AddCache(cache4);
397   EXPECT_EQ(cache2, host.swappable_cache_.get());  // unchanged
398
399   host.AssociateCompleteCache(cache3);
400   EXPECT_EQ(cache4, host.swappable_cache_.get());  // newest cache in group2
401   EXPECT_FALSE(group1->HasCache());  // both caches in group1 have refcount 0
402
403   host.AssociateNoCache(GURL());
404   EXPECT_FALSE(host.swappable_cache_.get());
405   EXPECT_FALSE(group2->HasCache());  // both caches in group2 have refcount 0
406
407   // Host adds reference to newest cache when an update is complete.
408   AppCache* cache5 = new AppCache(service_.storage(), 555);
409   cache5->set_complete(true);
410   group2->AddCache(cache5);
411   host.group_being_updated_ = group2;
412   host.OnUpdateComplete(group2.get());
413   EXPECT_FALSE(host.group_being_updated_.get());
414   EXPECT_EQ(cache5, host.swappable_cache_.get());
415
416   group2->RemoveCache(cache5);
417   EXPECT_FALSE(group2->HasCache());
418   host.group_being_updated_ = group2;
419   host.OnUpdateComplete(group2.get());
420   EXPECT_FALSE(host.group_being_updated_.get());
421   EXPECT_FALSE(host.swappable_cache_.get());  // group2 had no newest cache
422 }
423
424 TEST_F(AppCacheHostTest, ForDedicatedWorker) {
425   const int kMockProcessId = 1;
426   const int kParentHostId = 1;
427   const int kWorkerHostId = 2;
428
429   AppCacheBackendImpl backend_impl;
430   backend_impl.Initialize(&service_, &mock_frontend_, kMockProcessId);
431   backend_impl.RegisterHost(kParentHostId);
432   backend_impl.RegisterHost(kWorkerHostId);
433
434   AppCacheHost* parent_host = backend_impl.GetHost(kParentHostId);
435   EXPECT_FALSE(parent_host->is_for_dedicated_worker());
436
437   AppCacheHost* worker_host = backend_impl.GetHost(kWorkerHostId);
438   worker_host->SelectCacheForWorker(kParentHostId, kMockProcessId);
439   EXPECT_TRUE(worker_host->is_for_dedicated_worker());
440   EXPECT_EQ(parent_host, worker_host->GetParentAppCacheHost());
441
442   // We should have received an OnCacheSelected msg for the worker_host.
443   // The host for workers always indicates 'no cache selected' regardless
444   // of its parent's state. This is OK because the worker cannot access
445   // the scriptable interface, the only function available is resource
446   // loading (see appcache_request_handler_unittests those tests).
447   EXPECT_EQ(kWorkerHostId, mock_frontend_.last_host_id_);
448   EXPECT_EQ(kAppCacheNoCacheId, mock_frontend_.last_cache_id_);
449   EXPECT_EQ(APPCACHE_STATUS_UNCACHED, mock_frontend_.last_status_);
450
451   // Simulate the parent being torn down.
452   backend_impl.UnregisterHost(kParentHostId);
453   parent_host = NULL;
454   EXPECT_EQ(NULL, backend_impl.GetHost(kParentHostId));
455   EXPECT_EQ(NULL, worker_host->GetParentAppCacheHost());
456 }
457
458 TEST_F(AppCacheHostTest, SelectCacheAllowed) {
459   scoped_refptr<MockQuotaManagerProxy> mock_quota_proxy(
460       new MockQuotaManagerProxy);
461   MockAppCachePolicy mock_appcache_policy;
462   mock_appcache_policy.can_create_return_value_ = true;
463   service_.set_quota_manager_proxy(mock_quota_proxy.get());
464   service_.set_appcache_policy(&mock_appcache_policy);
465
466   // Reset our mock frontend
467   mock_frontend_.last_cache_id_ = -333;
468   mock_frontend_.last_host_id_ = -333;
469   mock_frontend_.last_status_ = APPCACHE_STATUS_OBSOLETE;
470   mock_frontend_.last_event_id_ = APPCACHE_OBSOLETE_EVENT;
471   mock_frontend_.content_blocked_ = false;
472
473   const GURL kDocAndOriginUrl(GURL("http://whatever/").GetOrigin());
474   const GURL kManifestUrl(GURL("http://whatever/cache.manifest"));
475   {
476     AppCacheHost host(1, &mock_frontend_, &service_);
477     host.first_party_url_ = kDocAndOriginUrl;
478     host.SelectCache(kDocAndOriginUrl, kAppCacheNoCacheId, kManifestUrl);
479     EXPECT_EQ(1, mock_quota_proxy->GetInUseCount(kDocAndOriginUrl));
480
481     // MockAppCacheService::LoadOrCreateGroup is asynchronous, so we shouldn't
482     // have received an OnCacheSelected msg yet.
483     EXPECT_EQ(-333, mock_frontend_.last_host_id_);
484     EXPECT_EQ(-333, mock_frontend_.last_cache_id_);
485     EXPECT_EQ(APPCACHE_STATUS_OBSOLETE, mock_frontend_.last_status_);
486     // No error events either
487     EXPECT_EQ(APPCACHE_OBSOLETE_EVENT, mock_frontend_.last_event_id_);
488     EXPECT_FALSE(mock_frontend_.content_blocked_);
489
490     EXPECT_TRUE(host.is_selection_pending());
491   }
492   EXPECT_EQ(0, mock_quota_proxy->GetInUseCount(kDocAndOriginUrl));
493   service_.set_quota_manager_proxy(NULL);
494 }
495
496 TEST_F(AppCacheHostTest, SelectCacheBlocked) {
497   scoped_refptr<MockQuotaManagerProxy> mock_quota_proxy(
498       new MockQuotaManagerProxy);
499   MockAppCachePolicy mock_appcache_policy;
500   mock_appcache_policy.can_create_return_value_ = false;
501   service_.set_quota_manager_proxy(mock_quota_proxy.get());
502   service_.set_appcache_policy(&mock_appcache_policy);
503
504   // Reset our mock frontend
505   mock_frontend_.last_cache_id_ = -333;
506   mock_frontend_.last_host_id_ = -333;
507   mock_frontend_.last_status_ = APPCACHE_STATUS_OBSOLETE;
508   mock_frontend_.last_event_id_ = APPCACHE_OBSOLETE_EVENT;
509   mock_frontend_.content_blocked_ = false;
510
511   const GURL kDocAndOriginUrl(GURL("http://whatever/").GetOrigin());
512   const GURL kManifestUrl(GURL("http://whatever/cache.manifest"));
513   {
514     AppCacheHost host(1, &mock_frontend_, &service_);
515     host.first_party_url_ = kDocAndOriginUrl;
516     host.SelectCache(kDocAndOriginUrl, kAppCacheNoCacheId, kManifestUrl);
517     EXPECT_EQ(1, mock_quota_proxy->GetInUseCount(kDocAndOriginUrl));
518
519     // We should have received an OnCacheSelected msg
520     EXPECT_EQ(1, mock_frontend_.last_host_id_);
521     EXPECT_EQ(kAppCacheNoCacheId, mock_frontend_.last_cache_id_);
522     EXPECT_EQ(APPCACHE_STATUS_UNCACHED, mock_frontend_.last_status_);
523
524     // Also, an error event was raised
525     EXPECT_EQ(APPCACHE_ERROR_EVENT, mock_frontend_.last_event_id_);
526     EXPECT_TRUE(mock_frontend_.content_blocked_);
527
528     // Otherwise, see that it respond as if there is no cache selected.
529     EXPECT_EQ(1, host.host_id());
530     EXPECT_EQ(&service_, host.service());
531     EXPECT_EQ(&mock_frontend_, host.frontend());
532     EXPECT_EQ(NULL, host.associated_cache());
533     EXPECT_FALSE(host.is_selection_pending());
534     EXPECT_TRUE(host.preferred_manifest_url().is_empty());
535   }
536   EXPECT_EQ(0, mock_quota_proxy->GetInUseCount(kDocAndOriginUrl));
537   service_.set_quota_manager_proxy(NULL);
538 }
539
540 }  // namespace content