Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / content / browser / service_worker / service_worker_write_to_cache_job_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/run_loop.h"
6 #include "content/browser/fileapi/mock_url_request_delegate.h"
7 #include "content/browser/service_worker/embedded_worker_test_helper.h"
8 #include "content/browser/service_worker/service_worker_context_core.h"
9 #include "content/browser/service_worker/service_worker_context_request_handler.h"
10 #include "content/browser/service_worker/service_worker_provider_host.h"
11 #include "content/browser/service_worker/service_worker_registration.h"
12 #include "content/browser/service_worker/service_worker_utils.h"
13 #include "content/common/resource_request_body.h"
14 #include "content/public/test/mock_resource_context.h"
15 #include "content/public/test/test_browser_thread_bundle.h"
16 #include "net/base/load_flags.h"
17 #include "net/http/http_response_headers.h"
18 #include "net/url_request/url_request_context.h"
19 #include "net/url_request/url_request_job_factory_impl.h"
20 #include "net/url_request/url_request_test_job.h"
21 #include "net/url_request/url_request_test_util.h"
22 #include "storage/browser/blob/blob_storage_context.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24
25 namespace content {
26
27 namespace {
28
29 int kMockRenderProcessId = 1224;
30 int kMockProviderId = 1;
31 const char kHeaders[] =
32     "HTTP/1.1 200 OK\0"
33     "Content-Type: text/javascript\0"
34     "Expires: Thu, 1 Jan 2100 20:00:00 GMT\0"
35     "\0";
36 const char kScriptCode[] = "// no script code\n";
37
38 void EmptyCallback() {
39 }
40
41 net::URLRequestJob* CreateNormalURLRequestJob(
42     net::URLRequest* request,
43     net::NetworkDelegate* network_delegate) {
44   return new net::URLRequestTestJob(request,
45                                     network_delegate,
46                                     std::string(kHeaders, arraysize(kHeaders)),
47                                     kScriptCode,
48                                     true);
49 }
50
51 net::URLRequestJob* CreateInvalidMimeTypeJob(
52     net::URLRequest* request,
53     net::NetworkDelegate* network_delegate) {
54   const char kPlainTextHeaders[] =
55       "HTTP/1.1 200 OK\0"
56       "Content-Type: text/plain\0"
57       "Expires: Thu, 1 Jan 2100 20:00:00 GMT\0"
58       "\0";
59   return new net::URLRequestTestJob(
60       request,
61       network_delegate,
62       std::string(kPlainTextHeaders, arraysize(kPlainTextHeaders)),
63       kScriptCode,
64       true);
65 }
66
67 class SSLCertificateErrorJob : public net::URLRequestTestJob {
68  public:
69   SSLCertificateErrorJob(net::URLRequest* request,
70                          net::NetworkDelegate* network_delegate,
71                          const std::string& response_headers,
72                          const std::string& response_data,
73                          bool auto_advance)
74       : net::URLRequestTestJob(request,
75                                network_delegate,
76                                response_headers,
77                                response_data,
78                                auto_advance),
79         weak_factory_(this) {}
80   void Start() override {
81     base::MessageLoop::current()->PostTask(
82         FROM_HERE,
83         base::Bind(&SSLCertificateErrorJob::NotifyError,
84                    weak_factory_.GetWeakPtr()));
85   }
86   void NotifyError() {
87     net::SSLInfo info;
88     info.cert_status = net::CERT_STATUS_DATE_INVALID;
89     NotifySSLCertificateError(info, true);
90   }
91
92  protected:
93   ~SSLCertificateErrorJob() override {}
94   base::WeakPtrFactory<SSLCertificateErrorJob> weak_factory_;
95 };
96
97 net::URLRequestJob* CreateSSLCertificateErrorJob(
98     net::URLRequest* request,
99     net::NetworkDelegate* network_delegate) {
100   return new SSLCertificateErrorJob(request,
101                                     network_delegate,
102                                     std::string(kHeaders, arraysize(kHeaders)),
103                                     kScriptCode,
104                                     true);
105 }
106
107 class CertStatusErrorJob : public net::URLRequestTestJob {
108  public:
109   CertStatusErrorJob(net::URLRequest* request,
110                      net::NetworkDelegate* network_delegate,
111                      const std::string& response_headers,
112                      const std::string& response_data,
113                      bool auto_advance)
114       : net::URLRequestTestJob(request,
115                                network_delegate,
116                                response_headers,
117                                response_data,
118                                auto_advance) {}
119   void GetResponseInfo(net::HttpResponseInfo* info) override {
120     URLRequestTestJob::GetResponseInfo(info);
121     info->ssl_info.cert_status = net::CERT_STATUS_DATE_INVALID;
122   }
123
124  protected:
125   ~CertStatusErrorJob() override {}
126 };
127
128 net::URLRequestJob* CreateCertStatusErrorJob(
129     net::URLRequest* request,
130     net::NetworkDelegate* network_delegate) {
131   return new CertStatusErrorJob(request,
132                                 network_delegate,
133                                 std::string(kHeaders, arraysize(kHeaders)),
134                                 kScriptCode,
135                                 true);
136 }
137
138 class MockHttpProtocolHandler
139     : public net::URLRequestJobFactory::ProtocolHandler {
140  public:
141   typedef base::Callback<
142       net::URLRequestJob*(net::URLRequest*, net::NetworkDelegate*)> JobCallback;
143
144   MockHttpProtocolHandler(ResourceContext* resource_context)
145       : resource_context_(resource_context) {}
146   ~MockHttpProtocolHandler() override {}
147
148   net::URLRequestJob* MaybeCreateJob(
149       net::URLRequest* request,
150       net::NetworkDelegate* network_delegate) const override {
151     ServiceWorkerRequestHandler* handler =
152         ServiceWorkerRequestHandler::GetHandler(request);
153     if (handler) {
154       return handler->MaybeCreateJob(
155           request, network_delegate, resource_context_);
156     }
157     return create_job_callback_.Run(request, network_delegate);
158   }
159   void SetCreateJobCallback(const JobCallback& callback) {
160     create_job_callback_ = callback;
161   }
162
163  private:
164   ResourceContext* resource_context_;
165   JobCallback create_job_callback_;
166 };
167 }
168
169 class ServiceWorkerWriteToCacheJobTest : public testing::Test {
170  public:
171   ServiceWorkerWriteToCacheJobTest()
172       : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
173         mock_protocol_handler_(NULL) {}
174   ~ServiceWorkerWriteToCacheJobTest() override {}
175
176   void SetUp() override {
177     helper_.reset(new EmbeddedWorkerTestHelper(kMockRenderProcessId));
178
179     // A new unstored registration/version.
180     scope_ = GURL("https://host/scope/");
181     script_url_ = GURL("https://host/script.js");
182     registration_ =
183         new ServiceWorkerRegistration(scope_, 1L, context()->AsWeakPtr());
184     version_ = new ServiceWorkerVersion(
185         registration_.get(), script_url_, 1L, context()->AsWeakPtr());
186
187     // An empty host.
188     scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
189         kMockRenderProcessId, kMockProviderId, context()->AsWeakPtr(), NULL));
190     provider_host_ = host->AsWeakPtr();
191     context()->AddProviderHost(host.Pass());
192     provider_host_->running_hosted_version_ = version_;
193
194     context()->storage()->LazyInitialize(base::Bind(&EmptyCallback));
195     base::RunLoop().RunUntilIdle();
196
197     url_request_context_.reset(new net::URLRequestContext);
198     mock_protocol_handler_ = new MockHttpProtocolHandler(&resource_context_);
199     url_request_job_factory_.reset(new net::URLRequestJobFactoryImpl);
200     url_request_job_factory_->SetProtocolHandler("https",
201                                                  mock_protocol_handler_);
202     url_request_context_->set_job_factory(url_request_job_factory_.get());
203
204     request_ = url_request_context_->CreateRequest(
205         script_url_, net::DEFAULT_PRIORITY, &url_request_delegate_, NULL);
206     ServiceWorkerRequestHandler::InitializeHandler(
207         request_.get(),
208         context_wrapper(),
209         &blob_storage_context_,
210         kMockRenderProcessId,
211         kMockProviderId,
212         false,
213         FETCH_REQUEST_MODE_NO_CORS,
214         FETCH_CREDENTIALS_MODE_OMIT,
215         RESOURCE_TYPE_SERVICE_WORKER,
216         REQUEST_CONTEXT_TYPE_SERVICE_WORKER,
217         REQUEST_CONTEXT_FRAME_TYPE_NONE,
218         scoped_refptr<ResourceRequestBody>());
219   }
220
221   void TearDown() override {
222     request_.reset();
223     url_request_context_.reset();
224     url_request_job_factory_.reset();
225     mock_protocol_handler_ = NULL;
226     version_ = NULL;
227     registration_ = NULL;
228     helper_.reset();
229     // URLRequestJobs may post clean-up tasks on destruction.
230     base::RunLoop().RunUntilIdle();
231   }
232
233   ServiceWorkerContextCore* context() const { return helper_->context(); }
234   ServiceWorkerContextWrapper* context_wrapper() const {
235     return helper_->context_wrapper();
236   }
237
238  protected:
239   TestBrowserThreadBundle browser_thread_bundle_;
240   scoped_ptr<EmbeddedWorkerTestHelper> helper_;
241   scoped_refptr<ServiceWorkerRegistration> registration_;
242   scoped_refptr<ServiceWorkerVersion> version_;
243   base::WeakPtr<ServiceWorkerProviderHost> provider_host_;
244   scoped_ptr<net::URLRequestContext> url_request_context_;
245   scoped_ptr<net::URLRequestJobFactoryImpl> url_request_job_factory_;
246   scoped_ptr<net::URLRequest> request_;
247   MockHttpProtocolHandler* mock_protocol_handler_;
248
249   storage::BlobStorageContext blob_storage_context_;
250   content::MockResourceContext resource_context_;
251
252   MockURLRequestDelegate url_request_delegate_;
253   GURL scope_;
254   GURL script_url_;
255 };
256
257 TEST_F(ServiceWorkerWriteToCacheJobTest, Normal) {
258   mock_protocol_handler_->SetCreateJobCallback(
259       base::Bind(&CreateNormalURLRequestJob));
260   request_->Start();
261   base::RunLoop().RunUntilIdle();
262   EXPECT_EQ(net::URLRequestStatus::SUCCESS, request_->status().status());
263   EXPECT_NE(kInvalidServiceWorkerResponseId,
264             version_->script_cache_map()->LookupResourceId(script_url_));
265 }
266
267 TEST_F(ServiceWorkerWriteToCacheJobTest, InvalidMimeType) {
268   mock_protocol_handler_->SetCreateJobCallback(
269       base::Bind(&CreateInvalidMimeTypeJob));
270   request_->Start();
271   base::RunLoop().RunUntilIdle();
272   EXPECT_EQ(net::URLRequestStatus::FAILED, request_->status().status());
273   EXPECT_EQ(net::ERR_INSECURE_RESPONSE, request_->status().error());
274   EXPECT_EQ(kInvalidServiceWorkerResponseId,
275             version_->script_cache_map()->LookupResourceId(script_url_));
276 }
277
278 TEST_F(ServiceWorkerWriteToCacheJobTest, SSLCertificateError) {
279   mock_protocol_handler_->SetCreateJobCallback(
280       base::Bind(&CreateSSLCertificateErrorJob));
281   request_->Start();
282   base::RunLoop().RunUntilIdle();
283   EXPECT_EQ(net::URLRequestStatus::FAILED, request_->status().status());
284   EXPECT_EQ(net::ERR_INSECURE_RESPONSE, request_->status().error());
285   EXPECT_EQ(kInvalidServiceWorkerResponseId,
286             version_->script_cache_map()->LookupResourceId(script_url_));
287 }
288
289 TEST_F(ServiceWorkerWriteToCacheJobTest, CertStatusError) {
290   mock_protocol_handler_->SetCreateJobCallback(
291       base::Bind(&CreateCertStatusErrorJob));
292   request_->Start();
293   base::RunLoop().RunUntilIdle();
294   EXPECT_EQ(net::URLRequestStatus::FAILED, request_->status().status());
295   EXPECT_EQ(net::ERR_INSECURE_RESPONSE, request_->status().error());
296   EXPECT_EQ(kInvalidServiceWorkerResponseId,
297             version_->script_cache_map()->LookupResourceId(script_url_));
298 }
299
300 }  // namespace content