a1993a9e7f497291ef2912ab45d2883b8c3503df
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / push_messaging / push_messaging_apitest.cc
1 // Copyright (c) 2012 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 "chrome/browser/extensions/api/push_messaging/push_messaging_api.h"
6
7 #include "apps/launcher.h"
8 #include "base/strings/stringprintf.h"
9 #include "chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_handler.h"
10 #include "chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_mapper.h"
11 #include "chrome/browser/extensions/extension_apitest.h"
12 #include "chrome/browser/extensions/extension_test_message_listener.h"
13 #include "chrome/browser/invalidation/fake_invalidation_service.h"
14 #include "chrome/browser/invalidation/invalidation_service_factory.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/test/base/ui_test_utils.h"
19 #include "components/invalidation/invalidation_service.h"
20 #include "google/cacheinvalidation/types.pb.h"
21 #include "sync/internal_api/public/base/invalidation.h"
22 #include "sync/notifier/fake_invalidator.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24
25 using ::testing::SaveArg;
26 using ::testing::StrictMock;
27 using ::testing::_;
28
29 using invalidation::InvalidationServiceFactory;
30
31 namespace extensions {
32
33 namespace {
34
35 invalidation::ObjectId ExtensionAndSubchannelToObjectId(
36     const std::string& extension_id, int subchannel_id) {
37   return invalidation::ObjectId(
38       ipc::invalidation::ObjectSource::CHROME_PUSH_MESSAGING,
39       base::StringPrintf("U/%s/%d", extension_id.c_str(), subchannel_id));
40 }
41
42 class MockInvalidationMapper : public PushMessagingInvalidationMapper {
43  public:
44   MockInvalidationMapper();
45   ~MockInvalidationMapper();
46
47   MOCK_METHOD1(SuppressInitialInvalidationsForExtension,
48                void(const std::string&));
49   MOCK_METHOD1(RegisterExtension, void(const std::string&));
50   MOCK_METHOD1(UnregisterExtension, void(const std::string&));
51 };
52
53 MockInvalidationMapper::MockInvalidationMapper() {}
54 MockInvalidationMapper::~MockInvalidationMapper() {}
55
56 }  // namespace
57
58 class PushMessagingApiTest : public ExtensionApiTest {
59  public:
60   PushMessagingApiTest()
61       : fake_invalidation_service_(NULL) {
62   }
63
64   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
65     ExtensionApiTest::SetUpCommandLine(command_line);
66   }
67
68   virtual void SetUp() OVERRIDE {
69     InvalidationServiceFactory::GetInstance()->RegisterTestingFactory(
70         invalidation::FakeInvalidationService::Build);
71     ExtensionApiTest::SetUp();
72   }
73
74   virtual void SetUpOnMainThread() OVERRIDE {
75     ExtensionApiTest::SetUpOnMainThread();
76     fake_invalidation_service_ =
77         static_cast<invalidation::FakeInvalidationService*>(
78             InvalidationServiceFactory::GetInstance()->GetForProfile(
79                 profile()));
80   }
81
82   void EmitInvalidation(
83       const invalidation::ObjectId& object_id,
84       int64 version,
85       const std::string& payload) {
86     fake_invalidation_service_->EmitInvalidationForTest(
87         syncer::Invalidation::Init(object_id, version, payload));
88   }
89
90   PushMessagingAPI* GetAPI() {
91     return PushMessagingAPI::Get(profile());
92   }
93
94   PushMessagingEventRouter* GetEventRouter() {
95     return PushMessagingAPI::Get(profile())->GetEventRouterForTest();
96   }
97
98   invalidation::FakeInvalidationService* fake_invalidation_service_;
99 };
100
101 IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, EventDispatch) {
102   ResultCatcher catcher;
103   catcher.RestrictToProfile(profile());
104
105   const extensions::Extension* extension =
106       LoadExtension(test_data_dir_.AppendASCII("push_messaging"));
107   ASSERT_TRUE(extension);
108   ui_test_utils::NavigateToURL(
109       browser(), extension->GetResourceURL("event_dispatch.html"));
110
111   GetEventRouter()->TriggerMessageForTest(extension->id(), 1, "payload");
112
113   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
114 }
115
116 // Test that a push introduced into the sync code makes it to the extension
117 // that we install.
118 IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, ReceivesPush) {
119   ResultCatcher catcher;
120   catcher.RestrictToProfile(profile());
121
122   const extensions::Extension* extension =
123       LoadExtension(test_data_dir_.AppendASCII("push_messaging"));
124   ASSERT_TRUE(extension);
125   ui_test_utils::NavigateToURL(
126       browser(), extension->GetResourceURL("event_dispatch.html"));
127
128   // PushMessagingInvalidationHandler suppresses the initial invalidation on
129   // each subchannel at install, so trigger the suppressions first.
130   for (int i = 0; i < 3; ++i) {
131     EmitInvalidation(
132         ExtensionAndSubchannelToObjectId(extension->id(), i), i, std::string());
133   }
134
135   EmitInvalidation(
136       ExtensionAndSubchannelToObjectId(extension->id(), 1), 5, "payload");
137   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
138 }
139
140 // Checks that an extension with the pushMessaging permission gets automatically
141 // registered for invalidations when it is loaded.
142 IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, AutoRegistration) {
143   scoped_ptr<StrictMock<MockInvalidationMapper> > mapper(
144       new StrictMock<MockInvalidationMapper>);
145   StrictMock<MockInvalidationMapper>* unsafe_mapper = mapper.get();
146   // PushMessagingEventRouter owns the mapper now.
147   GetAPI()->SetMapperForTest(
148       mapper.PassAs<PushMessagingInvalidationMapper>());
149
150   std::string extension_id1;
151   std::string extension_id2;
152   EXPECT_CALL(*unsafe_mapper, SuppressInitialInvalidationsForExtension(_))
153       .WillOnce(SaveArg<0>(&extension_id1));
154   EXPECT_CALL(*unsafe_mapper, RegisterExtension(_))
155       .WillOnce(SaveArg<0>(&extension_id2));
156   const extensions::Extension* extension =
157       LoadExtension(test_data_dir_.AppendASCII("push_messaging"));
158   ASSERT_TRUE(extension);
159   EXPECT_EQ(extension->id(), extension_id1);
160   EXPECT_EQ(extension->id(), extension_id2);
161   EXPECT_CALL(*unsafe_mapper, UnregisterExtension(extension->id()));
162   UnloadExtension(extension->id());
163 }
164
165 // Tests that we re-register for invalidations on restart for extensions that
166 // are already installed.
167 IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, PRE_Restart) {
168   PushMessagingInvalidationHandler* handler =
169       static_cast<PushMessagingInvalidationHandler*>(
170           GetAPI()->GetMapperForTest());
171   EXPECT_TRUE(handler->GetRegisteredExtensionsForTest().empty());
172   ASSERT_TRUE(InstallExtension(test_data_dir_.AppendASCII("push_messaging"),
173                                1 /* new install */));
174 }
175
176 IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, Restart) {
177   PushMessagingInvalidationHandler* handler =
178       static_cast<PushMessagingInvalidationHandler*>(
179           GetAPI()->GetMapperForTest());
180   EXPECT_EQ(1U, handler->GetRegisteredExtensionsForTest().size());
181 }
182
183 // Test that GetChannelId fails if no user is signed in.
184 IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, GetChannelId) {
185   ResultCatcher catcher;
186   catcher.RestrictToProfile(profile());
187
188   const extensions::Extension* extension =
189       LoadExtension(test_data_dir_.AppendASCII("push_messaging"));
190   ASSERT_TRUE(extension);
191   ui_test_utils::NavigateToURL(
192       browser(), extension->GetResourceURL("get_channel_id.html"));
193
194   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
195 }
196
197 }  // namespace extensions