Rename isSystemLocationEnabled to isLocationEnabled, as per internal review (185995).
[chromium-blink-merge.git] / content / browser / service_worker / service_worker_context_unittest.cc
blobe47c9e40f1a8bc9500b26816966a9a6e3a2d1946
1 // Copyright 2013 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/public/browser/service_worker_context.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h"
10 #include "content/browser/browser_thread_impl.h"
11 #include "content/browser/service_worker/embedded_worker_registry.h"
12 #include "content/browser/service_worker/embedded_worker_test_helper.h"
13 #include "content/browser/service_worker/service_worker_context_core.h"
14 #include "content/browser/service_worker/service_worker_context_observer.h"
15 #include "content/browser/service_worker/service_worker_context_wrapper.h"
16 #include "content/browser/service_worker/service_worker_registration.h"
17 #include "content/browser/service_worker/service_worker_storage.h"
18 #include "content/common/service_worker/embedded_worker_messages.h"
19 #include "content/common/service_worker/service_worker_messages.h"
20 #include "content/public/test/test_browser_thread_bundle.h"
21 #include "content/public/test/test_utils.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 namespace content {
26 namespace {
28 void SaveResponseCallback(bool* called,
29 int64* store_registration_id,
30 ServiceWorkerStatusCode status,
31 int64 registration_id) {
32 EXPECT_EQ(SERVICE_WORKER_OK, status) << ServiceWorkerStatusToString(status);
33 *called = true;
34 *store_registration_id = registration_id;
37 ServiceWorkerContextCore::RegistrationCallback MakeRegisteredCallback(
38 bool* called,
39 int64* store_registration_id) {
40 return base::Bind(&SaveResponseCallback, called, store_registration_id);
43 void CallCompletedCallback(bool* called, ServiceWorkerStatusCode) {
44 *called = true;
47 ServiceWorkerContextCore::UnregistrationCallback MakeUnregisteredCallback(
48 bool* called) {
49 return base::Bind(&CallCompletedCallback, called);
52 void ExpectRegisteredWorkers(
53 ServiceWorkerStatusCode expect_status,
54 bool expect_waiting,
55 bool expect_active,
56 ServiceWorkerStatusCode status,
57 const scoped_refptr<ServiceWorkerRegistration>& registration) {
58 ASSERT_EQ(expect_status, status);
59 if (status != SERVICE_WORKER_OK) {
60 EXPECT_FALSE(registration.get());
61 return;
64 if (expect_waiting) {
65 EXPECT_TRUE(registration->waiting_version());
66 } else {
67 EXPECT_FALSE(registration->waiting_version());
70 if (expect_active) {
71 EXPECT_TRUE(registration->active_version());
72 } else {
73 EXPECT_FALSE(registration->active_version());
77 class RejectInstallTestHelper : public EmbeddedWorkerTestHelper {
78 public:
79 explicit RejectInstallTestHelper(int mock_render_process_id)
80 : EmbeddedWorkerTestHelper(mock_render_process_id) {}
82 void OnInstallEvent(int embedded_worker_id,
83 int request_id,
84 int active_version_id) override {
85 SimulateSend(
86 new ServiceWorkerHostMsg_InstallEventFinished(
87 embedded_worker_id, request_id,
88 blink::WebServiceWorkerEventResultRejected));
92 class RejectActivateTestHelper : public EmbeddedWorkerTestHelper {
93 public:
94 explicit RejectActivateTestHelper(int mock_render_process_id)
95 : EmbeddedWorkerTestHelper(mock_render_process_id) {}
97 void OnActivateEvent(int embedded_worker_id, int request_id) override {
98 SimulateSend(
99 new ServiceWorkerHostMsg_ActivateEventFinished(
100 embedded_worker_id, request_id,
101 blink::WebServiceWorkerEventResultRejected));
105 enum NotificationType {
106 REGISTRATION_STORED,
107 REGISTRATION_DELETED,
108 STORAGE_RECOVERED,
111 struct NotificationLog {
112 NotificationType type;
113 GURL pattern;
116 } // namespace
118 class ServiceWorkerContextTest : public ServiceWorkerContextObserver,
119 public testing::Test {
120 public:
121 ServiceWorkerContextTest()
122 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
123 render_process_id_(99) {}
125 void SetUp() override {
126 helper_.reset(new EmbeddedWorkerTestHelper(render_process_id_));
127 helper_->context_wrapper()->AddObserver(this);
130 void TearDown() override { helper_.reset(); }
132 // ServiceWorkerContextObserver overrides.
133 void OnRegistrationStored(const GURL& pattern) override {
134 NotificationLog log;
135 log.type = REGISTRATION_STORED;
136 log.pattern = pattern;
137 notifications_.push_back(log);
139 void OnRegistrationDeleted(const GURL& pattern) override {
140 NotificationLog log;
141 log.type = REGISTRATION_DELETED;
142 log.pattern = pattern;
143 notifications_.push_back(log);
145 void OnStorageWiped() override {
146 NotificationLog log;
147 log.type = STORAGE_RECOVERED;
148 notifications_.push_back(log);
151 ServiceWorkerContextCore* context() { return helper_->context(); }
153 protected:
154 TestBrowserThreadBundle browser_thread_bundle_;
155 scoped_ptr<EmbeddedWorkerTestHelper> helper_;
156 const int render_process_id_;
157 std::vector<NotificationLog> notifications_;
160 // Make sure basic registration is working.
161 TEST_F(ServiceWorkerContextTest, Register) {
162 GURL pattern("http://www.example.com/");
163 GURL script_url("http://www.example.com/service_worker.js");
165 int64 registration_id = kInvalidServiceWorkerRegistrationId;
166 bool called = false;
167 context()->RegisterServiceWorker(
168 pattern,
169 script_url,
170 NULL,
171 MakeRegisteredCallback(&called, &registration_id));
173 ASSERT_FALSE(called);
174 base::RunLoop().RunUntilIdle();
175 EXPECT_TRUE(called);
177 EXPECT_EQ(4UL, helper_->ipc_sink()->message_count());
178 EXPECT_TRUE(helper_->ipc_sink()->GetUniqueMessageMatching(
179 EmbeddedWorkerMsg_StartWorker::ID));
180 EXPECT_TRUE(helper_->inner_ipc_sink()->GetUniqueMessageMatching(
181 ServiceWorkerMsg_InstallEvent::ID));
182 EXPECT_TRUE(helper_->inner_ipc_sink()->GetUniqueMessageMatching(
183 ServiceWorkerMsg_ActivateEvent::ID));
184 EXPECT_TRUE(helper_->ipc_sink()->GetUniqueMessageMatching(
185 EmbeddedWorkerMsg_StopWorker::ID));
186 EXPECT_NE(kInvalidServiceWorkerRegistrationId, registration_id);
188 context()->storage()->FindRegistrationForId(
189 registration_id,
190 pattern.GetOrigin(),
191 base::Bind(&ExpectRegisteredWorkers,
192 SERVICE_WORKER_OK,
193 false /* expect_waiting */,
194 true /* expect_active */));
195 base::RunLoop().RunUntilIdle();
197 ASSERT_EQ(1u, notifications_.size());
198 EXPECT_EQ(REGISTRATION_STORED, notifications_[0].type);
199 EXPECT_EQ(pattern, notifications_[0].pattern);
202 // Test registration when the service worker rejects the install event. The
203 // registration callback should indicate success, but there should be no waiting
204 // or active worker in the registration.
205 TEST_F(ServiceWorkerContextTest, Register_RejectInstall) {
206 GURL pattern("http://www.example.com/");
207 GURL script_url("http://www.example.com/service_worker.js");
209 helper_.reset(); // Make sure the process lookups stay overridden.
210 helper_.reset(new RejectInstallTestHelper(render_process_id_));
211 int64 registration_id = kInvalidServiceWorkerRegistrationId;
212 bool called = false;
213 context()->RegisterServiceWorker(
214 pattern,
215 script_url,
216 NULL,
217 MakeRegisteredCallback(&called, &registration_id));
219 ASSERT_FALSE(called);
220 base::RunLoop().RunUntilIdle();
221 EXPECT_TRUE(called);
223 EXPECT_EQ(3UL, helper_->ipc_sink()->message_count());
224 EXPECT_TRUE(helper_->ipc_sink()->GetUniqueMessageMatching(
225 EmbeddedWorkerMsg_StartWorker::ID));
226 EXPECT_TRUE(helper_->inner_ipc_sink()->GetUniqueMessageMatching(
227 ServiceWorkerMsg_InstallEvent::ID));
228 EXPECT_FALSE(helper_->inner_ipc_sink()->GetUniqueMessageMatching(
229 ServiceWorkerMsg_ActivateEvent::ID));
230 EXPECT_TRUE(helper_->ipc_sink()->GetUniqueMessageMatching(
231 EmbeddedWorkerMsg_StopWorker::ID));
232 EXPECT_NE(kInvalidServiceWorkerRegistrationId, registration_id);
234 context()->storage()->FindRegistrationForId(
235 registration_id,
236 pattern.GetOrigin(),
237 base::Bind(&ExpectRegisteredWorkers,
238 SERVICE_WORKER_ERROR_NOT_FOUND,
239 false /* expect_waiting */,
240 false /* expect_active */));
241 base::RunLoop().RunUntilIdle();
243 EXPECT_TRUE(notifications_.empty());
246 // Test registration when the service worker rejects the activate event. The
247 // registration callback should indicate success, but there should be no waiting
248 // or active worker in the registration.
249 TEST_F(ServiceWorkerContextTest, Register_RejectActivate) {
250 helper_.reset(); // Make sure the process lookups stay overridden.
251 helper_.reset(new RejectActivateTestHelper(render_process_id_));
252 int64 registration_id = kInvalidServiceWorkerRegistrationId;
253 bool called = false;
254 context()->RegisterServiceWorker(
255 GURL("http://www.example.com/"),
256 GURL("http://www.example.com/service_worker.js"),
257 NULL,
258 MakeRegisteredCallback(&called, &registration_id));
260 ASSERT_FALSE(called);
261 base::RunLoop().RunUntilIdle();
262 EXPECT_TRUE(called);
264 EXPECT_EQ(4UL, helper_->ipc_sink()->message_count());
265 EXPECT_TRUE(helper_->ipc_sink()->GetUniqueMessageMatching(
266 EmbeddedWorkerMsg_StartWorker::ID));
267 EXPECT_TRUE(helper_->inner_ipc_sink()->GetUniqueMessageMatching(
268 ServiceWorkerMsg_InstallEvent::ID));
269 EXPECT_TRUE(helper_->inner_ipc_sink()->GetUniqueMessageMatching(
270 ServiceWorkerMsg_ActivateEvent::ID));
271 EXPECT_TRUE(helper_->ipc_sink()->GetUniqueMessageMatching(
272 EmbeddedWorkerMsg_StopWorker::ID));
273 EXPECT_NE(kInvalidServiceWorkerRegistrationId, registration_id);
275 context()->storage()->FindRegistrationForId(
276 registration_id,
277 GURL("http://www.example.com"),
278 base::Bind(&ExpectRegisteredWorkers,
279 SERVICE_WORKER_ERROR_NOT_FOUND,
280 false /* expect_waiting */,
281 false /* expect_active */));
282 base::RunLoop().RunUntilIdle();
284 EXPECT_TRUE(notifications_.empty());
287 // Make sure registrations are cleaned up when they are unregistered.
288 TEST_F(ServiceWorkerContextTest, Unregister) {
289 GURL pattern("http://www.example.com/");
291 bool called = false;
292 int64 registration_id = kInvalidServiceWorkerRegistrationId;
293 context()->RegisterServiceWorker(
294 pattern,
295 GURL("http://www.example.com/service_worker.js"),
296 NULL,
297 MakeRegisteredCallback(&called, &registration_id));
299 ASSERT_FALSE(called);
300 base::RunLoop().RunUntilIdle();
301 ASSERT_TRUE(called);
302 EXPECT_NE(kInvalidServiceWorkerRegistrationId, registration_id);
304 called = false;
305 context()->UnregisterServiceWorker(pattern,
306 MakeUnregisteredCallback(&called));
308 ASSERT_FALSE(called);
309 base::RunLoop().RunUntilIdle();
310 ASSERT_TRUE(called);
312 context()->storage()->FindRegistrationForId(
313 registration_id,
314 pattern.GetOrigin(),
315 base::Bind(&ExpectRegisteredWorkers,
316 SERVICE_WORKER_ERROR_NOT_FOUND,
317 false /* expect_waiting */,
318 false /* expect_active */));
319 base::RunLoop().RunUntilIdle();
321 ASSERT_EQ(2u, notifications_.size());
322 EXPECT_EQ(REGISTRATION_STORED, notifications_[0].type);
323 EXPECT_EQ(pattern, notifications_[0].pattern);
324 EXPECT_EQ(REGISTRATION_DELETED, notifications_[1].type);
325 EXPECT_EQ(pattern, notifications_[1].pattern);
328 // Make sure registrations are cleaned up when they are unregistered in bulk.
329 TEST_F(ServiceWorkerContextTest, UnregisterMultiple) {
330 GURL origin1_p1("http://www.example.com/test");
331 GURL origin1_p2("http://www.example.com/hello");
332 GURL origin2_p1("http://www.example.com:8080/again");
333 GURL origin3_p1("http://www.other.com/");
335 bool called = false;
336 int64 registration_id1 = kInvalidServiceWorkerRegistrationId;
337 int64 registration_id2 = kInvalidServiceWorkerRegistrationId;
338 int64 registration_id3 = kInvalidServiceWorkerRegistrationId;
339 int64 registration_id4 = kInvalidServiceWorkerRegistrationId;
340 context()->RegisterServiceWorker(
341 origin1_p1,
342 GURL("http://www.example.com/service_worker.js"),
343 NULL,
344 MakeRegisteredCallback(&called, &registration_id1));
345 context()->RegisterServiceWorker(
346 origin1_p2,
347 GURL("http://www.example.com/service_worker2.js"),
348 NULL,
349 MakeRegisteredCallback(&called, &registration_id2));
350 context()->RegisterServiceWorker(
351 origin2_p1,
352 GURL("http://www.example.com:8080/service_worker3.js"),
353 NULL,
354 MakeRegisteredCallback(&called, &registration_id3));
355 context()->RegisterServiceWorker(
356 origin3_p1,
357 GURL("http://www.other.com/service_worker4.js"),
358 NULL,
359 MakeRegisteredCallback(&called, &registration_id4));
361 ASSERT_FALSE(called);
362 base::RunLoop().RunUntilIdle();
363 ASSERT_TRUE(called);
365 EXPECT_NE(kInvalidServiceWorkerRegistrationId, registration_id1);
366 EXPECT_NE(kInvalidServiceWorkerRegistrationId, registration_id2);
367 EXPECT_NE(kInvalidServiceWorkerRegistrationId, registration_id3);
368 EXPECT_NE(kInvalidServiceWorkerRegistrationId, registration_id4);
370 called = false;
371 context()->UnregisterServiceWorkers(origin1_p1.GetOrigin(),
372 MakeUnregisteredCallback(&called));
374 ASSERT_FALSE(called);
375 base::RunLoop().RunUntilIdle();
376 ASSERT_TRUE(called);
378 context()->storage()->FindRegistrationForId(
379 registration_id1,
380 origin1_p1.GetOrigin(),
381 base::Bind(&ExpectRegisteredWorkers,
382 SERVICE_WORKER_ERROR_NOT_FOUND,
383 false /* expect_waiting */,
384 false /* expect_active */));
385 context()->storage()->FindRegistrationForId(
386 registration_id2,
387 origin1_p2.GetOrigin(),
388 base::Bind(&ExpectRegisteredWorkers,
389 SERVICE_WORKER_ERROR_NOT_FOUND,
390 false /* expect_waiting */,
391 false /* expect_active */));
392 context()->storage()->FindRegistrationForId(
393 registration_id3,
394 origin2_p1.GetOrigin(),
395 base::Bind(&ExpectRegisteredWorkers,
396 SERVICE_WORKER_OK,
397 false /* expect_waiting */,
398 true /* expect_active */));
400 context()->storage()->FindRegistrationForId(
401 registration_id4,
402 origin3_p1.GetOrigin(),
403 base::Bind(&ExpectRegisteredWorkers,
404 SERVICE_WORKER_OK,
405 false /* expect_waiting */,
406 true /* expect_active */));
408 base::RunLoop().RunUntilIdle();
410 ASSERT_EQ(6u, notifications_.size());
411 EXPECT_EQ(REGISTRATION_STORED, notifications_[0].type);
412 EXPECT_EQ(origin1_p1, notifications_[0].pattern);
413 EXPECT_EQ(REGISTRATION_STORED, notifications_[1].type);
414 EXPECT_EQ(origin1_p2, notifications_[1].pattern);
415 EXPECT_EQ(REGISTRATION_STORED, notifications_[2].type);
416 EXPECT_EQ(origin2_p1, notifications_[2].pattern);
417 EXPECT_EQ(REGISTRATION_STORED, notifications_[3].type);
418 EXPECT_EQ(origin3_p1, notifications_[3].pattern);
419 EXPECT_EQ(REGISTRATION_DELETED, notifications_[4].type);
420 EXPECT_EQ(origin1_p2, notifications_[4].pattern);
421 EXPECT_EQ(REGISTRATION_DELETED, notifications_[5].type);
422 EXPECT_EQ(origin1_p1, notifications_[5].pattern);
425 // Make sure registering a new script shares an existing registration.
426 TEST_F(ServiceWorkerContextTest, RegisterNewScript) {
427 GURL pattern("http://www.example.com/");
429 bool called = false;
430 int64 old_registration_id = kInvalidServiceWorkerRegistrationId;
431 context()->RegisterServiceWorker(
432 pattern,
433 GURL("http://www.example.com/service_worker.js"),
434 NULL,
435 MakeRegisteredCallback(&called, &old_registration_id));
437 ASSERT_FALSE(called);
438 base::RunLoop().RunUntilIdle();
439 ASSERT_TRUE(called);
440 EXPECT_NE(kInvalidServiceWorkerRegistrationId, old_registration_id);
442 called = false;
443 int64 new_registration_id = kInvalidServiceWorkerRegistrationId;
444 context()->RegisterServiceWorker(
445 pattern,
446 GURL("http://www.example.com/service_worker_new.js"),
447 NULL,
448 MakeRegisteredCallback(&called, &new_registration_id));
450 ASSERT_FALSE(called);
451 base::RunLoop().RunUntilIdle();
452 ASSERT_TRUE(called);
454 EXPECT_NE(kInvalidServiceWorkerRegistrationId, new_registration_id);
455 EXPECT_EQ(old_registration_id, new_registration_id);
457 ASSERT_EQ(2u, notifications_.size());
458 EXPECT_EQ(REGISTRATION_STORED, notifications_[0].type);
459 EXPECT_EQ(pattern, notifications_[0].pattern);
460 EXPECT_EQ(REGISTRATION_STORED, notifications_[1].type);
461 EXPECT_EQ(pattern, notifications_[1].pattern);
464 // Make sure that when registering a duplicate pattern+script_url
465 // combination, that the same registration is used.
466 TEST_F(ServiceWorkerContextTest, RegisterDuplicateScript) {
467 GURL pattern("http://www.example.com/");
468 GURL script_url("http://www.example.com/service_worker.js");
470 bool called = false;
471 int64 old_registration_id = kInvalidServiceWorkerRegistrationId;
472 context()->RegisterServiceWorker(
473 pattern,
474 script_url,
475 NULL,
476 MakeRegisteredCallback(&called, &old_registration_id));
478 ASSERT_FALSE(called);
479 base::RunLoop().RunUntilIdle();
480 ASSERT_TRUE(called);
481 EXPECT_NE(kInvalidServiceWorkerRegistrationId, old_registration_id);
483 called = false;
484 int64 new_registration_id = kInvalidServiceWorkerRegistrationId;
485 context()->RegisterServiceWorker(
486 pattern,
487 script_url,
488 NULL,
489 MakeRegisteredCallback(&called, &new_registration_id));
491 ASSERT_FALSE(called);
492 base::RunLoop().RunUntilIdle();
493 ASSERT_TRUE(called);
494 EXPECT_EQ(old_registration_id, new_registration_id);
496 ASSERT_EQ(2u, notifications_.size());
497 EXPECT_EQ(REGISTRATION_STORED, notifications_[0].type);
498 EXPECT_EQ(pattern, notifications_[0].pattern);
499 EXPECT_EQ(REGISTRATION_STORED, notifications_[1].type);
500 EXPECT_EQ(pattern, notifications_[1].pattern);
503 // TODO(nhiroki): Test this for on-disk storage.
504 TEST_F(ServiceWorkerContextTest, DeleteAndStartOver) {
505 GURL pattern("http://www.example.com/");
506 GURL script_url("http://www.example.com/service_worker.js");
508 int64 registration_id = kInvalidServiceWorkerRegistrationId;
509 bool called = false;
510 context()->RegisterServiceWorker(
511 pattern,
512 script_url,
513 NULL,
514 MakeRegisteredCallback(&called, &registration_id));
516 ASSERT_FALSE(called);
517 base::RunLoop().RunUntilIdle();
518 EXPECT_TRUE(called);
520 context()->storage()->FindRegistrationForId(
521 registration_id,
522 pattern.GetOrigin(),
523 base::Bind(&ExpectRegisteredWorkers,
524 SERVICE_WORKER_OK,
525 false /* expect_waiting */,
526 true /* expect_active */));
527 base::RunLoop().RunUntilIdle();
529 // Next handle ids should be 0 (the next call should return 1).
530 EXPECT_EQ(0, context()->GetNewServiceWorkerHandleId());
531 EXPECT_EQ(0, context()->GetNewRegistrationHandleId());
533 context()->ScheduleDeleteAndStartOver();
535 // The storage is disabled while the recovery process is running, so the
536 // operation should be failed.
537 context()->storage()->FindRegistrationForId(
538 registration_id,
539 pattern.GetOrigin(),
540 base::Bind(&ExpectRegisteredWorkers,
541 SERVICE_WORKER_ERROR_FAILED,
542 false /* expect_waiting */,
543 true /* expect_active */));
544 base::RunLoop().RunUntilIdle();
546 // The context started over and the storage was re-initialized, so the
547 // registration should not be found.
548 context()->storage()->FindRegistrationForId(
549 registration_id,
550 pattern.GetOrigin(),
551 base::Bind(&ExpectRegisteredWorkers,
552 SERVICE_WORKER_ERROR_NOT_FOUND,
553 false /* expect_waiting */,
554 true /* expect_active */));
555 base::RunLoop().RunUntilIdle();
557 called = false;
558 context()->RegisterServiceWorker(
559 pattern,
560 script_url,
561 NULL,
562 MakeRegisteredCallback(&called, &registration_id));
564 ASSERT_FALSE(called);
565 base::RunLoop().RunUntilIdle();
566 EXPECT_TRUE(called);
568 context()->storage()->FindRegistrationForId(
569 registration_id,
570 pattern.GetOrigin(),
571 base::Bind(&ExpectRegisteredWorkers,
572 SERVICE_WORKER_OK,
573 false /* expect_waiting */,
574 true /* expect_active */));
575 base::RunLoop().RunUntilIdle();
577 // The new context should take over next handle ids.
578 EXPECT_EQ(1, context()->GetNewServiceWorkerHandleId());
579 EXPECT_EQ(1, context()->GetNewRegistrationHandleId());
581 ASSERT_EQ(3u, notifications_.size());
582 EXPECT_EQ(REGISTRATION_STORED, notifications_[0].type);
583 EXPECT_EQ(pattern, notifications_[0].pattern);
584 EXPECT_EQ(STORAGE_RECOVERED, notifications_[1].type);
585 EXPECT_EQ(REGISTRATION_STORED, notifications_[2].type);
586 EXPECT_EQ(pattern, notifications_[2].pattern);
589 } // namespace content