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_profile_service_factory.h"
13 #include "chrome/common/chrome_switches.h"
14 #include "chrome/common/pref_names.h"
15 #include "chrome/test/base/ui_test_utils.h"
16 #include "extensions/test/result_catcher.h"
18 using extensions::ResultCatcher;
22 const char kEventsExtension[] = "gcm/events";
24 gcm::GCMClient::SendErrorDetails CreateErrorDetails(
25 const std::string& message_id,
26 const gcm::GCMClient::Result result,
27 const std::string& total_messages) {
28 gcm::GCMClient::SendErrorDetails error;
29 error.message_id = message_id;
30 error.result = result;
31 error.additional_data["expectedMessageId"] = message_id;
33 case gcm::GCMClient::ASYNC_OPERATION_PENDING:
34 error.additional_data["expectedErrorMessage"] =
35 "Asynchronous operation is pending.";
37 case gcm::GCMClient::SERVER_ERROR:
38 error.additional_data["expectedErrorMessage"] = "Server error occurred.";
40 case gcm::GCMClient::NETWORK_ERROR:
41 error.additional_data["expectedErrorMessage"] = "Network error occurred.";
43 case gcm::GCMClient::TTL_EXCEEDED:
44 error.additional_data["expectedErrorMessage"] = "Time-to-live exceeded.";
46 case gcm::GCMClient::UNKNOWN_ERROR:
47 default: // Default case is the same as UNKNOWN_ERROR
48 error.additional_data["expectedErrorMessage"] = "Unknown error occurred.";
51 error.additional_data["totalMessages"] = total_messages;
57 namespace extensions {
59 class GcmApiTest : public ExtensionApiTest {
61 GcmApiTest() : fake_gcm_profile_service_(NULL) {}
64 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE;
65 virtual void SetUpOnMainThread() OVERRIDE;
67 void StartCollecting();
69 const Extension* LoadTestExtension(const std::string& extension_path,
70 const std::string& page_name);
71 gcm::FakeGCMProfileService* service() const;
74 gcm::FakeGCMProfileService* fake_gcm_profile_service_;
77 void GcmApiTest::SetUpCommandLine(CommandLine* command_line) {
78 // We now always create the GCMProfileService instance in
79 // ProfileSyncServiceFactory that is called when a profile is being
80 // initialized. In order to prevent it from being created, we add the switch
81 // to disable the sync logic.
82 command_line->AppendSwitch(switches::kDisableSync);
84 ExtensionApiTest::SetUpCommandLine(command_line);
87 void GcmApiTest::SetUpOnMainThread() {
88 // Enable GCM such that tests could be run on all channels.
89 browser()->profile()->GetPrefs()->SetBoolean(prefs::kGCMChannelEnabled, true);
91 gcm::GCMProfileServiceFactory::GetInstance()->SetTestingFactory(
92 browser()->profile(), &gcm::FakeGCMProfileService::Build);
93 fake_gcm_profile_service_ = static_cast<gcm::FakeGCMProfileService*>(
94 gcm::GCMProfileServiceFactory::GetInstance()->GetForProfile(
95 browser()->profile()));
97 ExtensionApiTest::SetUpOnMainThread();
100 void GcmApiTest::StartCollecting() {
101 service()->set_collect(true);
104 gcm::FakeGCMProfileService* GcmApiTest::service() const {
105 return fake_gcm_profile_service_;
108 const Extension* GcmApiTest::LoadTestExtension(
109 const std::string& extension_path,
110 const std::string& page_name) {
111 const Extension* extension =
112 LoadExtension(test_data_dir_.AppendASCII(extension_path));
114 ui_test_utils::NavigateToURL(
115 browser(), extension->GetResourceURL(page_name));
120 IN_PROC_BROWSER_TEST_F(GcmApiTest, RegisterValidation) {
121 ASSERT_TRUE(RunExtensionTest("gcm/functions/register_validation"));
124 IN_PROC_BROWSER_TEST_F(GcmApiTest, Register) {
126 ASSERT_TRUE(RunExtensionTest("gcm/functions/register"));
128 const std::vector<std::string>& sender_ids =
129 service()->last_registered_sender_ids();
130 EXPECT_TRUE(std::find(sender_ids.begin(), sender_ids.end(), "Sender1") !=
132 EXPECT_TRUE(std::find(sender_ids.begin(), sender_ids.end(), "Sender2") !=
136 IN_PROC_BROWSER_TEST_F(GcmApiTest, Unregister) {
137 service()->AddExpectedUnregisterResponse(gcm::GCMClient::SUCCESS);
138 service()->AddExpectedUnregisterResponse(gcm::GCMClient::SERVER_ERROR);
140 ASSERT_TRUE(RunExtensionTest("gcm/functions/unregister"));
143 IN_PROC_BROWSER_TEST_F(GcmApiTest, SendValidation) {
144 ASSERT_TRUE(RunExtensionTest("gcm/functions/send"));
147 IN_PROC_BROWSER_TEST_F(GcmApiTest, SendMessageData) {
149 ASSERT_TRUE(RunExtensionTest("gcm/functions/send_message_data"));
151 EXPECT_EQ("destination-id", service()->last_receiver_id());
152 const gcm::GCMClient::OutgoingMessage& message =
153 service()->last_sent_message();
154 gcm::GCMClient::MessageData::const_iterator iter;
156 EXPECT_EQ(100, message.time_to_live);
158 EXPECT_TRUE((iter = message.data.find("key1")) != message.data.end());
159 EXPECT_EQ("value1", iter->second);
161 EXPECT_TRUE((iter = message.data.find("key2")) != message.data.end());
162 EXPECT_EQ("value2", iter->second);
165 IN_PROC_BROWSER_TEST_F(GcmApiTest, SendMessageDefaultTTL) {
167 ASSERT_TRUE(RunExtensionTest("gcm/functions/send_message_default_ttl"));
169 EXPECT_EQ("destination-id", service()->last_receiver_id());
170 const gcm::GCMClient::OutgoingMessage& message =
171 service()->last_sent_message();
172 gcm::GCMClient::MessageData::const_iterator iter;
174 EXPECT_EQ(gcm::GCMClient::OutgoingMessage::kMaximumTTL, message.time_to_live);
177 IN_PROC_BROWSER_TEST_F(GcmApiTest, OnMessagesDeleted) {
178 ResultCatcher catcher;
179 catcher.RestrictToBrowserContext(profile());
181 const extensions::Extension* extension =
182 LoadTestExtension(kEventsExtension, "on_messages_deleted.html");
183 ASSERT_TRUE(extension);
185 extensions::ExtensionGCMAppHandler app_handler(profile());
186 app_handler.OnMessagesDeleted(extension->id());
187 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
190 IN_PROC_BROWSER_TEST_F(GcmApiTest, OnMessage) {
191 ResultCatcher catcher;
192 catcher.RestrictToBrowserContext(profile());
194 const extensions::Extension* extension =
195 LoadTestExtension(kEventsExtension, "on_message.html");
196 ASSERT_TRUE(extension);
198 extensions::ExtensionGCMAppHandler app_handler(profile());
200 gcm::GCMClient::IncomingMessage message;
201 message.data["property1"] = "value1";
202 message.data["property2"] = "value2";
203 // First message is sent without a collapse key.
204 app_handler.OnMessage(extension->id(), message);
206 // Second message carries the same data and a collapse key.
207 message.collapse_key = "collapseKeyValue";
208 app_handler.OnMessage(extension->id(), message);
210 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
213 IN_PROC_BROWSER_TEST_F(GcmApiTest, OnSendError) {
214 ResultCatcher catcher;
215 catcher.RestrictToBrowserContext(profile());
217 const extensions::Extension* extension =
218 LoadTestExtension(kEventsExtension, "on_send_error.html");
219 ASSERT_TRUE(extension);
221 std::string total_expected_messages = "5";
222 extensions::ExtensionGCMAppHandler app_handler(profile());
223 app_handler.OnSendError(
225 CreateErrorDetails("error_message_1",
226 gcm::GCMClient::ASYNC_OPERATION_PENDING,
227 total_expected_messages));
228 app_handler.OnSendError(
230 CreateErrorDetails("error_message_2",
231 gcm::GCMClient::SERVER_ERROR,
232 total_expected_messages));
233 app_handler.OnSendError(
235 CreateErrorDetails("error_message_3",
236 gcm::GCMClient::NETWORK_ERROR,
237 total_expected_messages));
238 app_handler.OnSendError(
240 CreateErrorDetails("error_message_4",
241 gcm::GCMClient::UNKNOWN_ERROR,
242 total_expected_messages));
243 app_handler.OnSendError(
245 CreateErrorDetails("error_message_5",
246 gcm::GCMClient::TTL_EXCEEDED,
247 total_expected_messages));
249 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
252 IN_PROC_BROWSER_TEST_F(GcmApiTest, Incognito) {
253 ResultCatcher catcher;
254 catcher.RestrictToBrowserContext(profile());
255 ResultCatcher incognito_catcher;
256 incognito_catcher.RestrictToBrowserContext(
257 profile()->GetOffTheRecordProfile());
259 ASSERT_TRUE(RunExtensionTestIncognito("gcm/functions/incognito"));
261 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
262 EXPECT_TRUE(incognito_catcher.GetNextResult()) << incognito_catcher.message();
265 } // namespace extensions