1 // Copyright 2013 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.
5 #include "base/prefs/pref_service.h"
6 #include "base/run_loop.h"
7 #include "chrome/browser/extensions/api/gcm/gcm_api.h"
8 #include "chrome/browser/extensions/extension_apitest.h"
9 #include "chrome/browser/extensions/extension_gcm_app_handler.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/services/gcm/fake_gcm_profile_service.h"
12 #include "chrome/browser/services/gcm/gcm_client_factory.h"
13 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h"
14 #include "chrome/common/chrome_switches.h"
15 #include "chrome/common/pref_names.h"
16 #include "chrome/test/base/ui_test_utils.h"
20 const char kEventsExtension[] = "gcm/events";
22 gcm::GCMClient::SendErrorDetails CreateErrorDetails(
23 const std::string& message_id,
24 const gcm::GCMClient::Result result,
25 const std::string& total_messages) {
26 gcm::GCMClient::SendErrorDetails error;
27 error.message_id = message_id;
28 error.result = result;
29 error.additional_data["expectedMessageId"] = message_id;
31 case gcm::GCMClient::ASYNC_OPERATION_PENDING:
32 error.additional_data["expectedErrorMessage"] =
33 "Asynchronous operation is pending.";
35 case gcm::GCMClient::SERVER_ERROR:
36 error.additional_data["expectedErrorMessage"] = "Server error occurred.";
38 case gcm::GCMClient::NETWORK_ERROR:
39 error.additional_data["expectedErrorMessage"] = "Network error occurred.";
41 case gcm::GCMClient::TTL_EXCEEDED:
42 error.additional_data["expectedErrorMessage"] = "Time-to-live exceeded.";
44 case gcm::GCMClient::UNKNOWN_ERROR:
45 default: // Default case is the same as UNKNOWN_ERROR
46 error.additional_data["expectedErrorMessage"] = "Unknown error occurred.";
49 error.additional_data["totalMessages"] = total_messages;
55 namespace extensions {
57 class GcmApiTest : public ExtensionApiTest {
59 GcmApiTest() : fake_gcm_profile_service_(NULL) {}
62 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE;
63 virtual void SetUpOnMainThread() OVERRIDE;
65 void StartCollecting();
67 const Extension* LoadTestExtension(const std::string& extension_path,
68 const std::string& page_name);
69 gcm::FakeGCMProfileService* service() const;
72 gcm::FakeGCMProfileService* fake_gcm_profile_service_;
75 void GcmApiTest::SetUpCommandLine(CommandLine* command_line) {
76 // We now always create the GCMProfileService instance in
77 // ProfileSyncServiceFactory that is called when a profile is being
78 // initialized. In order to prevent it from being created, we add the switch
79 // to disable the sync logic.
80 command_line->AppendSwitch(switches::kDisableSync);
82 ExtensionApiTest::SetUpCommandLine(command_line);
85 void GcmApiTest::SetUpOnMainThread() {
86 // Enable GCM such that tests could be run on all channels.
87 browser()->profile()->GetPrefs()->SetBoolean(prefs::kGCMChannelEnabled, true);
89 gcm::GCMProfileServiceFactory::GetInstance()->SetTestingFactory(
90 browser()->profile(), &gcm::FakeGCMProfileService::Build);
91 fake_gcm_profile_service_ = static_cast<gcm::FakeGCMProfileService*>(
92 gcm::GCMProfileServiceFactory::GetInstance()->GetForProfile(
93 browser()->profile()));
95 ExtensionApiTest::SetUpOnMainThread();
98 void GcmApiTest::StartCollecting() {
99 service()->set_collect(true);
102 gcm::FakeGCMProfileService* GcmApiTest::service() const {
103 return fake_gcm_profile_service_;
106 const Extension* GcmApiTest::LoadTestExtension(
107 const std::string& extension_path,
108 const std::string& page_name) {
109 const Extension* extension =
110 LoadExtension(test_data_dir_.AppendASCII(extension_path));
112 ui_test_utils::NavigateToURL(
113 browser(), extension->GetResourceURL(page_name));
118 IN_PROC_BROWSER_TEST_F(GcmApiTest, RegisterValidation) {
119 ASSERT_TRUE(RunExtensionTest("gcm/functions/register_validation"));
122 IN_PROC_BROWSER_TEST_F(GcmApiTest, Register) {
124 ASSERT_TRUE(RunExtensionTest("gcm/functions/register"));
126 const std::vector<std::string>& sender_ids =
127 service()->last_registered_sender_ids();
128 EXPECT_TRUE(std::find(sender_ids.begin(), sender_ids.end(), "Sender1") !=
130 EXPECT_TRUE(std::find(sender_ids.begin(), sender_ids.end(), "Sender2") !=
134 IN_PROC_BROWSER_TEST_F(GcmApiTest, Unregister) {
135 service()->AddExpectedUnregisterResponse(gcm::GCMClient::SUCCESS);
136 service()->AddExpectedUnregisterResponse(gcm::GCMClient::SERVER_ERROR);
138 ASSERT_TRUE(RunExtensionTest("gcm/functions/unregister"));
141 IN_PROC_BROWSER_TEST_F(GcmApiTest, SendValidation) {
142 ASSERT_TRUE(RunExtensionTest("gcm/functions/send"));
145 IN_PROC_BROWSER_TEST_F(GcmApiTest, SendMessageData) {
147 ASSERT_TRUE(RunExtensionTest("gcm/functions/send_message_data"));
149 EXPECT_EQ("destination-id", service()->last_receiver_id());
150 const gcm::GCMClient::OutgoingMessage& message =
151 service()->last_sent_message();
152 gcm::GCMClient::MessageData::const_iterator iter;
154 EXPECT_EQ(100, message.time_to_live);
156 EXPECT_TRUE((iter = message.data.find("key1")) != message.data.end());
157 EXPECT_EQ("value1", iter->second);
159 EXPECT_TRUE((iter = message.data.find("key2")) != message.data.end());
160 EXPECT_EQ("value2", iter->second);
163 IN_PROC_BROWSER_TEST_F(GcmApiTest, SendMessageDefaultTTL) {
165 ASSERT_TRUE(RunExtensionTest("gcm/functions/send_message_default_ttl"));
167 EXPECT_EQ("destination-id", service()->last_receiver_id());
168 const gcm::GCMClient::OutgoingMessage& message =
169 service()->last_sent_message();
170 gcm::GCMClient::MessageData::const_iterator iter;
172 EXPECT_EQ(2419200, message.time_to_live);
175 IN_PROC_BROWSER_TEST_F(GcmApiTest, OnMessagesDeleted) {
176 ResultCatcher catcher;
177 catcher.RestrictToProfile(profile());
179 const extensions::Extension* extension =
180 LoadTestExtension(kEventsExtension, "on_messages_deleted.html");
181 ASSERT_TRUE(extension);
183 extensions::ExtensionGCMAppHandler app_handler(profile());
184 app_handler.OnMessagesDeleted(extension->id());
185 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
188 IN_PROC_BROWSER_TEST_F(GcmApiTest, OnMessage) {
189 ResultCatcher catcher;
190 catcher.RestrictToProfile(profile());
192 const extensions::Extension* extension =
193 LoadTestExtension(kEventsExtension, "on_message.html");
194 ASSERT_TRUE(extension);
196 extensions::ExtensionGCMAppHandler app_handler(profile());
198 gcm::GCMClient::IncomingMessage message;
199 message.data["property1"] = "value1";
200 message.data["property2"] = "value2";
201 // First message is sent without a collapse key.
202 app_handler.OnMessage(extension->id(), message);
204 // Second message carries the same data and a collapse key.
205 message.collapse_key = "collapseKeyValue";
206 app_handler.OnMessage(extension->id(), message);
208 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
211 IN_PROC_BROWSER_TEST_F(GcmApiTest, OnSendError) {
212 ResultCatcher catcher;
213 catcher.RestrictToProfile(profile());
215 const extensions::Extension* extension =
216 LoadTestExtension(kEventsExtension, "on_send_error.html");
217 ASSERT_TRUE(extension);
219 std::string total_expected_messages = "5";
220 extensions::ExtensionGCMAppHandler app_handler(profile());
221 app_handler.OnSendError(
223 CreateErrorDetails("error_message_1",
224 gcm::GCMClient::ASYNC_OPERATION_PENDING,
225 total_expected_messages));
226 app_handler.OnSendError(
228 CreateErrorDetails("error_message_2",
229 gcm::GCMClient::SERVER_ERROR,
230 total_expected_messages));
231 app_handler.OnSendError(
233 CreateErrorDetails("error_message_3",
234 gcm::GCMClient::NETWORK_ERROR,
235 total_expected_messages));
236 app_handler.OnSendError(
238 CreateErrorDetails("error_message_4",
239 gcm::GCMClient::UNKNOWN_ERROR,
240 total_expected_messages));
241 app_handler.OnSendError(
243 CreateErrorDetails("error_message_5",
244 gcm::GCMClient::TTL_EXCEEDED,
245 total_expected_messages));
247 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
250 IN_PROC_BROWSER_TEST_F(GcmApiTest, Incognito) {
251 ResultCatcher catcher;
252 catcher.RestrictToProfile(profile());
253 ResultCatcher incognito_catcher;
254 incognito_catcher.RestrictToProfile(profile()->GetOffTheRecordProfile());
256 ASSERT_TRUE(RunExtensionTestIncognito("gcm/functions/incognito"));
258 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
259 EXPECT_TRUE(incognito_catcher.GetNextResult()) << incognito_catcher.message();
262 } // namespace extensions