1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/browser/service_worker/service_worker_registration.h"
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/logging.h"
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/message_loop/message_loop.h"
10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/run_loop.h"
1103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/thread_task_runner_handle.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/browser/browser_thread_impl.h"
13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/browser/service_worker/service_worker_context_core.h"
146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/browser/service_worker/service_worker_registration_handle.h"
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "url/gurl.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace content {
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class ServiceWorkerRegistrationTest : public testing::Test {
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ServiceWorkerRegistrationTest()
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : io_thread_(BrowserThread::IO, &message_loop_) {}
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  virtual void SetUp() OVERRIDE {
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    context_.reset(
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        new ServiceWorkerContextCore(base::FilePath(),
2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                     base::ThreadTaskRunnerHandle::Get(),
2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                     base::ThreadTaskRunnerHandle::Get(),
3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                     base::ThreadTaskRunnerHandle::Get(),
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     NULL,
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     NULL,
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     NULL));
34c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    context_ptr_ = context_->AsWeakPtr();
35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    context_.reset();
39010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    base::RunLoop().RunUntilIdle();
40010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  class RegistrationListener : public ServiceWorkerRegistration::Listener {
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)   public:
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    RegistrationListener() {}
456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ~RegistrationListener() {
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (observed_registration_.get())
476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        observed_registration_->RemoveListener(this);
486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    virtual void OnVersionAttributesChanged(
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        ServiceWorkerRegistration* registration,
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        ChangedVersionAttributesMask changed_mask,
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        const ServiceWorkerRegistrationInfo& info) OVERRIDE {
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      observed_registration_ = registration;
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      observed_changed_mask_ = changed_mask;
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      observed_info_ = info;
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    virtual void OnRegistrationFailed(
606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        ServiceWorkerRegistration* registration) OVERRIDE {
616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      NOTREACHED();
626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    virtual void OnRegistrationFinishedUninstalling(
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        ServiceWorkerRegistration* registration) OVERRIDE {
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      NOTREACHED();
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    virtual void OnUpdateFound(
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        ServiceWorkerRegistration* registration) OVERRIDE {
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      NOTREACHED();
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    void Reset() {
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      observed_registration_ = NULL;
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      observed_changed_mask_ = ChangedVersionAttributesMask();
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      observed_info_ = ServiceWorkerRegistrationInfo();
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_refptr<ServiceWorkerRegistration> observed_registration_;
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ChangedVersionAttributesMask observed_changed_mask_;
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ServiceWorkerRegistrationInfo observed_info_;
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  };
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) protected:
86c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_ptr<ServiceWorkerContextCore> context_;
87c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  base::WeakPtr<ServiceWorkerContextCore> context_ptr_;
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::MessageLoopForIO message_loop_;
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  BrowserThreadImpl io_thread_;
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(ServiceWorkerRegistrationTest, SetAndUnsetVersions) {
935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const GURL kScope("http://www.example.not/");
945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const GURL kScript("http://www.example.not/service_worker.js");
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int64 kRegistrationId = 1L;
965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<ServiceWorkerRegistration> registration =
975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new ServiceWorkerRegistration(
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          kScope,
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          kRegistrationId,
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          context_ptr_);
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const int64 version_1_id = 1L;
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const int64 version_2_id = 2L;
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<ServiceWorkerVersion> version_1 = new ServiceWorkerVersion(
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      registration.get(), kScript, version_1_id, context_ptr_);
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<ServiceWorkerVersion> version_2 = new ServiceWorkerVersion(
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      registration.get(), kScript, version_2_id, context_ptr_);
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  RegistrationListener listener;
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  registration->AddListener(&listener);
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  registration->SetActiveVersion(version_1.get());
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(version_1.get(), registration->active_version());
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(registration, listener.observed_registration_);
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(ChangedVersionAttributesMask::ACTIVE_VERSION,
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            listener.observed_changed_mask_.changed());
1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(kScope, listener.observed_info_.pattern);
1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(version_1_id, listener.observed_info_.active_version.version_id);
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(kScript, listener.observed_info_.active_version.script_url);
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(listener.observed_info_.installing_version.is_null);
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(listener.observed_info_.waiting_version.is_null);
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(listener.observed_info_.controlling_version.is_null);
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  listener.Reset();
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  registration->SetInstallingVersion(version_2.get());
1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(version_2.get(), registration->installing_version());
1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(ChangedVersionAttributesMask::INSTALLING_VERSION,
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            listener.observed_changed_mask_.changed());
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(version_1_id, listener.observed_info_.active_version.version_id);
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(version_2_id,
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            listener.observed_info_.installing_version.version_id);
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(listener.observed_info_.waiting_version.is_null);
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(listener.observed_info_.controlling_version.is_null);
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  listener.Reset();
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  registration->SetWaitingVersion(version_2.get());
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(version_2.get(), registration->waiting_version());
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(registration->installing_version());
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(listener.observed_changed_mask_.waiting_changed());
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(listener.observed_changed_mask_.installing_changed());
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(version_1_id, listener.observed_info_.active_version.version_id);
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(version_2_id, listener.observed_info_.waiting_version.version_id);
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(listener.observed_info_.installing_version.is_null);
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(listener.observed_info_.controlling_version.is_null);
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  listener.Reset();
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  registration->UnsetVersion(version_2.get());
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(registration->waiting_version());
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(ChangedVersionAttributesMask::WAITING_VERSION,
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            listener.observed_changed_mask_.changed());
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(version_1_id, listener.observed_info_.active_version.version_id);
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(listener.observed_info_.waiting_version.is_null);
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(listener.observed_info_.installing_version.is_null);
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(listener.observed_info_.controlling_version.is_null);
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(ServiceWorkerRegistrationTest, FailedRegistrationNoCrash) {
1616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const GURL kScope("http://www.example.not/");
1626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  int64 kRegistrationId = 1L;
1636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  int kProviderId = 1;
1646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  scoped_refptr<ServiceWorkerRegistration> registration =
1656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      new ServiceWorkerRegistration(
1666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          kScope,
1676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          kRegistrationId,
1686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          context_ptr_);
1696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  scoped_ptr<ServiceWorkerRegistrationHandle> handle(
1706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      new ServiceWorkerRegistrationHandle(context_ptr_,
1716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                          NULL,
1726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                          kProviderId,
1736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                          registration.get()));
1746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  registration->NotifyRegistrationFailed();
1756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Don't crash when handle gets destructed.
1766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
1776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace content
179