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 "base/files/scoped_temp_dir.h"
6 #include "base/logging.h"
7 #include "base/run_loop.h"
8 #include "content/browser/browser_thread_impl.h"
9 #include "content/browser/fileapi/mock_url_request_delegate.h"
10 #include "content/browser/service_worker/embedded_worker_test_helper.h"
11 #include "content/browser/service_worker/service_worker_context_core.h"
12 #include "content/browser/service_worker/service_worker_controllee_request_handler.h"
13 #include "content/browser/service_worker/service_worker_provider_host.h"
14 #include "content/browser/service_worker/service_worker_registration.h"
15 #include "content/browser/service_worker/service_worker_registration.h"
16 #include "content/browser/service_worker/service_worker_url_request_job.h"
17 #include "content/browser/service_worker/service_worker_utils.h"
18 #include "content/common/resource_request_body.h"
19 #include "content/public/test/test_browser_thread_bundle.h"
20 #include "net/url_request/url_request_context.h"
21 #include "testing/gtest/include/gtest/gtest.h"
27 int kMockRenderProcessId = 1224;
28 int kMockProviderId = 1;
30 void EmptyCallback() {}
34 class ServiceWorkerControlleeRequestHandlerTest : public testing::Test {
36 ServiceWorkerControlleeRequestHandlerTest()
37 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
39 virtual void SetUp() OVERRIDE {
40 helper_.reset(new EmbeddedWorkerTestHelper(kMockRenderProcessId));
42 // A new unstored registration/version.
43 scope_ = GURL("http://host/scope/");
44 script_url_ = GURL("http://host/script.js");
45 registration_ = new ServiceWorkerRegistration(
46 scope_, 1L, context()->AsWeakPtr());
47 version_ = new ServiceWorkerVersion(
48 registration_.get(), script_url_, 1L, context()->AsWeakPtr());
51 scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
52 kMockRenderProcessId, kMockProviderId,
53 context()->AsWeakPtr(), NULL));
54 provider_host_ = host->AsWeakPtr();
55 context()->AddProviderHost(host.Pass());
57 context()->storage()->LazyInitialize(base::Bind(&EmptyCallback));
58 base::RunLoop().RunUntilIdle();
61 virtual void TearDown() OVERRIDE {
67 ServiceWorkerContextCore* context() const { return helper_->context(); }
70 TestBrowserThreadBundle browser_thread_bundle_;
71 scoped_ptr<EmbeddedWorkerTestHelper> helper_;
72 scoped_refptr<ServiceWorkerRegistration> registration_;
73 scoped_refptr<ServiceWorkerVersion> version_;
74 base::WeakPtr<ServiceWorkerProviderHost> provider_host_;
75 net::URLRequestContext url_request_context_;
76 MockURLRequestDelegate url_request_delegate_;
81 TEST_F(ServiceWorkerControlleeRequestHandlerTest, ActivateWaitingVersion) {
82 // Store a registration that is installed but not activated yet.
83 version_->SetStatus(ServiceWorkerVersion::INSTALLED);
84 registration_->SetWaitingVersion(version_.get());
85 context()->storage()->StoreRegistration(
88 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
89 base::RunLoop().RunUntilIdle();
91 // Conduct a main resource load.
92 const GURL kDocUrl("http://host/scope/doc");
93 scoped_ptr<net::URLRequest> request = url_request_context_.CreateRequest(
95 net::DEFAULT_PRIORITY,
96 &url_request_delegate_,
98 scoped_ptr<ServiceWorkerControlleeRequestHandler> handler(
99 new ServiceWorkerControlleeRequestHandler(
100 context()->AsWeakPtr(),
102 base::WeakPtr<storage::BlobStorageContext>(),
103 RESOURCE_TYPE_MAIN_FRAME,
104 scoped_refptr<ResourceRequestBody>()));
105 scoped_refptr<net::URLRequestJob> job =
106 handler->MaybeCreateJob(request.get(), NULL);
107 ServiceWorkerURLRequestJob* sw_job =
108 static_cast<ServiceWorkerURLRequestJob*>(job.get());
110 EXPECT_FALSE(sw_job->ShouldFallbackToNetwork());
111 EXPECT_FALSE(sw_job->ShouldForwardToServiceWorker());
112 EXPECT_FALSE(version_->HasControllee());
114 base::RunLoop().RunUntilIdle();
116 EXPECT_EQ(ServiceWorkerVersion::ACTIVATED,
118 EXPECT_FALSE(sw_job->ShouldFallbackToNetwork());
119 EXPECT_TRUE(sw_job->ShouldForwardToServiceWorker());
120 EXPECT_TRUE(version_->HasControllee());
122 // Navigations should trigger an update too.
124 EXPECT_TRUE(version_->update_timer_.IsRunning());
127 // Test to not regress crbug/414118.
128 TEST_F(ServiceWorkerControlleeRequestHandlerTest, DeletedProviderHost) {
129 // Store a registration so the call to FindRegistrationForDocument will read
130 // from the database.
131 version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
132 registration_->SetActiveVersion(version_.get());
133 context()->storage()->StoreRegistration(
136 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
137 base::RunLoop().RunUntilIdle();
139 registration_ = NULL;
141 // Conduct a main resource load.
142 const GURL kDocUrl("http://host/scope/doc");
143 scoped_ptr<net::URLRequest> request = url_request_context_.CreateRequest(
145 net::DEFAULT_PRIORITY,
146 &url_request_delegate_,
148 scoped_ptr<ServiceWorkerControlleeRequestHandler> handler(
149 new ServiceWorkerControlleeRequestHandler(
150 context()->AsWeakPtr(),
152 base::WeakPtr<storage::BlobStorageContext>(),
153 RESOURCE_TYPE_MAIN_FRAME,
154 scoped_refptr<ResourceRequestBody>()));
155 scoped_refptr<net::URLRequestJob> job =
156 handler->MaybeCreateJob(request.get(), NULL);
157 ServiceWorkerURLRequestJob* sw_job =
158 static_cast<ServiceWorkerURLRequestJob*>(job.get());
160 EXPECT_FALSE(sw_job->ShouldFallbackToNetwork());
161 EXPECT_FALSE(sw_job->ShouldForwardToServiceWorker());
163 // Shouldn't crash if the ProviderHost is deleted prior to completion of
164 // the database lookup.
165 context()->RemoveProviderHost(kMockRenderProcessId, kMockProviderId);
166 EXPECT_FALSE(provider_host_.get());
167 base::RunLoop().RunUntilIdle();
168 EXPECT_TRUE(sw_job->ShouldFallbackToNetwork());
169 EXPECT_FALSE(sw_job->ShouldForwardToServiceWorker());
172 } // namespace content