blob: 229feab49888790de8203e40bd22f7a01b41abb1 [file] [log] [blame]
[email protected]848b1b62014-01-30 23:51:041// Copyright 2014 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 "google_apis/gcm/gcm_client_impl.h"
6
7#include "base/files/scoped_temp_dir.h"
8#include "base/message_loop/message_loop.h"
9#include "base/run_loop.h"
10#include "base/test/simple_test_clock.h"
[email protected]c523d202014-03-18 01:34:5411#include "components/os_crypt/os_crypt.h"
[email protected]848b1b62014-01-30 23:51:0412#include "google_apis/gcm/base/mcs_message.h"
13#include "google_apis/gcm/base/mcs_util.h"
14#include "google_apis/gcm/engine/fake_connection_factory.h"
15#include "google_apis/gcm/engine/fake_connection_handler.h"
16#include "google_apis/gcm/protocol/android_checkin.pb.h"
17#include "google_apis/gcm/protocol/checkin.pb.h"
18#include "google_apis/gcm/protocol/mcs.pb.h"
19#include "net/url_request/test_url_fetcher_factory.h"
20#include "net/url_request/url_fetcher_delegate.h"
21#include "net/url_request/url_request_test_util.h"
22#include "testing/gtest/include/gtest/gtest.h"
23
24namespace gcm {
25
26namespace {
27
28enum LastEvent {
29 NONE,
30 LOADING_COMPLETED,
[email protected]848b1b62014-01-30 23:51:0431 REGISTRATION_COMPLETED,
[email protected]e4007042014-02-15 20:34:2832 UNREGISTRATION_COMPLETED,
[email protected]848b1b62014-01-30 23:51:0433 MESSAGE_SEND_ERROR,
34 MESSAGE_RECEIVED,
35 MESSAGES_DELETED,
36};
37
38const uint64 kDeviceAndroidId = 54321;
39const uint64 kDeviceSecurityToken = 12345;
[email protected]3a20a4d2014-03-21 22:54:2140const char kAppId[] = "app_id";
41const char kSender[] = "project_id";
42const char kSender2[] = "project_id2";
43const char kSender3[] = "project_id3";
[email protected]848b1b62014-01-30 23:51:0444const char kRegistrationResponsePrefix[] = "token=";
[email protected]e4007042014-02-15 20:34:2845const char kUnregistrationResponsePrefix[] = "deleted=";
[email protected]848b1b62014-01-30 23:51:0446
47// Helper for building arbitrary data messages.
48MCSMessage BuildDownstreamMessage(
49 const std::string& project_id,
50 const std::string& app_id,
51 const std::map<std::string, std::string>& data) {
52 mcs_proto::DataMessageStanza data_message;
[email protected]848b1b62014-01-30 23:51:0453 data_message.set_from(project_id);
54 data_message.set_category(app_id);
55 for (std::map<std::string, std::string>::const_iterator iter = data.begin();
56 iter != data.end();
57 ++iter) {
58 mcs_proto::AppData* app_data = data_message.add_app_data();
59 app_data->set_key(iter->first);
60 app_data->set_value(iter->second);
61 }
62 return MCSMessage(kDataMessageStanzaTag, data_message);
63}
64
65class FakeMCSClient : public MCSClient {
66 public:
67 FakeMCSClient(base::Clock* clock,
[email protected]2bbe0a682014-03-26 00:08:3168 ConnectionFactory* connection_factory,
69 GCMStore* gcm_store);
[email protected]848b1b62014-01-30 23:51:0470 virtual ~FakeMCSClient();
[email protected]5799d052014-02-12 20:47:3971 virtual void Login(uint64 android_id, uint64 security_token) OVERRIDE;
[email protected]848b1b62014-01-30 23:51:0472 virtual void SendMessage(const MCSMessage& message) OVERRIDE;
[email protected]848b1b62014-01-30 23:51:0473
74 uint64 last_android_id() const { return last_android_id_; }
75 uint64 last_security_token() const { return last_security_token_; }
76 uint8 last_message_tag() const { return last_message_tag_; }
77 const mcs_proto::DataMessageStanza& last_data_message_stanza() const {
78 return last_data_message_stanza_;
79 }
80
81 private:
82 uint64 last_android_id_;
83 uint64 last_security_token_;
84 uint8 last_message_tag_;
85 mcs_proto::DataMessageStanza last_data_message_stanza_;
86};
87
88FakeMCSClient::FakeMCSClient(base::Clock* clock,
[email protected]2bbe0a682014-03-26 00:08:3189 ConnectionFactory* connection_factory,
90 GCMStore* gcm_store)
91 : MCSClient("", clock, connection_factory, gcm_store),
[email protected]848b1b62014-01-30 23:51:0492 last_android_id_(0u),
93 last_security_token_(0u),
94 last_message_tag_(kNumProtoTypes) {
95}
96
97FakeMCSClient::~FakeMCSClient() {
98}
99
[email protected]5799d052014-02-12 20:47:39100void FakeMCSClient::Login(uint64 android_id, uint64 security_token) {
[email protected]848b1b62014-01-30 23:51:04101 last_android_id_ = android_id;
102 last_security_token_ = security_token;
103}
104
105void FakeMCSClient::SendMessage(const MCSMessage& message) {
106 last_message_tag_ = message.tag();
107 if (last_message_tag_ == kDataMessageStanzaTag) {
108 last_data_message_stanza_.CopyFrom(
109 reinterpret_cast<const mcs_proto::DataMessageStanza&>(
110 message.GetProtobuf()));
111 }
112}
113
[email protected]2bbe0a682014-03-26 00:08:31114class FakeGCMInternalsBuilder : public GCMInternalsBuilder {
115 public:
116 FakeGCMInternalsBuilder();
117 virtual ~FakeGCMInternalsBuilder();
118
119 virtual scoped_ptr<base::Clock> BuildClock() OVERRIDE;
120 virtual scoped_ptr<MCSClient> BuildMCSClient(
121 const std::string& version,
122 base::Clock* clock,
123 ConnectionFactory* connection_factory,
124 GCMStore* gcm_store) OVERRIDE;
125 virtual scoped_ptr<ConnectionFactory> BuildConnectionFactory(
126 const std::vector<GURL>& endpoints,
127 const net::BackoffEntry::Policy& backoff_policy,
128 scoped_refptr<net::HttpNetworkSession> network_session,
129 net::NetLog* net_log) OVERRIDE;
130};
131
132FakeGCMInternalsBuilder::FakeGCMInternalsBuilder() {}
133
134FakeGCMInternalsBuilder::~FakeGCMInternalsBuilder() {}
135
136scoped_ptr<base::Clock> FakeGCMInternalsBuilder::BuildClock() {
137 return make_scoped_ptr<base::Clock>(new base::SimpleTestClock());
138}
139
140scoped_ptr<MCSClient> FakeGCMInternalsBuilder::BuildMCSClient(
141 const std::string& version,
142 base::Clock* clock,
143 ConnectionFactory* connection_factory,
144 GCMStore* gcm_store) {
145 return make_scoped_ptr<MCSClient>(new FakeMCSClient(clock,
146 connection_factory,
147 gcm_store));
148}
149
150scoped_ptr<ConnectionFactory> FakeGCMInternalsBuilder::BuildConnectionFactory(
151 const std::vector<GURL>& endpoints,
152 const net::BackoffEntry::Policy& backoff_policy,
153 scoped_refptr<net::HttpNetworkSession> network_session,
154 net::NetLog* net_log) {
155 return make_scoped_ptr<ConnectionFactory>(new FakeConnectionFactory());
156}
157
[email protected]848b1b62014-01-30 23:51:04158} // namespace
159
160class GCMClientImplTest : public testing::Test,
161 public GCMClient::Delegate {
162 public:
163 GCMClientImplTest();
164 virtual ~GCMClientImplTest();
165
166 virtual void SetUp() OVERRIDE;
167
168 void BuildGCMClient();
169 void InitializeGCMClient();
170 void ReceiveMessageFromMCS(const MCSMessage& message);
171 void CompleteCheckin(uint64 android_id, uint64 security_token);
172 void CompleteRegistration(const std::string& registration_id);
[email protected]e4007042014-02-15 20:34:28173 void CompleteUnregistration(const std::string& app_id);
[email protected]848b1b62014-01-30 23:51:04174
[email protected]3a20a4d2014-03-21 22:54:21175 bool ExistsRegistration(const std::string& app_id) const;
176 void AddRegistration(const std::string& app_id,
177 const std::vector<std::string>& sender_ids,
178 const std::string& registration_id);
179
[email protected]848b1b62014-01-30 23:51:04180 // GCMClient::Delegate overrides (for verification).
[email protected]848b1b62014-01-30 23:51:04181 virtual void OnRegisterFinished(const std::string& app_id,
182 const std::string& registration_id,
183 GCMClient::Result result) OVERRIDE;
[email protected]e4007042014-02-15 20:34:28184 virtual void OnUnregisterFinished(const std::string& app_id,
[email protected]0e88e1d12014-03-19 06:53:08185 GCMClient::Result result) OVERRIDE;
[email protected]848b1b62014-01-30 23:51:04186 virtual void OnSendFinished(const std::string& app_id,
187 const std::string& message_id,
188 GCMClient::Result result) OVERRIDE {}
189 virtual void OnMessageReceived(const std::string& registration_id,
190 const GCMClient::IncomingMessage& message)
191 OVERRIDE;
192 virtual void OnMessagesDeleted(const std::string& app_id) OVERRIDE;
[email protected]c6fe36b2014-03-11 10:58:12193 virtual void OnMessageSendError(
194 const std::string& app_id,
195 const gcm::GCMClient::SendErrorDetails& send_error_details) OVERRIDE;
[email protected]86625df2014-01-31 03:47:58196 virtual void OnGCMReady() OVERRIDE;
[email protected]848b1b62014-01-30 23:51:04197
[email protected]848b1b62014-01-30 23:51:04198 GCMClientImpl* gcm_client() const { return gcm_client_.get(); }
199 FakeMCSClient* mcs_client() const {
200 return reinterpret_cast<FakeMCSClient*>(gcm_client_->mcs_client_.get());
201 }
[email protected]2bbe0a682014-03-26 00:08:31202 ConnectionFactory* connection_factory() const {
203 return gcm_client_->connection_factory_.get();
204 }
[email protected]848b1b62014-01-30 23:51:04205
[email protected]3a20a4d2014-03-21 22:54:21206 void reset_last_event() {
207 last_event_ = NONE;
208 last_app_id_.clear();
209 last_registration_id_.clear();
210 last_message_id_.clear();
211 last_result_ = GCMClient::UNKNOWN_ERROR;
212 }
213
[email protected]848b1b62014-01-30 23:51:04214 LastEvent last_event() const { return last_event_; }
215 const std::string& last_app_id() const { return last_app_id_; }
216 const std::string& last_registration_id() const {
217 return last_registration_id_;
218 }
219 const std::string& last_message_id() const { return last_message_id_; }
220 GCMClient::Result last_result() const { return last_result_; }
[email protected]848b1b62014-01-30 23:51:04221 const GCMClient::IncomingMessage& last_message() const {
222 return last_message_;
223 }
[email protected]c6fe36b2014-03-11 10:58:12224 const GCMClient::SendErrorDetails& last_error_details() const {
225 return last_error_details_;
226 }
[email protected]848b1b62014-01-30 23:51:04227
228 int64 CurrentTime();
229
230 private:
231 // Tooling.
232 void PumpLoop();
233 void PumpLoopUntilIdle();
234 void QuitLoop();
235
236 base::SimpleTestClock* clock() const {
237 return reinterpret_cast<base::SimpleTestClock*>(gcm_client_->clock_.get());
238 }
239
240 // Variables used for verification.
241 LastEvent last_event_;
242 std::string last_app_id_;
243 std::string last_registration_id_;
244 std::string last_message_id_;
245 GCMClient::Result last_result_;
[email protected]848b1b62014-01-30 23:51:04246 GCMClient::IncomingMessage last_message_;
[email protected]c6fe36b2014-03-11 10:58:12247 GCMClient::SendErrorDetails last_error_details_;
[email protected]848b1b62014-01-30 23:51:04248
249 scoped_ptr<GCMClientImpl> gcm_client_;
[email protected]848b1b62014-01-30 23:51:04250
251 base::MessageLoop message_loop_;
252 scoped_ptr<base::RunLoop> run_loop_;
253 net::TestURLFetcherFactory url_fetcher_factory_;
254
255 // Injected to GCM client:
256 base::ScopedTempDir temp_directory_;
257 scoped_refptr<net::TestURLRequestContextGetter> url_request_context_getter_;
258};
259
260GCMClientImplTest::GCMClientImplTest()
261 : last_event_(NONE),
262 last_result_(GCMClient::UNKNOWN_ERROR),
263 url_request_context_getter_(new net::TestURLRequestContextGetter(
264 message_loop_.message_loop_proxy())) {
265}
266
267GCMClientImplTest::~GCMClientImplTest() {}
268
269void GCMClientImplTest::SetUp() {
270 ASSERT_TRUE(temp_directory_.CreateUniqueTempDir());
271 run_loop_.reset(new base::RunLoop);
272 BuildGCMClient();
273 InitializeGCMClient();
[email protected]3a20a4d2014-03-21 22:54:21274 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken);
[email protected]848b1b62014-01-30 23:51:04275}
276
277void GCMClientImplTest::PumpLoop() {
278 run_loop_->Run();
279 run_loop_.reset(new base::RunLoop());
280}
281
282void GCMClientImplTest::PumpLoopUntilIdle() {
283 run_loop_->RunUntilIdle();
284 run_loop_.reset(new base::RunLoop());
285}
286
287void GCMClientImplTest::QuitLoop() {
288 if (run_loop_ && run_loop_->running())
289 run_loop_->Quit();
290}
291
292void GCMClientImplTest::BuildGCMClient() {
[email protected]2bbe0a682014-03-26 00:08:31293 gcm_client_.reset(new GCMClientImpl(
294 make_scoped_ptr<GCMInternalsBuilder>(new FakeGCMInternalsBuilder())));
[email protected]848b1b62014-01-30 23:51:04295}
296
297void GCMClientImplTest::CompleteCheckin(uint64 android_id,
298 uint64 security_token) {
299 checkin_proto::AndroidCheckinResponse response;
300 response.set_stats_ok(true);
301 response.set_android_id(android_id);
302 response.set_security_token(security_token);
303
304 std::string response_string;
305 response.SerializeToString(&response_string);
306
307 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
308 ASSERT_TRUE(fetcher);
309 fetcher->set_response_code(net::HTTP_OK);
310 fetcher->SetResponseString(response_string);
311 fetcher->delegate()->OnURLFetchComplete(fetcher);
312 url_fetcher_factory_.RemoveFetcherFromMap(0);
313}
314
315void GCMClientImplTest::CompleteRegistration(
316 const std::string& registration_id) {
317 std::string response(kRegistrationResponsePrefix);
318 response.append(registration_id);
319 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
320 ASSERT_TRUE(fetcher);
321 fetcher->set_response_code(net::HTTP_OK);
322 fetcher->SetResponseString(response);
323 fetcher->delegate()->OnURLFetchComplete(fetcher);
[email protected]3a20a4d2014-03-21 22:54:21324 url_fetcher_factory_.RemoveFetcherFromMap(0);
[email protected]e4007042014-02-15 20:34:28325}
326
327void GCMClientImplTest::CompleteUnregistration(
328 const std::string& app_id) {
329 std::string response(kUnregistrationResponsePrefix);
330 response.append(app_id);
331 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
332 ASSERT_TRUE(fetcher);
333 fetcher->set_response_code(net::HTTP_OK);
334 fetcher->SetResponseString(response);
335 fetcher->delegate()->OnURLFetchComplete(fetcher);
[email protected]3a20a4d2014-03-21 22:54:21336 url_fetcher_factory_.RemoveFetcherFromMap(0);
337}
338
339bool GCMClientImplTest::ExistsRegistration(const std::string& app_id) const {
340 return gcm_client_->registrations_.count(app_id) > 0;
341}
342
343void GCMClientImplTest::AddRegistration(
344 const std::string& app_id,
345 const std::vector<std::string>& sender_ids,
346 const std::string& registration_id) {
347 linked_ptr<RegistrationInfo> registration(new RegistrationInfo);
348 registration->sender_ids = sender_ids;
349 registration->registration_id = registration_id;
350 gcm_client_->registrations_[app_id] = registration;
[email protected]848b1b62014-01-30 23:51:04351}
352
353void GCMClientImplTest::InitializeGCMClient() {
[email protected]848b1b62014-01-30 23:51:04354 clock()->Advance(base::TimeDelta::FromMilliseconds(1));
[email protected]2bbe0a682014-03-26 00:08:31355
[email protected]848b1b62014-01-30 23:51:04356 // Actual initialization.
357 checkin_proto::ChromeBuildProto chrome_build_proto;
358 gcm_client_->Initialize(chrome_build_proto,
359 temp_directory_.path(),
[email protected]495a7db92014-02-22 07:49:59360 std::vector<std::string>(),
[email protected]848b1b62014-01-30 23:51:04361 message_loop_.message_loop_proxy(),
[email protected]5799d052014-02-12 20:47:39362 url_request_context_getter_,
363 this);
[email protected]d3a4b2e2014-02-27 13:46:54364
[email protected]0693d5162014-02-12 00:20:17365#if defined(OS_MACOSX)
366 // On OSX, prevent the Keychain permissions popup during unit tests.
[email protected]92cdb1ca2014-02-28 18:34:10367 OSCrypt::UseMockKeychain(true); // Must be after Initialize.
[email protected]0693d5162014-02-12 00:20:17368#endif
[email protected]d3a4b2e2014-02-27 13:46:54369
[email protected]2bbe0a682014-03-26 00:08:31370 // Start loading and check-in.
[email protected]d3a4b2e2014-02-27 13:46:54371 gcm_client_->Load();
372
[email protected]848b1b62014-01-30 23:51:04373 PumpLoopUntilIdle();
[email protected]848b1b62014-01-30 23:51:04374}
375
376void GCMClientImplTest::ReceiveMessageFromMCS(const MCSMessage& message) {
377 gcm_client_->OnMessageReceivedFromMCS(message);
378}
379
[email protected]86625df2014-01-31 03:47:58380void GCMClientImplTest::OnGCMReady() {
[email protected]848b1b62014-01-30 23:51:04381 last_event_ = LOADING_COMPLETED;
382 QuitLoop();
383}
384
[email protected]848b1b62014-01-30 23:51:04385void GCMClientImplTest::OnMessageReceived(
386 const std::string& registration_id,
387 const GCMClient::IncomingMessage& message) {
388 last_event_ = MESSAGE_RECEIVED;
389 last_app_id_ = registration_id;
390 last_message_ = message;
391 QuitLoop();
392}
393
394void GCMClientImplTest::OnRegisterFinished(const std::string& app_id,
395 const std::string& registration_id,
396 GCMClient::Result result) {
397 last_event_ = REGISTRATION_COMPLETED;
398 last_app_id_ = app_id;
399 last_registration_id_ = registration_id;
400 last_result_ = result;
401}
402
[email protected]e4007042014-02-15 20:34:28403void GCMClientImplTest::OnUnregisterFinished(const std::string& app_id,
[email protected]0e88e1d12014-03-19 06:53:08404 GCMClient::Result result) {
[email protected]e4007042014-02-15 20:34:28405 last_event_ = UNREGISTRATION_COMPLETED;
406 last_app_id_ = app_id;
[email protected]0e88e1d12014-03-19 06:53:08407 last_result_ = result;
[email protected]e4007042014-02-15 20:34:28408}
409
[email protected]848b1b62014-01-30 23:51:04410void GCMClientImplTest::OnMessagesDeleted(const std::string& app_id) {
411 last_event_ = MESSAGES_DELETED;
412 last_app_id_ = app_id;
413}
414
[email protected]c6fe36b2014-03-11 10:58:12415void GCMClientImplTest::OnMessageSendError(
416 const std::string& app_id,
417 const gcm::GCMClient::SendErrorDetails& send_error_details) {
[email protected]848b1b62014-01-30 23:51:04418 last_event_ = MESSAGE_SEND_ERROR;
419 last_app_id_ = app_id;
[email protected]c6fe36b2014-03-11 10:58:12420 last_error_details_ = send_error_details;
[email protected]848b1b62014-01-30 23:51:04421}
422
423int64 GCMClientImplTest::CurrentTime() {
424 return clock()->Now().ToInternalValue() / base::Time::kMicrosecondsPerSecond;
425}
426
[email protected]848b1b62014-01-30 23:51:04427TEST_F(GCMClientImplTest, LoadingCompleted) {
428 EXPECT_EQ(LOADING_COMPLETED, last_event());
429 EXPECT_EQ(kDeviceAndroidId, mcs_client()->last_android_id());
430 EXPECT_EQ(kDeviceSecurityToken, mcs_client()->last_security_token());
431}
432
[email protected]8e3ee1da2014-02-13 05:21:03433TEST_F(GCMClientImplTest, CheckOut) {
434 EXPECT_TRUE(mcs_client());
[email protected]2bbe0a682014-03-26 00:08:31435 EXPECT_TRUE(connection_factory());
[email protected]8e3ee1da2014-02-13 05:21:03436 gcm_client()->CheckOut();
437 EXPECT_FALSE(mcs_client());
[email protected]2bbe0a682014-03-26 00:08:31438 EXPECT_FALSE(connection_factory());
[email protected]8e3ee1da2014-02-13 05:21:03439}
440
[email protected]848b1b62014-01-30 23:51:04441TEST_F(GCMClientImplTest, RegisterApp) {
[email protected]3a20a4d2014-03-21 22:54:21442 EXPECT_FALSE(ExistsRegistration(kAppId));
443
[email protected]848b1b62014-01-30 23:51:04444 std::vector<std::string> senders;
445 senders.push_back("sender");
[email protected]3a20a4d2014-03-21 22:54:21446 gcm_client()->Register(kAppId, senders);
[email protected]848b1b62014-01-30 23:51:04447 CompleteRegistration("reg_id");
448
449 EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
[email protected]3a20a4d2014-03-21 22:54:21450 EXPECT_EQ(kAppId, last_app_id());
[email protected]848b1b62014-01-30 23:51:04451 EXPECT_EQ("reg_id", last_registration_id());
452 EXPECT_EQ(GCMClient::SUCCESS, last_result());
[email protected]3a20a4d2014-03-21 22:54:21453 EXPECT_TRUE(ExistsRegistration(kAppId));
454}
455
[email protected]3904d2b2014-03-22 01:34:31456TEST_F(GCMClientImplTest, DISABLED_RegisterAppFromCache) {
[email protected]3a20a4d2014-03-21 22:54:21457 EXPECT_FALSE(ExistsRegistration(kAppId));
458
459 std::vector<std::string> senders;
460 senders.push_back("sender");
461 gcm_client()->Register(kAppId, senders);
462 CompleteRegistration("reg_id");
463 EXPECT_TRUE(ExistsRegistration(kAppId));
464
465 EXPECT_EQ(kAppId, last_app_id());
466 EXPECT_EQ("reg_id", last_registration_id());
467 EXPECT_EQ(GCMClient::SUCCESS, last_result());
468 EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
469
470 // Recreate GCMClient in order to load from the persistent store.
471 BuildGCMClient();
472 InitializeGCMClient();
473
474 EXPECT_TRUE(ExistsRegistration(kAppId));
[email protected]848b1b62014-01-30 23:51:04475}
476
[email protected]e4007042014-02-15 20:34:28477TEST_F(GCMClientImplTest, UnregisterApp) {
[email protected]3a20a4d2014-03-21 22:54:21478 EXPECT_FALSE(ExistsRegistration(kAppId));
479
480 std::vector<std::string> senders;
481 senders.push_back("sender");
482 gcm_client()->Register(kAppId, senders);
483 CompleteRegistration("reg_id");
484 EXPECT_TRUE(ExistsRegistration(kAppId));
485
486 gcm_client()->Unregister(kAppId);
487 CompleteUnregistration(kAppId);
[email protected]e4007042014-02-15 20:34:28488
489 EXPECT_EQ(UNREGISTRATION_COMPLETED, last_event());
[email protected]3a20a4d2014-03-21 22:54:21490 EXPECT_EQ(kAppId, last_app_id());
[email protected]e4007042014-02-15 20:34:28491 EXPECT_EQ(GCMClient::SUCCESS, last_result());
[email protected]3a20a4d2014-03-21 22:54:21492 EXPECT_FALSE(ExistsRegistration(kAppId));
[email protected]e4007042014-02-15 20:34:28493}
494
[email protected]848b1b62014-01-30 23:51:04495TEST_F(GCMClientImplTest, DispatchDownstreamMessage) {
[email protected]3a20a4d2014-03-21 22:54:21496 // Register to receive messages from kSender and kSender2 only.
497 std::vector<std::string> senders;
498 senders.push_back(kSender);
499 senders.push_back(kSender2);
500 AddRegistration(kAppId, senders, "reg_id");
501
[email protected]848b1b62014-01-30 23:51:04502 std::map<std::string, std::string> expected_data;
503 expected_data["message_type"] = "gcm";
504 expected_data["key"] = "value";
505 expected_data["key2"] = "value2";
[email protected]3a20a4d2014-03-21 22:54:21506
507 // Message for kSender will be received.
508 MCSMessage message(BuildDownstreamMessage(kSender, kAppId, expected_data));
[email protected]848b1b62014-01-30 23:51:04509 EXPECT_TRUE(message.IsValid());
510 ReceiveMessageFromMCS(message);
511
512 expected_data.erase(expected_data.find("message_type"));
513 EXPECT_EQ(MESSAGE_RECEIVED, last_event());
[email protected]3a20a4d2014-03-21 22:54:21514 EXPECT_EQ(kAppId, last_app_id());
[email protected]848b1b62014-01-30 23:51:04515 EXPECT_EQ(expected_data.size(), last_message().data.size());
516 EXPECT_EQ(expected_data, last_message().data);
[email protected]3a20a4d2014-03-21 22:54:21517 EXPECT_EQ(kSender, last_message().sender_id);
518
519 reset_last_event();
520
521 // Message for kSender2 will be received.
522 MCSMessage message2(BuildDownstreamMessage(kSender2, kAppId, expected_data));
523 EXPECT_TRUE(message2.IsValid());
524 ReceiveMessageFromMCS(message2);
525
526 EXPECT_EQ(MESSAGE_RECEIVED, last_event());
527 EXPECT_EQ(kAppId, last_app_id());
528 EXPECT_EQ(expected_data.size(), last_message().data.size());
529 EXPECT_EQ(expected_data, last_message().data);
530 EXPECT_EQ(kSender2, last_message().sender_id);
531
532 reset_last_event();
533
534 // Message from kSender3 will be dropped.
535 MCSMessage message3(BuildDownstreamMessage(kSender3, kAppId, expected_data));
536 EXPECT_TRUE(message3.IsValid());
537 ReceiveMessageFromMCS(message3);
538
539 EXPECT_NE(MESSAGE_RECEIVED, last_event());
540 EXPECT_NE(kAppId, last_app_id());
[email protected]848b1b62014-01-30 23:51:04541}
542
543TEST_F(GCMClientImplTest, DispatchDownstreamMessageSendError) {
544 std::map<std::string, std::string> expected_data;
545 expected_data["message_type"] = "send_error";
546 expected_data["google.message_id"] = "007";
[email protected]c6fe36b2014-03-11 10:58:12547 expected_data["error_details"] = "some details";
[email protected]848b1b62014-01-30 23:51:04548 MCSMessage message(BuildDownstreamMessage(
[email protected]3a20a4d2014-03-21 22:54:21549 kSender, kAppId, expected_data));
[email protected]848b1b62014-01-30 23:51:04550 EXPECT_TRUE(message.IsValid());
551 ReceiveMessageFromMCS(message);
552
553 EXPECT_EQ(MESSAGE_SEND_ERROR, last_event());
[email protected]3a20a4d2014-03-21 22:54:21554 EXPECT_EQ(kAppId, last_app_id());
[email protected]c6fe36b2014-03-11 10:58:12555 EXPECT_EQ("007", last_error_details().message_id);
556 EXPECT_EQ(1UL, last_error_details().additional_data.size());
557 GCMClient::MessageData::const_iterator iter =
558 last_error_details().additional_data.find("error_details");
559 EXPECT_TRUE(iter != last_error_details().additional_data.end());
560 EXPECT_EQ("some details", iter->second);
[email protected]848b1b62014-01-30 23:51:04561}
562
563TEST_F(GCMClientImplTest, DispatchDownstreamMessgaesDeleted) {
564 std::map<std::string, std::string> expected_data;
565 expected_data["message_type"] = "deleted_messages";
566 MCSMessage message(BuildDownstreamMessage(
[email protected]3a20a4d2014-03-21 22:54:21567 kSender, kAppId, expected_data));
[email protected]848b1b62014-01-30 23:51:04568 EXPECT_TRUE(message.IsValid());
569 ReceiveMessageFromMCS(message);
570
571 EXPECT_EQ(MESSAGES_DELETED, last_event());
[email protected]3a20a4d2014-03-21 22:54:21572 EXPECT_EQ(kAppId, last_app_id());
[email protected]848b1b62014-01-30 23:51:04573}
574
575TEST_F(GCMClientImplTest, SendMessage) {
576 mcs_proto::DataMessageStanza stanza;
577 stanza.set_ttl(500);
578
579 GCMClient::OutgoingMessage message;
580 message.id = "007";
581 message.time_to_live = 500;
582 message.data["key"] = "value";
[email protected]3a20a4d2014-03-21 22:54:21583 gcm_client()->Send(kAppId, kSender, message);
[email protected]848b1b62014-01-30 23:51:04584
585 EXPECT_EQ(kDataMessageStanzaTag, mcs_client()->last_message_tag());
[email protected]3a20a4d2014-03-21 22:54:21586 EXPECT_EQ(kAppId, mcs_client()->last_data_message_stanza().category());
587 EXPECT_EQ(kSender, mcs_client()->last_data_message_stanza().to());
[email protected]848b1b62014-01-30 23:51:04588 EXPECT_EQ(500, mcs_client()->last_data_message_stanza().ttl());
589 EXPECT_EQ(CurrentTime(), mcs_client()->last_data_message_stanza().sent());
590 EXPECT_EQ("007", mcs_client()->last_data_message_stanza().id());
[email protected]848b1b62014-01-30 23:51:04591 EXPECT_EQ("[email protected]", mcs_client()->last_data_message_stanza().from());
[email protected]3a20a4d2014-03-21 22:54:21592 EXPECT_EQ(kSender, mcs_client()->last_data_message_stanza().to());
[email protected]848b1b62014-01-30 23:51:04593 EXPECT_EQ("key", mcs_client()->last_data_message_stanza().app_data(0).key());
594 EXPECT_EQ("value",
595 mcs_client()->last_data_message_stanza().app_data(0).value());
596}
597
598} // namespace gcm