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