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