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