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/run_loop.h"
7#include "content/browser/service_worker/embedded_worker_registry.h"
8#include "content/browser/service_worker/embedded_worker_test_helper.h"
9#include "content/browser/service_worker/service_worker_context_core.h"
10#include "content/browser/service_worker/service_worker_handle.h"
11#include "content/browser/service_worker/service_worker_registration.h"
12#include "content/browser/service_worker/service_worker_test_utils.h"
13#include "content/browser/service_worker/service_worker_version.h"
14#include "content/common/service_worker/embedded_worker_messages.h"
15#include "content/common/service_worker/service_worker_messages.h"
16#include "content/public/test/test_browser_thread_bundle.h"
17#include "ipc/ipc_message.h"
18#include "ipc/ipc_test_sink.h"
19#include "testing/gtest/include/gtest/gtest.h"
20#include "third_party/WebKit/public/platform/WebServiceWorkerState.h"
21
22namespace content {
23
24namespace {
25
26const int kRenderProcessId = 88;  // A dummy ID for testing.
27
28void VerifyStateChangedMessage(int expected_handle_id,
29                              blink::WebServiceWorkerState expected_state,
30                              const IPC::Message* message) {
31  ASSERT_TRUE(message != NULL);
32  ServiceWorkerMsg_ServiceWorkerStateChanged::Param param;
33  ASSERT_TRUE(ServiceWorkerMsg_ServiceWorkerStateChanged::Read(
34      message, &param));
35  EXPECT_EQ(expected_handle_id, param.b);
36  EXPECT_EQ(expected_state, param.c);
37}
38
39}  // namespace
40
41class ServiceWorkerHandleTest : public testing::Test {
42 public:
43  ServiceWorkerHandleTest()
44      : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
45
46  virtual void SetUp() OVERRIDE {
47    helper_.reset(new EmbeddedWorkerTestHelper(kRenderProcessId));
48
49    const GURL pattern("http://www.example.com/");
50    registration_ = new ServiceWorkerRegistration(
51        pattern,
52        1L,
53        helper_->context()->AsWeakPtr());
54    version_ = new ServiceWorkerVersion(
55        registration_.get(),
56        GURL("http://www.example.com/service_worker.js"),
57        1L,
58        helper_->context()->AsWeakPtr());
59
60    helper_->SimulateAddProcessToPattern(pattern, kRenderProcessId);
61  }
62
63  virtual void TearDown() OVERRIDE {
64    registration_ = NULL;
65    version_ = NULL;
66    helper_.reset();
67  }
68
69  IPC::TestSink* ipc_sink() { return helper_->ipc_sink(); }
70
71  TestBrowserThreadBundle browser_thread_bundle_;
72  scoped_ptr<EmbeddedWorkerTestHelper> helper_;
73  scoped_refptr<ServiceWorkerRegistration> registration_;
74  scoped_refptr<ServiceWorkerVersion> version_;
75
76 private:
77  DISALLOW_COPY_AND_ASSIGN(ServiceWorkerHandleTest);
78};
79
80TEST_F(ServiceWorkerHandleTest, OnVersionStateChanged) {
81  scoped_ptr<ServiceWorkerHandle> handle =
82      ServiceWorkerHandle::Create(helper_->context()->AsWeakPtr(),
83                                  helper_.get(),
84                                  1 /* thread_id */,
85                                  33 /* provider_id */,
86                                  version_.get());
87
88  // Start the worker, and then...
89  ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
90  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
91  base::RunLoop().RunUntilIdle();
92  EXPECT_EQ(SERVICE_WORKER_OK, status);
93
94  // ...dispatch install event.
95  status = SERVICE_WORKER_ERROR_FAILED;
96  version_->SetStatus(ServiceWorkerVersion::INSTALLING);
97  version_->DispatchInstallEvent(-1, CreateReceiverOnCurrentThread(&status));
98  base::RunLoop().RunUntilIdle();
99  EXPECT_EQ(SERVICE_WORKER_OK, status);
100
101  version_->SetStatus(ServiceWorkerVersion::INSTALLED);
102
103  ASSERT_EQ(4UL, ipc_sink()->message_count());
104
105  // We should be sending 1. StartWorker,
106  EXPECT_EQ(EmbeddedWorkerMsg_StartWorker::ID,
107            ipc_sink()->GetMessageAt(0)->type());
108  // 2. StateChanged (state == Installing),
109  VerifyStateChangedMessage(handle->handle_id(),
110                            blink::WebServiceWorkerStateInstalling,
111                            ipc_sink()->GetMessageAt(1));
112  // 3. SendMessageToWorker (to send InstallEvent), and
113  EXPECT_EQ(EmbeddedWorkerContextMsg_MessageToWorker::ID,
114            ipc_sink()->GetMessageAt(2)->type());
115  // 4. StateChanged (state == Installed).
116  VerifyStateChangedMessage(handle->handle_id(),
117                            blink::WebServiceWorkerStateInstalled,
118                            ipc_sink()->GetMessageAt(3));
119}
120
121}  // namespace content
122