1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/api/push_messaging/push_messaging_api.h"
#include "chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_handler.h"
#include "chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_mapper.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h"
#include "chrome/browser/extensions/extension_test_message_listener.h"
#include "chrome/browser/extensions/platform_app_launcher.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/ui_test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
using ::testing::_;
using ::testing::SaveArg;
using ::testing::StrictMock;
// TODO(dcheng): This is hardcoded for now since the svn export is not done yet.
// Once it's done, use ipc::invalidation::ObjectSource::CHROME_PUSH_MESSAGING.
const int kSourceId = 1030;
namespace extensions {
class MockInvalidationMapper : public PushMessagingInvalidationMapper {
public:
MockInvalidationMapper();
~MockInvalidationMapper();
MOCK_METHOD1(RegisterExtension, void(const std::string&));
MOCK_METHOD1(UnregisterExtension, void(const std::string&));
};
MockInvalidationMapper::MockInvalidationMapper() {}
MockInvalidationMapper::~MockInvalidationMapper() {}
class PushMessagingApiTest : public ExtensionApiTest {
public:
virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
ExtensionApiTest::SetUpCommandLine(command_line);
command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis);
}
PushMessagingEventRouter* GetEventRouter() {
return ExtensionSystem::Get(browser()->profile())->extension_service()->
push_messaging_event_router();
}
};
IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, EventDispatch) {
ResultCatcher catcher;
catcher.RestrictToProfile(browser()->profile());
ExtensionTestMessageListener ready("ready", true);
const extensions::Extension* extension =
LoadExtension(test_data_dir_.AppendASCII("push_messaging"));
ASSERT_TRUE(extension);
extensions::LaunchPlatformApp(
browser()->profile(), extension, NULL, FilePath());
EXPECT_TRUE(ready.WaitUntilSatisfied());
GetEventRouter()->TriggerMessageForTest(extension->id(), 1, "payload");
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
}
// Test that a push introduced into the sync code makes it to the extension
// that we install.
IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, ReceivesPush) {
ResultCatcher catcher;
catcher.RestrictToProfile(browser()->profile());
ExtensionTestMessageListener ready("ready", true);
const extensions::Extension* extension =
LoadExtension(test_data_dir_.AppendASCII("push_messaging"));
ASSERT_TRUE(extension);
extensions::LaunchPlatformApp(
browser()->profile(), extension, NULL, FilePath());
EXPECT_TRUE(ready.WaitUntilSatisfied());
ProfileSyncService* pss = ProfileSyncServiceFactory::GetForProfile(
browser()->profile());
ASSERT_TRUE(pss);
// Construct a sync id for the object "U/<extension-id>/1".
std::string id = "U/";
id += extension->id();
id += "/1";
invalidation::ObjectId object_id(kSourceId, id);
pss->EmitInvalidationForTest(object_id, "payload");
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
}
// Checks that an extension with the pushMessaging permission gets automatically
// registered for invalidations when it is loaded.
IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, AutoRegistration) {
scoped_ptr<StrictMock<MockInvalidationMapper> > mapper(
new StrictMock<MockInvalidationMapper>);
StrictMock<MockInvalidationMapper>* unsafe_mapper = mapper.get();
// PushMessagingEventRouter owns the mapper now.
GetEventRouter()->SetMapperForTest(
mapper.PassAs<PushMessagingInvalidationMapper>());
std::string extension_id;
EXPECT_CALL(*unsafe_mapper, RegisterExtension(_))
.WillOnce(SaveArg<0>(&extension_id));
const extensions::Extension* extension =
LoadExtension(test_data_dir_.AppendASCII("push_messaging"));
ASSERT_TRUE(extension);
EXPECT_EQ(extension->id(), extension_id);
EXPECT_CALL(*unsafe_mapper, UnregisterExtension(extension->id()));
UnloadExtension(extension->id());
}
// Tests that we re-register for invalidations on restart for extensions that
// are already installed.
IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, PRE_Restart) {
PushMessagingInvalidationHandler* handler =
static_cast<PushMessagingInvalidationHandler*>(
GetEventRouter()->GetMapperForTest());
EXPECT_TRUE(handler->GetRegisteredExtensionsForTest().empty());
ASSERT_TRUE(InstallExtension(test_data_dir_.AppendASCII("push_messaging"),
1 /* new install */));
}
IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, Restart) {
PushMessagingInvalidationHandler* handler =
static_cast<PushMessagingInvalidationHandler*>(
GetEventRouter()->GetMapperForTest());
EXPECT_EQ(1U, handler->GetRegisteredExtensionsForTest().size());
}
// Test the GetChannelId API.
IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, GetChannelId) {
ResultCatcher catcher;
catcher.RestrictToProfile(browser()->profile());
// ExtensionTestMessageListener ready("ready", true);
const extensions::Extension* extension =
LoadExtension(test_data_dir_.AppendASCII("get_channel_id"));
ASSERT_TRUE(extension);
extensions::LaunchPlatformApp(
browser()->profile(), extension, NULL, FilePath());
// EXPECT_TRUE(ready.WaitUntilSatisfied());
// Just loading the page will cause a getChannelId call, so we check
// for a callback. It should fail because there is no auth token.
// Make sure we got a failure (but we do get a result).
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
}
} // namespace extensions
|