1 // 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.
5 #include "components/gcm_driver/gcm_account_mapper.h"
8 #include "base/test/simple_test_clock.h"
9 #include "base/time/time.h"
10 #include "components/gcm_driver/fake_gcm_driver.h"
11 #include "google_apis/gcm/engine/account_mapping.h"
12 #include "google_apis/gcm/engine/gcm_store.h"
13 #include "testing/gtest/include/gtest/gtest.h"
19 const char kGCMAccountMapperSenderId
[] = "745476177629";
20 const char kGCMAccountMapperSendTo
[] = "google.com";
21 const char kRegistrationId
[] = "reg_id";
22 const char kEmbeddedAppIdKey
[] = "gcmb";
23 const char kTestAppId
[] = "test_app_id";
24 const char kTestDataKey
[] = "data_key";
25 const char kTestDataValue
[] = "data_value";
26 const char kTestCollapseKey
[] = "test_collapse_key";
27 const char kTestSenderId
[] = "test_sender_id";
30 AccountMapping
MakeAccountMapping(const std::string
& account_id
,
31 AccountMapping::MappingStatus status
,
32 const base::Time
& status_change_timestamp
,
33 const std::string
& last_message_id
) {
34 AccountMapping account_mapping
;
35 account_mapping
.account_id
= account_id
;
36 account_mapping
.email
= account_id
+ "@gmail.com";
37 // account_mapping.access_token intentionally left empty.
38 account_mapping
.status
= status
;
39 account_mapping
.status_change_timestamp
= status_change_timestamp
;
40 account_mapping
.last_message_id
= last_message_id
;
41 return account_mapping
;
44 GCMClient::AccountTokenInfo
MakeAccountTokenInfo(
45 const std::string
& account_id
) {
46 GCMClient::AccountTokenInfo account_token
;
47 account_token
.account_id
= account_id
;
48 account_token
.email
= account_id
+ "@gmail.com";
49 account_token
.access_token
= account_id
+ "_token";
53 void VerifyMappings(const GCMAccountMapper::AccountMappings
& expected_mappings
,
54 const GCMAccountMapper::AccountMappings
& actual_mappings
,
55 const std::string
& verification_info
) {
56 EXPECT_EQ(expected_mappings
.size(), actual_mappings
.size())
57 << "Verification Info: " << verification_info
;
58 GCMAccountMapper::AccountMappings::const_iterator expected_iter
=
59 expected_mappings
.begin();
60 GCMAccountMapper::AccountMappings::const_iterator actual_iter
=
61 actual_mappings
.begin();
62 for (; expected_iter
!= expected_mappings
.end() &&
63 actual_iter
!= actual_mappings
.end();
64 ++expected_iter
, ++actual_iter
) {
65 EXPECT_EQ(expected_iter
->email
, actual_iter
->email
)
66 << "Verification Info: " << verification_info
67 << "; Account ID of expected: " << expected_iter
->account_id
;
68 EXPECT_EQ(expected_iter
->account_id
, actual_iter
->account_id
)
69 << "Verification Info: " << verification_info
;
70 EXPECT_EQ(expected_iter
->status
, actual_iter
->status
)
71 << "Verification Info: " << verification_info
72 << "; Account ID of expected: " << expected_iter
->account_id
;
73 EXPECT_EQ(expected_iter
->status_change_timestamp
,
74 actual_iter
->status_change_timestamp
)
75 << "Verification Info: " << verification_info
76 << "; Account ID of expected: " << expected_iter
->account_id
;
80 class CustomFakeGCMDriver
: public FakeGCMDriver
{
82 enum LastMessageAction
{
89 CustomFakeGCMDriver();
90 ~CustomFakeGCMDriver() override
;
92 // GCMDriver implementation:
93 void UpdateAccountMapping(const AccountMapping
& account_mapping
) override
;
94 void RemoveAccountMapping(const std::string
& account_id
) override
;
95 void AddAppHandler(const std::string
& app_id
,
96 GCMAppHandler
* handler
) override
;
97 void RemoveAppHandler(const std::string
& app_id
) override
;
98 void RegisterImpl(const std::string
& app_id
,
99 const std::vector
<std::string
>& sender_ids
) override
;
101 void CompleteRegister(const std::string
& registration_id
,
102 GCMClient::Result result
);
103 void CompleteSend(const std::string
& message_id
, GCMClient::Result result
);
104 void AcknowledgeSend(const std::string
& message_id
);
105 void MessageSendError(const std::string
& message_id
);
107 void CompleteSendAllMessages();
108 void AcknowledgeSendAllMessages();
109 void SetLastMessageAction(const std::string
& message_id
,
110 LastMessageAction action
);
113 const AccountMapping
& last_account_mapping() const {
114 return account_mapping_
;
116 const std::string
& last_message_id() const { return last_message_id_
; }
117 const std::string
& last_removed_account_id() const {
118 return last_removed_account_id_
;
120 LastMessageAction
last_action() const { return last_action_
; }
121 bool registration_id_requested() const { return registration_id_requested_
; }
124 void SendImpl(const std::string
& app_id
,
125 const std::string
& receiver_id
,
126 const OutgoingMessage
& message
) override
;
129 AccountMapping account_mapping_
;
130 std::string last_message_id_
;
131 std::string last_removed_account_id_
;
132 LastMessageAction last_action_
;
133 std::map
<std::string
, LastMessageAction
> all_messages_
;
134 bool registration_id_requested_
;
137 CustomFakeGCMDriver::CustomFakeGCMDriver()
138 : last_action_(NONE
), registration_id_requested_(false) {
141 CustomFakeGCMDriver::~CustomFakeGCMDriver() {
144 void CustomFakeGCMDriver::UpdateAccountMapping(
145 const AccountMapping
& account_mapping
) {
146 account_mapping_
.email
= account_mapping
.email
;
147 account_mapping_
.account_id
= account_mapping
.account_id
;
148 account_mapping_
.access_token
= account_mapping
.access_token
;
149 account_mapping_
.status
= account_mapping
.status
;
150 account_mapping_
.status_change_timestamp
=
151 account_mapping
.status_change_timestamp
;
152 account_mapping_
.last_message_id
= account_mapping
.last_message_id
;
155 void CustomFakeGCMDriver::RemoveAccountMapping(const std::string
& account_id
) {
156 last_removed_account_id_
= account_id
;
159 void CustomFakeGCMDriver::AddAppHandler(const std::string
& app_id
,
160 GCMAppHandler
* handler
) {
161 GCMDriver::AddAppHandler(app_id
, handler
);
164 void CustomFakeGCMDriver::RemoveAppHandler(const std::string
& app_id
) {
165 GCMDriver::RemoveAppHandler(app_id
);
168 void CustomFakeGCMDriver::RegisterImpl(
169 const std::string
& app_id
,
170 const std::vector
<std::string
>& sender_ids
) {
171 DCHECK_EQ(kGCMAccountMapperAppId
, app_id
);
172 DCHECK_EQ(1u, sender_ids
.size());
173 DCHECK_EQ(kGCMAccountMapperSenderId
, sender_ids
[0]);
174 registration_id_requested_
= true;
177 void CustomFakeGCMDriver::CompleteRegister(const std::string
& registration_id
,
178 GCMClient::Result result
) {
179 RegisterFinished(kGCMAccountMapperAppId
, registration_id
, result
);
182 void CustomFakeGCMDriver::CompleteSend(const std::string
& message_id
,
183 GCMClient::Result result
) {
184 SendFinished(kGCMAccountMapperAppId
, message_id
, result
);
185 SetLastMessageAction(message_id
, SEND_FINISHED
);
188 void CustomFakeGCMDriver::AcknowledgeSend(const std::string
& message_id
) {
189 GetAppHandler(kGCMAccountMapperAppId
)
190 ->OnSendAcknowledged(kGCMAccountMapperAppId
, message_id
);
191 SetLastMessageAction(message_id
, SEND_ACKNOWLEDGED
);
194 void CustomFakeGCMDriver::MessageSendError(const std::string
& message_id
) {
195 GCMClient::SendErrorDetails send_error
;
196 send_error
.message_id
= message_id
;
197 send_error
.result
= GCMClient::TTL_EXCEEDED
;
198 GetAppHandler(kGCMAccountMapperAppId
)
199 ->OnSendError(kGCMAccountMapperAppId
, send_error
);
202 void CustomFakeGCMDriver::SendImpl(const std::string
& app_id
,
203 const std::string
& receiver_id
,
204 const OutgoingMessage
& message
) {
205 DCHECK_EQ(kGCMAccountMapperAppId
, app_id
);
206 DCHECK_EQ(kGCMAccountMapperSendTo
, receiver_id
);
208 SetLastMessageAction(message
.id
, SEND_STARTED
);
211 void CustomFakeGCMDriver::CompleteSendAllMessages() {
212 for (std::map
<std::string
, LastMessageAction
>::const_iterator iter
=
213 all_messages_
.begin();
214 iter
!= all_messages_
.end();
216 if (iter
->second
== SEND_STARTED
)
217 CompleteSend(iter
->first
, GCMClient::SUCCESS
);
221 void CustomFakeGCMDriver::AcknowledgeSendAllMessages() {
222 for (std::map
<std::string
, LastMessageAction
>::const_iterator iter
=
223 all_messages_
.begin();
224 iter
!= all_messages_
.end();
226 if (iter
->second
== SEND_FINISHED
)
227 AcknowledgeSend(iter
->first
);
231 void CustomFakeGCMDriver::Clear() {
232 account_mapping_
= AccountMapping();
233 last_message_id_
.clear();
234 last_removed_account_id_
.clear();
236 registration_id_requested_
= false;
239 void CustomFakeGCMDriver::SetLastMessageAction(const std::string
& message_id
,
240 LastMessageAction action
) {
241 last_action_
= action
;
242 last_message_id_
= message_id
;
243 all_messages_
[message_id
] = action
;
248 class GCMAccountMapperTest
: public testing::Test
{
250 GCMAccountMapperTest();
251 ~GCMAccountMapperTest() override
;
255 void Initialize(const GCMAccountMapper::AccountMappings mappings
);
256 const GCMAccountMapper::AccountMappings
& GetAccounts() const {
257 return account_mapper_
->accounts_
;
259 void MessageReceived(const std::string
& app_id
,
260 const IncomingMessage
& message
);
262 GCMAccountMapper
* mapper() { return account_mapper_
.get(); }
264 CustomFakeGCMDriver
& gcm_driver() { return gcm_driver_
; }
266 base::SimpleTestClock
* clock() { return clock_
; }
267 const std::string
& last_received_app_id() const {
268 return last_received_app_id_
;
270 const IncomingMessage
& last_received_message() const {
271 return last_received_message_
;
275 CustomFakeGCMDriver gcm_driver_
;
276 scoped_ptr
<GCMAccountMapper
> account_mapper_
;
277 base::SimpleTestClock
* clock_
;
278 std::string last_received_app_id_
;
279 IncomingMessage last_received_message_
;
282 GCMAccountMapperTest::GCMAccountMapperTest() {
286 GCMAccountMapperTest::~GCMAccountMapperTest() {
289 void GCMAccountMapperTest::Restart() {
291 account_mapper_
->ShutdownHandler();
292 gcm_driver_
.RemoveAppHandler(kGCMAccountMapperAppId
);
293 account_mapper_
.reset(new GCMAccountMapper(&gcm_driver_
));
294 scoped_ptr
<base::SimpleTestClock
> clock(new base::SimpleTestClock
);
295 clock_
= clock
.get();
296 account_mapper_
->SetClockForTesting(clock
.Pass());
299 void GCMAccountMapperTest::Initialize(
300 const GCMAccountMapper::AccountMappings mappings
) {
301 mapper()->Initialize(mappings
,
302 base::Bind(&GCMAccountMapperTest::MessageReceived
,
303 base::Unretained(this)));
306 void GCMAccountMapperTest::MessageReceived(const std::string
& app_id
,
307 const IncomingMessage
& message
) {
308 last_received_app_id_
= app_id
;
309 last_received_message_
= message
;
312 // Tests the initialization of account mappings (from the store) when empty.
313 // It also checks that initialization triggers registration ID request.
314 TEST_F(GCMAccountMapperTest
, InitializeAccountMappingsEmpty
) {
315 EXPECT_FALSE(gcm_driver().registration_id_requested());
316 Initialize(GCMAccountMapper::AccountMappings());
317 EXPECT_TRUE(GetAccounts().empty());
318 EXPECT_TRUE(gcm_driver().registration_id_requested());
321 // Tests that registration is retried, when new tokens are delivered and in no
322 // other circumstances.
323 TEST_F(GCMAccountMapperTest
, RegistrationRetryUponFailure
) {
324 Initialize(GCMAccountMapper::AccountMappings());
325 EXPECT_TRUE(gcm_driver().registration_id_requested());
326 gcm_driver().Clear();
328 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::UNKNOWN_ERROR
);
329 EXPECT_FALSE(gcm_driver().registration_id_requested());
330 gcm_driver().Clear();
332 std::vector
<GCMClient::AccountTokenInfo
> account_tokens
;
333 account_tokens
.push_back(MakeAccountTokenInfo("acc_id2"));
334 mapper()->SetAccountTokens(account_tokens
);
335 EXPECT_TRUE(gcm_driver().registration_id_requested());
336 gcm_driver().Clear();
338 gcm_driver().CompleteRegister(kRegistrationId
,
339 GCMClient::ASYNC_OPERATION_PENDING
);
340 EXPECT_FALSE(gcm_driver().registration_id_requested());
343 // Tests the initialization of account mappings (from the store).
344 TEST_F(GCMAccountMapperTest
, InitializeAccountMappings
) {
345 GCMAccountMapper::AccountMappings account_mappings
;
346 AccountMapping account_mapping1
= MakeAccountMapping("acc_id1",
347 AccountMapping::MAPPED
,
350 AccountMapping account_mapping2
= MakeAccountMapping("acc_id2",
351 AccountMapping::ADDING
,
354 account_mappings
.push_back(account_mapping1
);
355 account_mappings
.push_back(account_mapping2
);
357 Initialize(account_mappings
);
359 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
360 EXPECT_EQ(2UL, mappings
.size());
361 GCMAccountMapper::AccountMappings::const_iterator iter
= mappings
.begin();
363 EXPECT_EQ(account_mapping1
.account_id
, iter
->account_id
);
364 EXPECT_EQ(account_mapping1
.email
, iter
->email
);
365 EXPECT_TRUE(account_mapping1
.access_token
.empty());
366 EXPECT_EQ(account_mapping1
.status
, iter
->status
);
367 EXPECT_EQ(account_mapping1
.status_change_timestamp
,
368 iter
->status_change_timestamp
);
369 EXPECT_TRUE(account_mapping1
.last_message_id
.empty());
372 EXPECT_EQ(account_mapping2
.account_id
, iter
->account_id
);
373 EXPECT_EQ(account_mapping2
.email
, iter
->email
);
374 EXPECT_TRUE(account_mapping2
.access_token
.empty());
375 EXPECT_EQ(account_mapping2
.status
, iter
->status
);
376 EXPECT_EQ(account_mapping2
.status_change_timestamp
,
377 iter
->status_change_timestamp
);
378 EXPECT_EQ(account_mapping2
.last_message_id
, iter
->last_message_id
);
381 // Tests that account tokens are not processed until registration ID is
383 TEST_F(GCMAccountMapperTest
, SetAccountTokensOnlyWorksWithRegisterationId
) {
384 // Start with empty list.
385 Initialize(GCMAccountMapper::AccountMappings());
387 std::vector
<GCMClient::AccountTokenInfo
> account_tokens
;
388 account_tokens
.push_back(MakeAccountTokenInfo("acc_id"));
389 mapper()->SetAccountTokens(account_tokens
);
391 EXPECT_TRUE(GetAccounts().empty());
393 account_tokens
.clear();
394 account_tokens
.push_back(MakeAccountTokenInfo("acc_id1"));
395 account_tokens
.push_back(MakeAccountTokenInfo("acc_id2"));
396 mapper()->SetAccountTokens(account_tokens
);
398 EXPECT_TRUE(GetAccounts().empty());
400 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
402 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
403 EXPECT_EQ(2UL, mappings
.size());
404 EXPECT_EQ("acc_id1", mappings
[0].account_id
);
405 EXPECT_EQ("acc_id2", mappings
[1].account_id
);
408 // Tests the part where a new account is added with a token, to the point when
409 // GCM message is sent.
410 TEST_F(GCMAccountMapperTest
, AddMappingToMessageSent
) {
411 Initialize(GCMAccountMapper::AccountMappings());
412 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
414 std::vector
<GCMClient::AccountTokenInfo
> account_tokens
;
415 GCMClient::AccountTokenInfo account_token
= MakeAccountTokenInfo("acc_id");
416 account_tokens
.push_back(account_token
);
417 mapper()->SetAccountTokens(account_tokens
);
419 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
420 EXPECT_EQ(1UL, mappings
.size());
421 GCMAccountMapper::AccountMappings::const_iterator iter
= mappings
.begin();
422 EXPECT_EQ("acc_id", iter
->account_id
);
423 EXPECT_EQ("acc_id@gmail.com", iter
->email
);
424 EXPECT_EQ("acc_id_token", iter
->access_token
);
425 EXPECT_EQ(AccountMapping::NEW
, iter
->status
);
426 EXPECT_EQ(base::Time(), iter
->status_change_timestamp
);
428 EXPECT_TRUE(!gcm_driver().last_message_id().empty());
431 // Tests the part where GCM message is successfully queued.
432 TEST_F(GCMAccountMapperTest
, AddMappingMessageQueued
) {
433 Initialize(GCMAccountMapper::AccountMappings());
434 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
436 std::vector
<GCMClient::AccountTokenInfo
> account_tokens
;
437 GCMClient::AccountTokenInfo account_token
= MakeAccountTokenInfo("acc_id");
438 account_tokens
.push_back(account_token
);
439 mapper()->SetAccountTokens(account_tokens
);
441 clock()->SetNow(base::Time::Now());
442 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS
);
444 EXPECT_EQ(account_token
.email
, gcm_driver().last_account_mapping().email
);
445 EXPECT_EQ(account_token
.account_id
,
446 gcm_driver().last_account_mapping().account_id
);
447 EXPECT_EQ(account_token
.access_token
,
448 gcm_driver().last_account_mapping().access_token
);
449 EXPECT_EQ(AccountMapping::ADDING
, gcm_driver().last_account_mapping().status
);
450 EXPECT_EQ(clock()->Now(),
451 gcm_driver().last_account_mapping().status_change_timestamp
);
452 EXPECT_EQ(gcm_driver().last_message_id(),
453 gcm_driver().last_account_mapping().last_message_id
);
455 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
456 GCMAccountMapper::AccountMappings::const_iterator iter
= mappings
.begin();
457 EXPECT_EQ(account_token
.email
, iter
->email
);
458 EXPECT_EQ(account_token
.account_id
, iter
->account_id
);
459 EXPECT_EQ(account_token
.access_token
, iter
->access_token
);
460 EXPECT_EQ(AccountMapping::ADDING
, iter
->status
);
461 EXPECT_EQ(clock()->Now(), iter
->status_change_timestamp
);
462 EXPECT_EQ(gcm_driver().last_message_id(), iter
->last_message_id
);
465 // Tests status change from ADDING to MAPPED (Message is acknowledged).
466 TEST_F(GCMAccountMapperTest
, AddMappingMessageAcknowledged
) {
467 Initialize(GCMAccountMapper::AccountMappings());
468 gcm_driver().AddAppHandler(kGCMAccountMapperAppId
, mapper());
469 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
471 std::vector
<GCMClient::AccountTokenInfo
> account_tokens
;
472 GCMClient::AccountTokenInfo account_token
= MakeAccountTokenInfo("acc_id");
473 account_tokens
.push_back(account_token
);
474 mapper()->SetAccountTokens(account_tokens
);
476 clock()->SetNow(base::Time::Now());
477 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS
);
478 clock()->SetNow(base::Time::Now());
479 gcm_driver().AcknowledgeSend(gcm_driver().last_message_id());
481 EXPECT_EQ(account_token
.email
, gcm_driver().last_account_mapping().email
);
482 EXPECT_EQ(account_token
.account_id
,
483 gcm_driver().last_account_mapping().account_id
);
484 EXPECT_EQ(account_token
.access_token
,
485 gcm_driver().last_account_mapping().access_token
);
486 EXPECT_EQ(AccountMapping::MAPPED
, gcm_driver().last_account_mapping().status
);
487 EXPECT_EQ(clock()->Now(),
488 gcm_driver().last_account_mapping().status_change_timestamp
);
489 EXPECT_TRUE(gcm_driver().last_account_mapping().last_message_id
.empty());
491 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
492 GCMAccountMapper::AccountMappings::const_iterator iter
= mappings
.begin();
493 EXPECT_EQ(account_token
.email
, iter
->email
);
494 EXPECT_EQ(account_token
.account_id
, iter
->account_id
);
495 EXPECT_EQ(account_token
.access_token
, iter
->access_token
);
496 EXPECT_EQ(AccountMapping::MAPPED
, iter
->status
);
497 EXPECT_EQ(clock()->Now(), iter
->status_change_timestamp
);
498 EXPECT_TRUE(iter
->last_message_id
.empty());
501 // Tests status change form ADDING to MAPPED (When message was acknowledged,
502 // after Chrome was restarted).
503 TEST_F(GCMAccountMapperTest
, AddMappingMessageAckedAfterRestart
) {
504 Initialize(GCMAccountMapper::AccountMappings());
505 gcm_driver().AddAppHandler(kGCMAccountMapperAppId
, mapper());
506 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
508 std::vector
<GCMClient::AccountTokenInfo
> account_tokens
;
509 GCMClient::AccountTokenInfo account_token
= MakeAccountTokenInfo("acc_id");
510 account_tokens
.push_back(account_token
);
511 mapper()->SetAccountTokens(account_tokens
);
513 clock()->SetNow(base::Time::Now());
514 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS
);
517 GCMAccountMapper::AccountMappings stored_mappings
;
518 stored_mappings
.push_back(gcm_driver().last_account_mapping());
519 Initialize(stored_mappings
);
520 gcm_driver().AddAppHandler(kGCMAccountMapperAppId
, mapper());
522 clock()->SetNow(base::Time::Now());
523 gcm_driver().AcknowledgeSend(gcm_driver().last_message_id());
525 EXPECT_EQ(account_token
.email
, gcm_driver().last_account_mapping().email
);
526 EXPECT_EQ(account_token
.account_id
,
527 gcm_driver().last_account_mapping().account_id
);
528 EXPECT_EQ(account_token
.access_token
,
529 gcm_driver().last_account_mapping().access_token
);
530 EXPECT_EQ(AccountMapping::MAPPED
, gcm_driver().last_account_mapping().status
);
531 EXPECT_EQ(clock()->Now(),
532 gcm_driver().last_account_mapping().status_change_timestamp
);
533 EXPECT_TRUE(gcm_driver().last_account_mapping().last_message_id
.empty());
535 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
536 GCMAccountMapper::AccountMappings::const_iterator iter
= mappings
.begin();
537 EXPECT_EQ(account_token
.email
, iter
->email
);
538 EXPECT_EQ(account_token
.account_id
, iter
->account_id
);
539 EXPECT_EQ(account_token
.access_token
, iter
->access_token
);
540 EXPECT_EQ(AccountMapping::MAPPED
, iter
->status
);
541 EXPECT_EQ(clock()->Now(), iter
->status_change_timestamp
);
542 EXPECT_TRUE(iter
->last_message_id
.empty());
545 // Tests a case when ADD message times out for a new account.
546 TEST_F(GCMAccountMapperTest
, AddMappingMessageSendErrorForNewAccount
) {
547 Initialize(GCMAccountMapper::AccountMappings());
548 gcm_driver().AddAppHandler(kGCMAccountMapperAppId
, mapper());
549 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
551 std::vector
<GCMClient::AccountTokenInfo
> account_tokens
;
552 GCMClient::AccountTokenInfo account_token
= MakeAccountTokenInfo("acc_id");
553 account_tokens
.push_back(account_token
);
554 mapper()->SetAccountTokens(account_tokens
);
556 clock()->SetNow(base::Time::Now());
557 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS
);
559 clock()->SetNow(base::Time::Now());
560 std::string old_message_id
= gcm_driver().last_message_id();
561 gcm_driver().MessageSendError(old_message_id
);
563 // No new message is sent because of the send error, as the token is stale.
564 // Because the account was new, the entry should be deleted.
565 EXPECT_EQ(old_message_id
, gcm_driver().last_message_id());
566 EXPECT_EQ(account_token
.account_id
, gcm_driver().last_removed_account_id());
567 EXPECT_TRUE(GetAccounts().empty());
570 /// Tests a case when ADD message times out for a MAPPED account.
571 TEST_F(GCMAccountMapperTest
, AddMappingMessageSendErrorForMappedAccount
) {
572 // Start with one account that is mapped.
573 base::Time status_change_timestamp
= base::Time::Now();
574 AccountMapping mapping
= MakeAccountMapping("acc_id",
575 AccountMapping::MAPPED
,
576 status_change_timestamp
,
579 GCMAccountMapper::AccountMappings stored_mappings
;
580 stored_mappings
.push_back(mapping
);
581 Initialize(stored_mappings
);
582 gcm_driver().AddAppHandler(kGCMAccountMapperAppId
, mapper());
583 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
585 clock()->SetNow(base::Time::Now());
586 gcm_driver().MessageSendError("add_message_id");
588 // No new message is sent because of the send error, as the token is stale.
589 // Because the account was new, the entry should be deleted.
590 EXPECT_TRUE(gcm_driver().last_message_id().empty());
592 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
593 GCMAccountMapper::AccountMappings::const_iterator iter
= mappings
.begin();
594 EXPECT_EQ(mapping
.email
, iter
->email
);
595 EXPECT_EQ(mapping
.account_id
, iter
->account_id
);
596 EXPECT_EQ(mapping
.access_token
, iter
->access_token
);
597 EXPECT_EQ(AccountMapping::MAPPED
, iter
->status
);
598 EXPECT_EQ(status_change_timestamp
, iter
->status_change_timestamp
);
599 EXPECT_TRUE(iter
->last_message_id
.empty());
602 // Tests that a missing token for an account will trigger removing of that
603 // account. This test goes only until the message is passed to GCM.
604 TEST_F(GCMAccountMapperTest
, RemoveMappingToMessageSent
) {
605 // Start with one account that is mapped.
606 AccountMapping mapping
= MakeAccountMapping("acc_id",
607 AccountMapping::MAPPED
,
611 GCMAccountMapper::AccountMappings stored_mappings
;
612 stored_mappings
.push_back(mapping
);
613 Initialize(stored_mappings
);
614 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
615 clock()->SetNow(base::Time::Now());
617 mapper()->SetAccountTokens(std::vector
<GCMClient::AccountTokenInfo
>());
619 EXPECT_EQ(mapping
.account_id
, gcm_driver().last_account_mapping().account_id
);
620 EXPECT_EQ(mapping
.email
, gcm_driver().last_account_mapping().email
);
621 EXPECT_EQ(AccountMapping::REMOVING
,
622 gcm_driver().last_account_mapping().status
);
623 EXPECT_EQ(clock()->Now(),
624 gcm_driver().last_account_mapping().status_change_timestamp
);
625 EXPECT_TRUE(gcm_driver().last_account_mapping().last_message_id
.empty());
627 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
628 GCMAccountMapper::AccountMappings::const_iterator iter
= mappings
.begin();
629 EXPECT_EQ(mapping
.email
, iter
->email
);
630 EXPECT_EQ(mapping
.account_id
, iter
->account_id
);
631 EXPECT_EQ(mapping
.access_token
, iter
->access_token
);
632 EXPECT_EQ(AccountMapping::REMOVING
, iter
->status
);
633 EXPECT_EQ(clock()->Now(), iter
->status_change_timestamp
);
634 EXPECT_TRUE(iter
->last_message_id
.empty());
637 // Tests that a missing token for an account will trigger removing of that
638 // account. This test goes until the message is queued by GCM.
639 TEST_F(GCMAccountMapperTest
, RemoveMappingMessageQueued
) {
640 // Start with one account that is mapped.
641 AccountMapping mapping
= MakeAccountMapping("acc_id",
642 AccountMapping::MAPPED
,
646 GCMAccountMapper::AccountMappings stored_mappings
;
647 stored_mappings
.push_back(mapping
);
648 Initialize(stored_mappings
);
649 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
650 clock()->SetNow(base::Time::Now());
651 base::Time status_change_timestamp
= clock()->Now();
653 mapper()->SetAccountTokens(std::vector
<GCMClient::AccountTokenInfo
>());
654 clock()->SetNow(base::Time::Now());
655 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS
);
657 EXPECT_EQ(mapping
.account_id
, gcm_driver().last_account_mapping().account_id
);
658 EXPECT_EQ(mapping
.email
, gcm_driver().last_account_mapping().email
);
659 EXPECT_EQ(AccountMapping::REMOVING
,
660 gcm_driver().last_account_mapping().status
);
661 EXPECT_EQ(status_change_timestamp
,
662 gcm_driver().last_account_mapping().status_change_timestamp
);
663 EXPECT_TRUE(!gcm_driver().last_account_mapping().last_message_id
.empty());
665 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
666 GCMAccountMapper::AccountMappings::const_iterator iter
= mappings
.begin();
667 EXPECT_EQ(mapping
.email
, iter
->email
);
668 EXPECT_EQ(mapping
.account_id
, iter
->account_id
);
669 EXPECT_EQ(mapping
.access_token
, iter
->access_token
);
670 EXPECT_EQ(AccountMapping::REMOVING
, iter
->status
);
671 EXPECT_EQ(status_change_timestamp
, iter
->status_change_timestamp
);
672 EXPECT_EQ(gcm_driver().last_account_mapping().last_message_id
,
673 iter
->last_message_id
);
676 // Tests that a missing token for an account will trigger removing of that
677 // account. This test goes until the message is acknowledged by GCM.
678 // This is a complete success scenario for account removal, and it end with
679 // account mapping being completely gone.
680 TEST_F(GCMAccountMapperTest
, RemoveMappingMessageAcknowledged
) {
681 // Start with one account that is mapped.
682 AccountMapping mapping
= MakeAccountMapping("acc_id",
683 AccountMapping::MAPPED
,
687 GCMAccountMapper::AccountMappings stored_mappings
;
688 stored_mappings
.push_back(mapping
);
689 Initialize(stored_mappings
);
690 gcm_driver().AddAppHandler(kGCMAccountMapperAppId
, mapper());
691 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
692 clock()->SetNow(base::Time::Now());
694 mapper()->SetAccountTokens(std::vector
<GCMClient::AccountTokenInfo
>());
695 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS
);
696 gcm_driver().AcknowledgeSend(gcm_driver().last_message_id());
698 EXPECT_EQ(mapping
.account_id
, gcm_driver().last_removed_account_id());
700 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
701 EXPECT_TRUE(mappings
.empty());
704 // Tests that account removing proceeds, when a removing message is acked after
705 // Chrome was restarted.
706 TEST_F(GCMAccountMapperTest
, RemoveMappingMessageAckedAfterRestart
) {
707 // Start with one account that is mapped.
708 AccountMapping mapping
= MakeAccountMapping("acc_id",
709 AccountMapping::REMOVING
,
711 "remove_message_id");
713 GCMAccountMapper::AccountMappings stored_mappings
;
714 stored_mappings
.push_back(mapping
);
715 Initialize(stored_mappings
);
716 gcm_driver().AddAppHandler(kGCMAccountMapperAppId
, mapper());
718 gcm_driver().AcknowledgeSend("remove_message_id");
720 EXPECT_EQ(mapping
.account_id
, gcm_driver().last_removed_account_id());
722 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
723 EXPECT_TRUE(mappings
.empty());
726 // Tests that account removing proceeds, when a removing message is acked after
727 // Chrome was restarted.
728 TEST_F(GCMAccountMapperTest
, RemoveMappingMessageSendError
) {
729 // Start with one account that is mapped.
730 base::Time status_change_timestamp
= base::Time::Now();
731 AccountMapping mapping
= MakeAccountMapping("acc_id",
732 AccountMapping::REMOVING
,
733 status_change_timestamp
,
734 "remove_message_id");
736 GCMAccountMapper::AccountMappings stored_mappings
;
737 stored_mappings
.push_back(mapping
);
738 Initialize(stored_mappings
);
739 gcm_driver().AddAppHandler(kGCMAccountMapperAppId
, mapper());
741 clock()->SetNow(base::Time::Now());
742 gcm_driver().MessageSendError("remove_message_id");
744 EXPECT_TRUE(gcm_driver().last_removed_account_id().empty());
746 EXPECT_EQ(mapping
.account_id
, gcm_driver().last_account_mapping().account_id
);
747 EXPECT_EQ(mapping
.email
, gcm_driver().last_account_mapping().email
);
748 EXPECT_EQ(AccountMapping::REMOVING
,
749 gcm_driver().last_account_mapping().status
);
750 EXPECT_EQ(status_change_timestamp
,
751 gcm_driver().last_account_mapping().status_change_timestamp
);
752 // Message is not persisted, until send is completed.
753 EXPECT_TRUE(gcm_driver().last_account_mapping().last_message_id
.empty());
755 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
756 GCMAccountMapper::AccountMappings::const_iterator iter
= mappings
.begin();
757 EXPECT_EQ(mapping
.email
, iter
->email
);
758 EXPECT_EQ(mapping
.account_id
, iter
->account_id
);
759 EXPECT_TRUE(iter
->access_token
.empty());
760 EXPECT_EQ(AccountMapping::REMOVING
, iter
->status
);
761 EXPECT_EQ(status_change_timestamp
, iter
->status_change_timestamp
);
762 EXPECT_TRUE(iter
->last_message_id
.empty());
765 // Tests that, if a new token arrives when the adding message is in progress
766 // no new message is sent and account mapper still waits for the first one to
768 TEST_F(GCMAccountMapperTest
, TokenIsRefreshedWhenAdding
) {
769 Initialize(GCMAccountMapper::AccountMappings());
770 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
772 clock()->SetNow(base::Time::Now());
773 std::vector
<GCMClient::AccountTokenInfo
> account_tokens
;
774 GCMClient::AccountTokenInfo account_token
= MakeAccountTokenInfo("acc_id");
775 account_tokens
.push_back(account_token
);
776 mapper()->SetAccountTokens(account_tokens
);
777 DCHECK_EQ(CustomFakeGCMDriver::SEND_STARTED
, gcm_driver().last_action());
779 clock()->SetNow(base::Time::Now());
780 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS
);
781 DCHECK_EQ(CustomFakeGCMDriver::SEND_FINISHED
, gcm_driver().last_action());
783 // Providing another token and clearing status.
784 gcm_driver().Clear();
785 mapper()->SetAccountTokens(account_tokens
);
786 DCHECK_EQ(CustomFakeGCMDriver::NONE
, gcm_driver().last_action());
789 // Tests that, if a new token arrives when a removing message is in progress
790 // a new adding message is sent and while account mapping status is changed to
791 // mapped. If the original Removing message arrives it is discarded.
792 TEST_F(GCMAccountMapperTest
, TokenIsRefreshedWhenRemoving
) {
793 // Start with one account that is mapped.
794 AccountMapping mapping
= MakeAccountMapping(
795 "acc_id", AccountMapping::MAPPED
, base::Time::Now(), std::string());
797 GCMAccountMapper::AccountMappings stored_mappings
;
798 stored_mappings
.push_back(mapping
);
799 Initialize(stored_mappings
);
800 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
801 clock()->SetNow(base::Time::Now());
803 // Remove the token to trigger a remove message to be sent
804 mapper()->SetAccountTokens(std::vector
<GCMClient::AccountTokenInfo
>());
805 EXPECT_EQ(CustomFakeGCMDriver::SEND_STARTED
, gcm_driver().last_action());
806 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS
);
807 EXPECT_EQ(CustomFakeGCMDriver::SEND_FINISHED
, gcm_driver().last_action());
809 std::string remove_message_id
= gcm_driver().last_message_id();
810 gcm_driver().Clear();
812 // The account mapping for acc_id is now in status REMOVING.
813 // Adding the token for that account.
814 clock()->SetNow(base::Time::Now());
815 std::vector
<GCMClient::AccountTokenInfo
> account_tokens
;
816 GCMClient::AccountTokenInfo account_token
= MakeAccountTokenInfo("acc_id");
817 account_tokens
.push_back(account_token
);
818 mapper()->SetAccountTokens(account_tokens
);
819 DCHECK_EQ(CustomFakeGCMDriver::SEND_STARTED
, gcm_driver().last_action());
820 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS
);
821 EXPECT_EQ(CustomFakeGCMDriver::SEND_FINISHED
, gcm_driver().last_action());
823 std::string add_message_id
= gcm_driver().last_message_id();
825 // A remove message confirmation arrives now, but should be ignored.
826 gcm_driver().AcknowledgeSend(remove_message_id
);
828 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
829 GCMAccountMapper::AccountMappings::const_iterator iter
= mappings
.begin();
830 EXPECT_EQ(mapping
.email
, iter
->email
);
831 EXPECT_EQ(mapping
.account_id
, iter
->account_id
);
832 EXPECT_FALSE(iter
->access_token
.empty());
833 EXPECT_EQ(AccountMapping::MAPPED
, iter
->status
);
834 // Status change timestamp is set to very long time ago, to make sure the next
835 // round of mapping picks it up.
836 EXPECT_EQ(base::Time(), iter
->status_change_timestamp
);
837 EXPECT_EQ(add_message_id
, iter
->last_message_id
);
840 // Tests adding/removing works for multiple accounts, after a restart and when
841 // tokens are periodically delierverd.
842 TEST_F(GCMAccountMapperTest
, MultipleAccountMappings
) {
843 clock()->SetNow(base::Time::Now());
844 base::Time half_hour_ago
= clock()->Now() - base::TimeDelta::FromMinutes(30);
845 GCMAccountMapper::AccountMappings stored_mappings
;
846 stored_mappings
.push_back(MakeAccountMapping(
847 "acc_id_0", AccountMapping::ADDING
, half_hour_ago
, "acc_id_0_msg"));
848 stored_mappings
.push_back(MakeAccountMapping(
849 "acc_id_1", AccountMapping::MAPPED
, half_hour_ago
, "acc_id_1_msg"));
850 stored_mappings
.push_back(MakeAccountMapping(
851 "acc_id_2", AccountMapping::REMOVING
, half_hour_ago
, "acc_id_2_msg"));
853 Initialize(stored_mappings
);
854 gcm_driver().AddAppHandler(kGCMAccountMapperAppId
, mapper());
855 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
857 GCMAccountMapper::AccountMappings
expected_mappings(stored_mappings
);
859 // Finish messages after a restart.
860 clock()->SetNow(base::Time::Now());
861 gcm_driver().AcknowledgeSend(expected_mappings
[0].last_message_id
);
862 expected_mappings
[0].status_change_timestamp
= clock()->Now();
863 expected_mappings
[0].status
= AccountMapping::MAPPED
;
864 expected_mappings
[0].last_message_id
.clear();
866 clock()->SetNow(base::Time::Now());
867 gcm_driver().AcknowledgeSend(expected_mappings
[1].last_message_id
);
868 expected_mappings
[1].status_change_timestamp
= clock()->Now();
869 expected_mappings
[1].status
= AccountMapping::MAPPED
;
870 expected_mappings
[1].last_message_id
.clear();
872 // Upon success last element is removed.
873 clock()->SetNow(base::Time::Now());
874 gcm_driver().AcknowledgeSend(expected_mappings
[2].last_message_id
);
875 expected_mappings
.pop_back();
877 VerifyMappings(expected_mappings
, GetAccounts(), "Step 1, After restart");
879 // One of accounts gets removed.
880 std::vector
<GCMClient::AccountTokenInfo
> account_tokens
;
881 account_tokens
.push_back(MakeAccountTokenInfo("acc_id_0"));
883 // Advance a day to make sure existing mappings will be reported.
884 clock()->SetNow(clock()->Now() + base::TimeDelta::FromDays(1));
885 mapper()->SetAccountTokens(account_tokens
);
887 expected_mappings
[0].status
= AccountMapping::MAPPED
;
888 expected_mappings
[1].status
= AccountMapping::REMOVING
;
889 expected_mappings
[1].status_change_timestamp
= clock()->Now();
891 gcm_driver().CompleteSendAllMessages();
894 expected_mappings
, GetAccounts(), "Step 2, One account is being removed");
896 clock()->SetNow(clock()->Now() + base::TimeDelta::FromSeconds(5));
897 gcm_driver().AcknowledgeSendAllMessages();
899 expected_mappings
[0].status_change_timestamp
= clock()->Now();
900 expected_mappings
.pop_back();
903 expected_mappings
, GetAccounts(), "Step 3, Removing completed");
905 account_tokens
.clear();
906 account_tokens
.push_back(MakeAccountTokenInfo("acc_id_0"));
907 account_tokens
.push_back(MakeAccountTokenInfo("acc_id_3"));
908 account_tokens
.push_back(MakeAccountTokenInfo("acc_id_4"));
910 // Advance a day to make sure existing mappings will be reported.
911 clock()->SetNow(clock()->Now() + base::TimeDelta::FromDays(1));
912 mapper()->SetAccountTokens(account_tokens
);
914 // Mapping from acc_id_0 still in position 0
915 expected_mappings
.push_back(MakeAccountMapping(
916 "acc_id_3", AccountMapping::NEW
, base::Time(), std::string()));
917 expected_mappings
.push_back(MakeAccountMapping(
918 "acc_id_4", AccountMapping::NEW
, base::Time(), std::string()));
920 VerifyMappings(expected_mappings
, GetAccounts(), "Step 4, Two new accounts");
922 clock()->SetNow(clock()->Now() + base::TimeDelta::FromSeconds(1));
923 gcm_driver().CompleteSendAllMessages();
925 expected_mappings
[1].status
= AccountMapping::ADDING
;
926 expected_mappings
[1].status_change_timestamp
= clock()->Now();
927 expected_mappings
[2].status
= AccountMapping::ADDING
;
928 expected_mappings
[2].status_change_timestamp
= clock()->Now();
931 expected_mappings
, GetAccounts(), "Step 5, Two accounts being added");
933 clock()->SetNow(clock()->Now() + base::TimeDelta::FromSeconds(5));
934 gcm_driver().AcknowledgeSendAllMessages();
936 expected_mappings
[0].status_change_timestamp
= clock()->Now();
937 expected_mappings
[1].status_change_timestamp
= clock()->Now();
938 expected_mappings
[1].status
= AccountMapping::MAPPED
;
939 expected_mappings
[2].status_change_timestamp
= clock()->Now();
940 expected_mappings
[2].status
= AccountMapping::MAPPED
;
943 expected_mappings
, GetAccounts(), "Step 6, Three mapped accounts");
946 TEST_F(GCMAccountMapperTest
, DispatchMessageSentToGaiaID
) {
947 Initialize(GCMAccountMapper::AccountMappings());
948 gcm_driver().AddAppHandler(kGCMAccountMapperAppId
, mapper());
949 IncomingMessage message
;
950 message
.data
[kEmbeddedAppIdKey
] = kTestAppId
;
951 message
.data
[kTestDataKey
] = kTestDataValue
;
952 message
.collapse_key
= kTestCollapseKey
;
953 message
.sender_id
= kTestSenderId
;
954 mapper()->OnMessage(kGCMAccountMapperAppId
, message
);
956 EXPECT_EQ(kTestAppId
, last_received_app_id());
957 EXPECT_EQ(1UL, last_received_message().data
.size());
958 MessageData::const_iterator it
=
959 last_received_message().data
.find(kTestDataKey
);
960 EXPECT_TRUE(it
!= last_received_message().data
.end());
961 EXPECT_EQ(kTestDataValue
, it
->second
);
962 EXPECT_EQ(kTestCollapseKey
, last_received_message().collapse_key
);
963 EXPECT_EQ(kTestSenderId
, last_received_message().sender_id
);