blob: 6e9816088a76e153df56cb0b1c53e9419038e486 [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006
Ben Murdochbb1529c2013-08-08 10:24:53 +01007#include "apps/launcher.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01008#include "base/strings/stringprintf.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +00009#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"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000012#include "chrome/browser/extensions/extension_test_message_listener.h"
Ben Murdocheb525c52013-07-10 11:40:50 +010013#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"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000016#include "chrome/browser/profiles/profile.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000017#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"
Ben Murdocheb525c52013-07-10 11:40:50 +010021#include "sync/notifier/fake_invalidator.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000022#include "testing/gmock/include/gmock/gmock.h"
23
24using ::testing::_;
25using ::testing::SaveArg;
26using ::testing::StrictMock;
27
Ben Murdocheb525c52013-07-10 11:40:50 +010028using invalidation::InvalidationServiceFactory;
29
Torne (Richard Coles)58218062012-11-14 11:43:16 +000030namespace extensions {
31
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000032namespace {
33
34invalidation::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
Torne (Richard Coles)58218062012-11-14 11:43:16 +000041class MockInvalidationMapper : public PushMessagingInvalidationMapper {
42 public:
43 MockInvalidationMapper();
44 ~MockInvalidationMapper();
45
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000046 MOCK_METHOD1(SuppressInitialInvalidationsForExtension,
47 void(const std::string&));
Torne (Richard Coles)58218062012-11-14 11:43:16 +000048 MOCK_METHOD1(RegisterExtension, void(const std::string&));
49 MOCK_METHOD1(UnregisterExtension, void(const std::string&));
50};
51
52MockInvalidationMapper::MockInvalidationMapper() {}
53MockInvalidationMapper::~MockInvalidationMapper() {}
54
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000055} // namespace
56
Torne (Richard Coles)58218062012-11-14 11:43:16 +000057class PushMessagingApiTest : public ExtensionApiTest {
58 public:
Ben Murdocheb525c52013-07-10 11:40:50 +010059 PushMessagingApiTest()
60 : fake_invalidation_service_(NULL) {
61 }
62
Torne (Richard Coles)58218062012-11-14 11:43:16 +000063 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
64 ExtensionApiTest::SetUpCommandLine(command_line);
65 }
66
Ben Murdocheb525c52013-07-10 11:40:50 +010067 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 const std::string& payload) {
Ben Murdochca12bfa2013-07-23 11:17:05 +010084 fake_invalidation_service_->EmitInvalidationForTest(
85 object_id,
86 syncer::Invalidation::kUnknownVersion,
87 payload);
Ben Murdocheb525c52013-07-10 11:40:50 +010088 }
89
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000090 PushMessagingAPI* GetAPI() {
91 return PushMessagingAPI::Get(profile());
92 }
93
Torne (Richard Coles)58218062012-11-14 11:43:16 +000094 PushMessagingEventRouter* GetEventRouter() {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000095 return PushMessagingAPI::Get(profile())->GetEventRouterForTest();
Torne (Richard Coles)58218062012-11-14 11:43:16 +000096 }
Ben Murdocheb525c52013-07-10 11:40:50 +010097
98 invalidation::FakeInvalidationService* fake_invalidation_service_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000099};
100
101IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, EventDispatch) {
102 ResultCatcher catcher;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000103 catcher.RestrictToProfile(profile());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000104
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"));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000110
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.
118IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, ReceivesPush) {
119 ResultCatcher catcher;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000120 catcher.RestrictToProfile(profile());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000121
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"));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000127
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000128 // PushMessagingInvalidationHandler suppresses the initial invalidation on
129 // each subchannel at install, so trigger the suppressions first.
130 for (int i = 0; i < 3; ++i) {
Ben Murdocheb525c52013-07-10 11:40:50 +0100131 EmitInvalidation(
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000132 ExtensionAndSubchannelToObjectId(extension->id(), i), std::string());
133 }
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000134
Ben Murdocheb525c52013-07-10 11:40:50 +0100135 EmitInvalidation(
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000136 ExtensionAndSubchannelToObjectId(extension->id(), 1), "payload");
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000137 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.
142IN_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.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000147 GetAPI()->SetMapperForTest(
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000148 mapper.PassAs<PushMessagingInvalidationMapper>());
149
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000150 std::string extension_id1;
151 std::string extension_id2;
152 EXPECT_CALL(*unsafe_mapper, SuppressInitialInvalidationsForExtension(_))
153 .WillOnce(SaveArg<0>(&extension_id1));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000154 EXPECT_CALL(*unsafe_mapper, RegisterExtension(_))
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000155 .WillOnce(SaveArg<0>(&extension_id2));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000156 const extensions::Extension* extension =
157 LoadExtension(test_data_dir_.AppendASCII("push_messaging"));
158 ASSERT_TRUE(extension);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000159 EXPECT_EQ(extension->id(), extension_id1);
160 EXPECT_EQ(extension->id(), extension_id2);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000161 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.
167IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, PRE_Restart) {
168 PushMessagingInvalidationHandler* handler =
169 static_cast<PushMessagingInvalidationHandler*>(
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000170 GetAPI()->GetMapperForTest());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000171 EXPECT_TRUE(handler->GetRegisteredExtensionsForTest().empty());
172 ASSERT_TRUE(InstallExtension(test_data_dir_.AppendASCII("push_messaging"),
173 1 /* new install */));
174}
175
176IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, Restart) {
177 PushMessagingInvalidationHandler* handler =
178 static_cast<PushMessagingInvalidationHandler*>(
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000179 GetAPI()->GetMapperForTest());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000180 EXPECT_EQ(1U, handler->GetRegisteredExtensionsForTest().size());
181}
182
183// Test that GetChannelId fails if no user is signed in.
184IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, GetChannelId) {
185 ResultCatcher catcher;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000186 catcher.RestrictToProfile(profile());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000187
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