Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / browser / service_worker / service_worker_url_request_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/basictypes.h"
6 #include "base/callback.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h"
10 #include "content/browser/fileapi/chrome_blob_storage_context.h"
11 #include "content/browser/fileapi/mock_url_request_delegate.h"
12 #include "content/browser/service_worker/embedded_worker_registry.h"
13 #include "content/browser/service_worker/embedded_worker_test_helper.h"
14 #include "content/browser/service_worker/service_worker_context_core.h"
15 #include "content/browser/service_worker/service_worker_provider_host.h"
16 #include "content/browser/service_worker/service_worker_registration.h"
17 #include "content/browser/service_worker/service_worker_test_utils.h"
18 #include "content/browser/service_worker/service_worker_url_request_job.h"
19 #include "content/browser/service_worker/service_worker_version.h"
20 #include "content/common/resource_request_body.h"
21 #include "content/common/service_worker/service_worker_messages.h"
22 #include "content/public/browser/blob_handle.h"
23 #include "content/public/test/test_browser_context.h"
24 #include "content/public/test/test_browser_thread_bundle.h"
25 #include "net/base/io_buffer.h"
26 #include "net/http/http_request_headers.h"
27 #include "net/http/http_response_headers.h"
28 #include "net/url_request/url_request.h"
29 #include "net/url_request/url_request_context.h"
30 #include "net/url_request/url_request_job_factory_impl.h"
31 #include "storage/browser/blob/blob_storage_context.h"
32 #include "storage/browser/blob/blob_url_request_job.h"
33 #include "storage/browser/blob/blob_url_request_job_factory.h"
34 #include "storage/common/blob/blob_data.h"
35 #include "testing/gtest/include/gtest/gtest.h"
36
37 namespace content {
38
39 class ServiceWorkerURLRequestJobTest;
40
41 namespace {
42
43 const int kProcessID = 1;
44 const int kProviderID = 100;
45 const char kTestData[] = "Here is sample text for the blob.";
46
47 class MockHttpProtocolHandler
48     : public net::URLRequestJobFactory::ProtocolHandler {
49  public:
50   MockHttpProtocolHandler(
51       base::WeakPtr<ServiceWorkerProviderHost> provider_host,
52       base::WeakPtr<storage::BlobStorageContext> blob_storage_context)
53       : provider_host_(provider_host),
54         blob_storage_context_(blob_storage_context) {}
55   virtual ~MockHttpProtocolHandler() {}
56
57   virtual net::URLRequestJob* MaybeCreateJob(
58       net::URLRequest* request,
59       net::NetworkDelegate* network_delegate) const OVERRIDE {
60     ServiceWorkerURLRequestJob* job =
61         new ServiceWorkerURLRequestJob(request,
62                                        network_delegate,
63                                        provider_host_,
64                                        blob_storage_context_,
65                                        scoped_refptr<ResourceRequestBody>());
66     job->ForwardToServiceWorker();
67     return job;
68   }
69
70  private:
71   base::WeakPtr<ServiceWorkerProviderHost> provider_host_;
72   base::WeakPtr<storage::BlobStorageContext> blob_storage_context_;
73 };
74
75 // Returns a BlobProtocolHandler that uses |blob_storage_context|. Caller owns
76 // the memory.
77 storage::BlobProtocolHandler* CreateMockBlobProtocolHandler(
78     storage::BlobStorageContext* blob_storage_context) {
79   // The FileSystemContext and MessageLoopProxy are not actually used but a
80   // MessageLoopProxy is needed to avoid a DCHECK in BlobURLRequestJob ctor.
81   return new storage::BlobProtocolHandler(
82       blob_storage_context, NULL, base::MessageLoopProxy::current().get());
83 }
84
85 }  // namespace
86
87 class ServiceWorkerURLRequestJobTest : public testing::Test {
88  protected:
89   ServiceWorkerURLRequestJobTest()
90       : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
91         blob_data_(new storage::BlobData("blob-id:myblob")) {}
92   virtual ~ServiceWorkerURLRequestJobTest() {}
93
94   virtual void SetUp() OVERRIDE {
95     browser_context_.reset(new TestBrowserContext);
96     SetUpWithHelper(new EmbeddedWorkerTestHelper(kProcessID));
97   }
98
99   void SetUpWithHelper(EmbeddedWorkerTestHelper* helper) {
100     helper_.reset(helper);
101
102     registration_ = new ServiceWorkerRegistration(
103         GURL("http://example.com/"),
104         1L,
105         helper_->context()->AsWeakPtr());
106     version_ = new ServiceWorkerVersion(
107         registration_.get(),
108         GURL("http://example.com/service_worker.js"),
109         1L,
110         helper_->context()->AsWeakPtr());
111
112     scoped_ptr<ServiceWorkerProviderHost> provider_host(
113         new ServiceWorkerProviderHost(
114             kProcessID, kProviderID, helper_->context()->AsWeakPtr(), NULL));
115     provider_host->AssociateRegistration(registration_.get());
116     registration_->SetActiveVersion(version_.get());
117
118     ChromeBlobStorageContext* chrome_blob_storage_context =
119         ChromeBlobStorageContext::GetFor(browser_context_.get());
120     // Wait for chrome_blob_storage_context to finish initializing.
121     base::RunLoop().RunUntilIdle();
122     storage::BlobStorageContext* blob_storage_context =
123         chrome_blob_storage_context->context();
124
125     url_request_job_factory_.reset(new net::URLRequestJobFactoryImpl);
126     url_request_job_factory_->SetProtocolHandler(
127         "http",
128         new MockHttpProtocolHandler(provider_host->AsWeakPtr(),
129                                     blob_storage_context->AsWeakPtr()));
130     url_request_job_factory_->SetProtocolHandler(
131         "blob", CreateMockBlobProtocolHandler(blob_storage_context));
132     url_request_context_.set_job_factory(url_request_job_factory_.get());
133
134     helper_->context()->AddProviderHost(provider_host.Pass());
135   }
136
137   virtual void TearDown() OVERRIDE {
138     version_ = NULL;
139     registration_ = NULL;
140     helper_.reset();
141   }
142
143   void TestRequest(int expected_status_code,
144                    const std::string& expected_status_text,
145                    const std::string& expected_response) {
146     request_ = url_request_context_.CreateRequest(
147         GURL("http://example.com/foo.html"),
148         net::DEFAULT_PRIORITY,
149         &url_request_delegate_,
150         NULL);
151
152     request_->set_method("GET");
153     request_->Start();
154     base::RunLoop().RunUntilIdle();
155     EXPECT_TRUE(request_->status().is_success());
156     EXPECT_EQ(expected_status_code,
157               request_->response_headers()->response_code());
158     EXPECT_EQ(expected_status_text,
159               request_->response_headers()->GetStatusText());
160     EXPECT_EQ(expected_response, url_request_delegate_.response_data());
161   }
162
163   TestBrowserThreadBundle thread_bundle_;
164
165   scoped_ptr<TestBrowserContext> browser_context_;
166   scoped_ptr<EmbeddedWorkerTestHelper> helper_;
167   scoped_refptr<ServiceWorkerRegistration> registration_;
168   scoped_refptr<ServiceWorkerVersion> version_;
169
170   scoped_ptr<net::URLRequestJobFactoryImpl> url_request_job_factory_;
171   net::URLRequestContext url_request_context_;
172   MockURLRequestDelegate url_request_delegate_;
173   scoped_ptr<net::URLRequest> request_;
174
175   scoped_refptr<storage::BlobData> blob_data_;
176
177  private:
178   DISALLOW_COPY_AND_ASSIGN(ServiceWorkerURLRequestJobTest);
179 };
180
181 TEST_F(ServiceWorkerURLRequestJobTest, Simple) {
182   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
183   TestRequest(200, "OK", std::string());
184 }
185
186 // Responds to fetch events with a blob.
187 class BlobResponder : public EmbeddedWorkerTestHelper {
188  public:
189   BlobResponder(int mock_render_process_id, const std::string& blob_uuid)
190       : EmbeddedWorkerTestHelper(mock_render_process_id),
191         blob_uuid_(blob_uuid) {}
192   virtual ~BlobResponder() {}
193
194  protected:
195   virtual void OnFetchEvent(int embedded_worker_id,
196                             int request_id,
197                             const ServiceWorkerFetchRequest& request) OVERRIDE {
198     SimulateSend(new ServiceWorkerHostMsg_FetchEventFinished(
199         embedded_worker_id,
200         request_id,
201         SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE,
202         ServiceWorkerResponse(
203             GURL(""), 200, "OK", ServiceWorkerHeaderMap(), blob_uuid_)));
204   }
205
206   std::string blob_uuid_;
207
208  private:
209   DISALLOW_COPY_AND_ASSIGN(BlobResponder);
210 };
211
212 TEST_F(ServiceWorkerURLRequestJobTest, BlobResponse) {
213   ChromeBlobStorageContext* blob_storage_context =
214       ChromeBlobStorageContext::GetFor(browser_context_.get());
215   std::string expected_response;
216   for (int i = 0; i < 1024; ++i) {
217     blob_data_->AppendData(kTestData);
218     expected_response += kTestData;
219   }
220   scoped_ptr<storage::BlobDataHandle> blob_handle =
221       blob_storage_context->context()->AddFinishedBlob(blob_data_.get());
222   SetUpWithHelper(new BlobResponder(kProcessID, blob_handle->uuid()));
223
224   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
225   TestRequest(200, "OK", expected_response);
226 }
227
228 TEST_F(ServiceWorkerURLRequestJobTest, NonExistentBlobUUIDResponse) {
229   SetUpWithHelper(new BlobResponder(kProcessID, "blob-id:nothing-is-here"));
230   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
231   TestRequest(500, "Service Worker Response Error", std::string());
232 }
233
234 // TODO(kinuko): Add more tests with different response data and also for
235 // FallbackToNetwork case.
236
237 }  // namespace content