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 GCMClient::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 GCMClient::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 GCMClient::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 GCMClient::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 GCMClient::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(
307 const std::string
& app_id
,
308 const GCMClient::IncomingMessage
& message
) {
309 last_received_app_id_
= app_id
;
310 last_received_message_
= message
;
313 // Tests the initialization of account mappings (from the store) when empty.
314 // It also checks that initialization triggers registration ID request.
315 TEST_F(GCMAccountMapperTest
, InitializeAccountMappingsEmpty
) {
316 EXPECT_FALSE(gcm_driver().registration_id_requested());
317 Initialize(GCMAccountMapper::AccountMappings());
318 EXPECT_TRUE(GetAccounts().empty());
319 EXPECT_TRUE(gcm_driver().registration_id_requested());
322 // Tests that registration is retried, when new tokens are delivered and in no
323 // other circumstances.
324 TEST_F(GCMAccountMapperTest
, RegistrationRetryUponFailure
) {
325 Initialize(GCMAccountMapper::AccountMappings());
326 EXPECT_TRUE(gcm_driver().registration_id_requested());
327 gcm_driver().Clear();
329 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::UNKNOWN_ERROR
);
330 EXPECT_FALSE(gcm_driver().registration_id_requested());
331 gcm_driver().Clear();
333 std::vector
<GCMClient::AccountTokenInfo
> account_tokens
;
334 account_tokens
.push_back(MakeAccountTokenInfo("acc_id2"));
335 mapper()->SetAccountTokens(account_tokens
);
336 EXPECT_TRUE(gcm_driver().registration_id_requested());
337 gcm_driver().Clear();
339 gcm_driver().CompleteRegister(kRegistrationId
,
340 GCMClient::ASYNC_OPERATION_PENDING
);
341 EXPECT_FALSE(gcm_driver().registration_id_requested());
344 // Tests the initialization of account mappings (from the store).
345 TEST_F(GCMAccountMapperTest
, InitializeAccountMappings
) {
346 GCMAccountMapper::AccountMappings account_mappings
;
347 AccountMapping account_mapping1
= MakeAccountMapping("acc_id1",
348 AccountMapping::MAPPED
,
351 AccountMapping account_mapping2
= MakeAccountMapping("acc_id2",
352 AccountMapping::ADDING
,
355 account_mappings
.push_back(account_mapping1
);
356 account_mappings
.push_back(account_mapping2
);
358 Initialize(account_mappings
);
360 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
361 EXPECT_EQ(2UL, mappings
.size());
362 GCMAccountMapper::AccountMappings::const_iterator iter
= mappings
.begin();
364 EXPECT_EQ(account_mapping1
.account_id
, iter
->account_id
);
365 EXPECT_EQ(account_mapping1
.email
, iter
->email
);
366 EXPECT_TRUE(account_mapping1
.access_token
.empty());
367 EXPECT_EQ(account_mapping1
.status
, iter
->status
);
368 EXPECT_EQ(account_mapping1
.status_change_timestamp
,
369 iter
->status_change_timestamp
);
370 EXPECT_TRUE(account_mapping1
.last_message_id
.empty());
373 EXPECT_EQ(account_mapping2
.account_id
, iter
->account_id
);
374 EXPECT_EQ(account_mapping2
.email
, iter
->email
);
375 EXPECT_TRUE(account_mapping2
.access_token
.empty());
376 EXPECT_EQ(account_mapping2
.status
, iter
->status
);
377 EXPECT_EQ(account_mapping2
.status_change_timestamp
,
378 iter
->status_change_timestamp
);
379 EXPECT_EQ(account_mapping2
.last_message_id
, iter
->last_message_id
);
382 // Tests that account tokens are not processed until registration ID is
384 TEST_F(GCMAccountMapperTest
, SetAccountTokensOnlyWorksWithRegisterationId
) {
385 // Start with empty list.
386 Initialize(GCMAccountMapper::AccountMappings());
388 std::vector
<GCMClient::AccountTokenInfo
> account_tokens
;
389 account_tokens
.push_back(MakeAccountTokenInfo("acc_id"));
390 mapper()->SetAccountTokens(account_tokens
);
392 EXPECT_TRUE(GetAccounts().empty());
394 account_tokens
.clear();
395 account_tokens
.push_back(MakeAccountTokenInfo("acc_id1"));
396 account_tokens
.push_back(MakeAccountTokenInfo("acc_id2"));
397 mapper()->SetAccountTokens(account_tokens
);
399 EXPECT_TRUE(GetAccounts().empty());
401 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
403 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
404 EXPECT_EQ(2UL, mappings
.size());
405 EXPECT_EQ("acc_id1", mappings
[0].account_id
);
406 EXPECT_EQ("acc_id2", mappings
[1].account_id
);
409 // Tests the part where a new account is added with a token, to the point when
410 // GCM message is sent.
411 TEST_F(GCMAccountMapperTest
, AddMappingToMessageSent
) {
412 Initialize(GCMAccountMapper::AccountMappings());
413 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
415 std::vector
<GCMClient::AccountTokenInfo
> account_tokens
;
416 GCMClient::AccountTokenInfo account_token
= MakeAccountTokenInfo("acc_id");
417 account_tokens
.push_back(account_token
);
418 mapper()->SetAccountTokens(account_tokens
);
420 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
421 EXPECT_EQ(1UL, mappings
.size());
422 GCMAccountMapper::AccountMappings::const_iterator iter
= mappings
.begin();
423 EXPECT_EQ("acc_id", iter
->account_id
);
424 EXPECT_EQ("acc_id@gmail.com", iter
->email
);
425 EXPECT_EQ("acc_id_token", iter
->access_token
);
426 EXPECT_EQ(AccountMapping::NEW
, iter
->status
);
427 EXPECT_EQ(base::Time(), iter
->status_change_timestamp
);
429 EXPECT_TRUE(!gcm_driver().last_message_id().empty());
432 // Tests the part where GCM message is successfully queued.
433 TEST_F(GCMAccountMapperTest
, AddMappingMessageQueued
) {
434 Initialize(GCMAccountMapper::AccountMappings());
435 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
437 std::vector
<GCMClient::AccountTokenInfo
> account_tokens
;
438 GCMClient::AccountTokenInfo account_token
= MakeAccountTokenInfo("acc_id");
439 account_tokens
.push_back(account_token
);
440 mapper()->SetAccountTokens(account_tokens
);
442 clock()->SetNow(base::Time::Now());
443 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS
);
445 EXPECT_EQ(account_token
.email
, gcm_driver().last_account_mapping().email
);
446 EXPECT_EQ(account_token
.account_id
,
447 gcm_driver().last_account_mapping().account_id
);
448 EXPECT_EQ(account_token
.access_token
,
449 gcm_driver().last_account_mapping().access_token
);
450 EXPECT_EQ(AccountMapping::ADDING
, gcm_driver().last_account_mapping().status
);
451 EXPECT_EQ(clock()->Now(),
452 gcm_driver().last_account_mapping().status_change_timestamp
);
453 EXPECT_EQ(gcm_driver().last_message_id(),
454 gcm_driver().last_account_mapping().last_message_id
);
456 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
457 GCMAccountMapper::AccountMappings::const_iterator iter
= mappings
.begin();
458 EXPECT_EQ(account_token
.email
, iter
->email
);
459 EXPECT_EQ(account_token
.account_id
, iter
->account_id
);
460 EXPECT_EQ(account_token
.access_token
, iter
->access_token
);
461 EXPECT_EQ(AccountMapping::ADDING
, iter
->status
);
462 EXPECT_EQ(clock()->Now(), iter
->status_change_timestamp
);
463 EXPECT_EQ(gcm_driver().last_message_id(), iter
->last_message_id
);
466 // Tests status change from ADDING to MAPPED (Message is acknowledged).
467 TEST_F(GCMAccountMapperTest
, AddMappingMessageAcknowledged
) {
468 Initialize(GCMAccountMapper::AccountMappings());
469 gcm_driver().AddAppHandler(kGCMAccountMapperAppId
, mapper());
470 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
472 std::vector
<GCMClient::AccountTokenInfo
> account_tokens
;
473 GCMClient::AccountTokenInfo account_token
= MakeAccountTokenInfo("acc_id");
474 account_tokens
.push_back(account_token
);
475 mapper()->SetAccountTokens(account_tokens
);
477 clock()->SetNow(base::Time::Now());
478 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS
);
479 clock()->SetNow(base::Time::Now());
480 gcm_driver().AcknowledgeSend(gcm_driver().last_message_id());
482 EXPECT_EQ(account_token
.email
, gcm_driver().last_account_mapping().email
);
483 EXPECT_EQ(account_token
.account_id
,
484 gcm_driver().last_account_mapping().account_id
);
485 EXPECT_EQ(account_token
.access_token
,
486 gcm_driver().last_account_mapping().access_token
);
487 EXPECT_EQ(AccountMapping::MAPPED
, gcm_driver().last_account_mapping().status
);
488 EXPECT_EQ(clock()->Now(),
489 gcm_driver().last_account_mapping().status_change_timestamp
);
490 EXPECT_TRUE(gcm_driver().last_account_mapping().last_message_id
.empty());
492 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
493 GCMAccountMapper::AccountMappings::const_iterator iter
= mappings
.begin();
494 EXPECT_EQ(account_token
.email
, iter
->email
);
495 EXPECT_EQ(account_token
.account_id
, iter
->account_id
);
496 EXPECT_EQ(account_token
.access_token
, iter
->access_token
);
497 EXPECT_EQ(AccountMapping::MAPPED
, iter
->status
);
498 EXPECT_EQ(clock()->Now(), iter
->status_change_timestamp
);
499 EXPECT_TRUE(iter
->last_message_id
.empty());
502 // Tests status change form ADDING to MAPPED (When message was acknowledged,
503 // after Chrome was restarted).
504 TEST_F(GCMAccountMapperTest
, AddMappingMessageAckedAfterRestart
) {
505 Initialize(GCMAccountMapper::AccountMappings());
506 gcm_driver().AddAppHandler(kGCMAccountMapperAppId
, mapper());
507 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
509 std::vector
<GCMClient::AccountTokenInfo
> account_tokens
;
510 GCMClient::AccountTokenInfo account_token
= MakeAccountTokenInfo("acc_id");
511 account_tokens
.push_back(account_token
);
512 mapper()->SetAccountTokens(account_tokens
);
514 clock()->SetNow(base::Time::Now());
515 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS
);
518 GCMAccountMapper::AccountMappings stored_mappings
;
519 stored_mappings
.push_back(gcm_driver().last_account_mapping());
520 Initialize(stored_mappings
);
521 gcm_driver().AddAppHandler(kGCMAccountMapperAppId
, mapper());
523 clock()->SetNow(base::Time::Now());
524 gcm_driver().AcknowledgeSend(gcm_driver().last_message_id());
526 EXPECT_EQ(account_token
.email
, gcm_driver().last_account_mapping().email
);
527 EXPECT_EQ(account_token
.account_id
,
528 gcm_driver().last_account_mapping().account_id
);
529 EXPECT_EQ(account_token
.access_token
,
530 gcm_driver().last_account_mapping().access_token
);
531 EXPECT_EQ(AccountMapping::MAPPED
, gcm_driver().last_account_mapping().status
);
532 EXPECT_EQ(clock()->Now(),
533 gcm_driver().last_account_mapping().status_change_timestamp
);
534 EXPECT_TRUE(gcm_driver().last_account_mapping().last_message_id
.empty());
536 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
537 GCMAccountMapper::AccountMappings::const_iterator iter
= mappings
.begin();
538 EXPECT_EQ(account_token
.email
, iter
->email
);
539 EXPECT_EQ(account_token
.account_id
, iter
->account_id
);
540 EXPECT_EQ(account_token
.access_token
, iter
->access_token
);
541 EXPECT_EQ(AccountMapping::MAPPED
, iter
->status
);
542 EXPECT_EQ(clock()->Now(), iter
->status_change_timestamp
);
543 EXPECT_TRUE(iter
->last_message_id
.empty());
546 // Tests a case when ADD message times out for a new account.
547 TEST_F(GCMAccountMapperTest
, AddMappingMessageSendErrorForNewAccount
) {
548 Initialize(GCMAccountMapper::AccountMappings());
549 gcm_driver().AddAppHandler(kGCMAccountMapperAppId
, mapper());
550 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
552 std::vector
<GCMClient::AccountTokenInfo
> account_tokens
;
553 GCMClient::AccountTokenInfo account_token
= MakeAccountTokenInfo("acc_id");
554 account_tokens
.push_back(account_token
);
555 mapper()->SetAccountTokens(account_tokens
);
557 clock()->SetNow(base::Time::Now());
558 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS
);
560 clock()->SetNow(base::Time::Now());
561 std::string old_message_id
= gcm_driver().last_message_id();
562 gcm_driver().MessageSendError(old_message_id
);
564 // No new message is sent because of the send error, as the token is stale.
565 // Because the account was new, the entry should be deleted.
566 EXPECT_EQ(old_message_id
, gcm_driver().last_message_id());
567 EXPECT_EQ(account_token
.account_id
, gcm_driver().last_removed_account_id());
568 EXPECT_TRUE(GetAccounts().empty());
571 /// Tests a case when ADD message times out for a MAPPED account.
572 TEST_F(GCMAccountMapperTest
, AddMappingMessageSendErrorForMappedAccount
) {
573 // Start with one account that is mapped.
574 base::Time status_change_timestamp
= base::Time::Now();
575 AccountMapping mapping
= MakeAccountMapping("acc_id",
576 AccountMapping::MAPPED
,
577 status_change_timestamp
,
580 GCMAccountMapper::AccountMappings stored_mappings
;
581 stored_mappings
.push_back(mapping
);
582 Initialize(stored_mappings
);
583 gcm_driver().AddAppHandler(kGCMAccountMapperAppId
, mapper());
584 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
586 clock()->SetNow(base::Time::Now());
587 gcm_driver().MessageSendError("add_message_id");
589 // No new message is sent because of the send error, as the token is stale.
590 // Because the account was new, the entry should be deleted.
591 EXPECT_TRUE(gcm_driver().last_message_id().empty());
593 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
594 GCMAccountMapper::AccountMappings::const_iterator iter
= mappings
.begin();
595 EXPECT_EQ(mapping
.email
, iter
->email
);
596 EXPECT_EQ(mapping
.account_id
, iter
->account_id
);
597 EXPECT_EQ(mapping
.access_token
, iter
->access_token
);
598 EXPECT_EQ(AccountMapping::MAPPED
, iter
->status
);
599 EXPECT_EQ(status_change_timestamp
, iter
->status_change_timestamp
);
600 EXPECT_TRUE(iter
->last_message_id
.empty());
603 // Tests that a missing token for an account will trigger removing of that
604 // account. This test goes only until the message is passed to GCM.
605 TEST_F(GCMAccountMapperTest
, RemoveMappingToMessageSent
) {
606 // Start with one account that is mapped.
607 AccountMapping mapping
= MakeAccountMapping("acc_id",
608 AccountMapping::MAPPED
,
612 GCMAccountMapper::AccountMappings stored_mappings
;
613 stored_mappings
.push_back(mapping
);
614 Initialize(stored_mappings
);
615 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
616 clock()->SetNow(base::Time::Now());
618 mapper()->SetAccountTokens(std::vector
<GCMClient::AccountTokenInfo
>());
620 EXPECT_EQ(mapping
.account_id
, gcm_driver().last_account_mapping().account_id
);
621 EXPECT_EQ(mapping
.email
, gcm_driver().last_account_mapping().email
);
622 EXPECT_EQ(AccountMapping::REMOVING
,
623 gcm_driver().last_account_mapping().status
);
624 EXPECT_EQ(clock()->Now(),
625 gcm_driver().last_account_mapping().status_change_timestamp
);
626 EXPECT_TRUE(gcm_driver().last_account_mapping().last_message_id
.empty());
628 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
629 GCMAccountMapper::AccountMappings::const_iterator iter
= mappings
.begin();
630 EXPECT_EQ(mapping
.email
, iter
->email
);
631 EXPECT_EQ(mapping
.account_id
, iter
->account_id
);
632 EXPECT_EQ(mapping
.access_token
, iter
->access_token
);
633 EXPECT_EQ(AccountMapping::REMOVING
, iter
->status
);
634 EXPECT_EQ(clock()->Now(), iter
->status_change_timestamp
);
635 EXPECT_TRUE(iter
->last_message_id
.empty());
638 // Tests that a missing token for an account will trigger removing of that
639 // account. This test goes until the message is queued by GCM.
640 TEST_F(GCMAccountMapperTest
, RemoveMappingMessageQueued
) {
641 // Start with one account that is mapped.
642 AccountMapping mapping
= MakeAccountMapping("acc_id",
643 AccountMapping::MAPPED
,
647 GCMAccountMapper::AccountMappings stored_mappings
;
648 stored_mappings
.push_back(mapping
);
649 Initialize(stored_mappings
);
650 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
651 clock()->SetNow(base::Time::Now());
652 base::Time status_change_timestamp
= clock()->Now();
654 mapper()->SetAccountTokens(std::vector
<GCMClient::AccountTokenInfo
>());
655 clock()->SetNow(base::Time::Now());
656 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS
);
658 EXPECT_EQ(mapping
.account_id
, gcm_driver().last_account_mapping().account_id
);
659 EXPECT_EQ(mapping
.email
, gcm_driver().last_account_mapping().email
);
660 EXPECT_EQ(AccountMapping::REMOVING
,
661 gcm_driver().last_account_mapping().status
);
662 EXPECT_EQ(status_change_timestamp
,
663 gcm_driver().last_account_mapping().status_change_timestamp
);
664 EXPECT_TRUE(!gcm_driver().last_account_mapping().last_message_id
.empty());
666 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
667 GCMAccountMapper::AccountMappings::const_iterator iter
= mappings
.begin();
668 EXPECT_EQ(mapping
.email
, iter
->email
);
669 EXPECT_EQ(mapping
.account_id
, iter
->account_id
);
670 EXPECT_EQ(mapping
.access_token
, iter
->access_token
);
671 EXPECT_EQ(AccountMapping::REMOVING
, iter
->status
);
672 EXPECT_EQ(status_change_timestamp
, iter
->status_change_timestamp
);
673 EXPECT_EQ(gcm_driver().last_account_mapping().last_message_id
,
674 iter
->last_message_id
);
677 // Tests that a missing token for an account will trigger removing of that
678 // account. This test goes until the message is acknowledged by GCM.
679 // This is a complete success scenario for account removal, and it end with
680 // account mapping being completely gone.
681 TEST_F(GCMAccountMapperTest
, RemoveMappingMessageAcknowledged
) {
682 // Start with one account that is mapped.
683 AccountMapping mapping
= MakeAccountMapping("acc_id",
684 AccountMapping::MAPPED
,
688 GCMAccountMapper::AccountMappings stored_mappings
;
689 stored_mappings
.push_back(mapping
);
690 Initialize(stored_mappings
);
691 gcm_driver().AddAppHandler(kGCMAccountMapperAppId
, mapper());
692 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
693 clock()->SetNow(base::Time::Now());
695 mapper()->SetAccountTokens(std::vector
<GCMClient::AccountTokenInfo
>());
696 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS
);
697 gcm_driver().AcknowledgeSend(gcm_driver().last_message_id());
699 EXPECT_EQ(mapping
.account_id
, gcm_driver().last_removed_account_id());
701 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
702 EXPECT_TRUE(mappings
.empty());
705 // Tests that account removing proceeds, when a removing message is acked after
706 // Chrome was restarted.
707 TEST_F(GCMAccountMapperTest
, RemoveMappingMessageAckedAfterRestart
) {
708 // Start with one account that is mapped.
709 AccountMapping mapping
= MakeAccountMapping("acc_id",
710 AccountMapping::REMOVING
,
712 "remove_message_id");
714 GCMAccountMapper::AccountMappings stored_mappings
;
715 stored_mappings
.push_back(mapping
);
716 Initialize(stored_mappings
);
717 gcm_driver().AddAppHandler(kGCMAccountMapperAppId
, mapper());
719 gcm_driver().AcknowledgeSend("remove_message_id");
721 EXPECT_EQ(mapping
.account_id
, gcm_driver().last_removed_account_id());
723 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
724 EXPECT_TRUE(mappings
.empty());
727 // Tests that account removing proceeds, when a removing message is acked after
728 // Chrome was restarted.
729 TEST_F(GCMAccountMapperTest
, RemoveMappingMessageSendError
) {
730 // Start with one account that is mapped.
731 base::Time status_change_timestamp
= base::Time::Now();
732 AccountMapping mapping
= MakeAccountMapping("acc_id",
733 AccountMapping::REMOVING
,
734 status_change_timestamp
,
735 "remove_message_id");
737 GCMAccountMapper::AccountMappings stored_mappings
;
738 stored_mappings
.push_back(mapping
);
739 Initialize(stored_mappings
);
740 gcm_driver().AddAppHandler(kGCMAccountMapperAppId
, mapper());
742 clock()->SetNow(base::Time::Now());
743 gcm_driver().MessageSendError("remove_message_id");
745 EXPECT_TRUE(gcm_driver().last_removed_account_id().empty());
747 EXPECT_EQ(mapping
.account_id
, gcm_driver().last_account_mapping().account_id
);
748 EXPECT_EQ(mapping
.email
, gcm_driver().last_account_mapping().email
);
749 EXPECT_EQ(AccountMapping::REMOVING
,
750 gcm_driver().last_account_mapping().status
);
751 EXPECT_EQ(status_change_timestamp
,
752 gcm_driver().last_account_mapping().status_change_timestamp
);
753 // Message is not persisted, until send is completed.
754 EXPECT_TRUE(gcm_driver().last_account_mapping().last_message_id
.empty());
756 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
757 GCMAccountMapper::AccountMappings::const_iterator iter
= mappings
.begin();
758 EXPECT_EQ(mapping
.email
, iter
->email
);
759 EXPECT_EQ(mapping
.account_id
, iter
->account_id
);
760 EXPECT_TRUE(iter
->access_token
.empty());
761 EXPECT_EQ(AccountMapping::REMOVING
, iter
->status
);
762 EXPECT_EQ(status_change_timestamp
, iter
->status_change_timestamp
);
763 EXPECT_TRUE(iter
->last_message_id
.empty());
766 // Tests that, if a new token arrives when the adding message is in progress
767 // no new message is sent and account mapper still waits for the first one to
769 TEST_F(GCMAccountMapperTest
, TokenIsRefreshedWhenAdding
) {
770 Initialize(GCMAccountMapper::AccountMappings());
771 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
773 clock()->SetNow(base::Time::Now());
774 std::vector
<GCMClient::AccountTokenInfo
> account_tokens
;
775 GCMClient::AccountTokenInfo account_token
= MakeAccountTokenInfo("acc_id");
776 account_tokens
.push_back(account_token
);
777 mapper()->SetAccountTokens(account_tokens
);
778 DCHECK_EQ(CustomFakeGCMDriver::SEND_STARTED
, gcm_driver().last_action());
780 clock()->SetNow(base::Time::Now());
781 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS
);
782 DCHECK_EQ(CustomFakeGCMDriver::SEND_FINISHED
, gcm_driver().last_action());
784 // Providing another token and clearing status.
785 gcm_driver().Clear();
786 mapper()->SetAccountTokens(account_tokens
);
787 DCHECK_EQ(CustomFakeGCMDriver::NONE
, gcm_driver().last_action());
790 // Tests that, if a new token arrives when a removing message is in progress
791 // a new adding message is sent and while account mapping status is changed to
792 // mapped. If the original Removing message arrives it is discarded.
793 TEST_F(GCMAccountMapperTest
, TokenIsRefreshedWhenRemoving
) {
794 // Start with one account that is mapped.
795 AccountMapping mapping
= MakeAccountMapping(
796 "acc_id", AccountMapping::MAPPED
, base::Time::Now(), std::string());
798 GCMAccountMapper::AccountMappings stored_mappings
;
799 stored_mappings
.push_back(mapping
);
800 Initialize(stored_mappings
);
801 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
802 clock()->SetNow(base::Time::Now());
804 // Remove the token to trigger a remove message to be sent
805 mapper()->SetAccountTokens(std::vector
<GCMClient::AccountTokenInfo
>());
806 EXPECT_EQ(CustomFakeGCMDriver::SEND_STARTED
, gcm_driver().last_action());
807 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS
);
808 EXPECT_EQ(CustomFakeGCMDriver::SEND_FINISHED
, gcm_driver().last_action());
810 std::string remove_message_id
= gcm_driver().last_message_id();
811 gcm_driver().Clear();
813 // The account mapping for acc_id is now in status REMOVING.
814 // Adding the token for that account.
815 clock()->SetNow(base::Time::Now());
816 std::vector
<GCMClient::AccountTokenInfo
> account_tokens
;
817 GCMClient::AccountTokenInfo account_token
= MakeAccountTokenInfo("acc_id");
818 account_tokens
.push_back(account_token
);
819 mapper()->SetAccountTokens(account_tokens
);
820 DCHECK_EQ(CustomFakeGCMDriver::SEND_STARTED
, gcm_driver().last_action());
821 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS
);
822 EXPECT_EQ(CustomFakeGCMDriver::SEND_FINISHED
, gcm_driver().last_action());
824 std::string add_message_id
= gcm_driver().last_message_id();
826 // A remove message confirmation arrives now, but should be ignored.
827 gcm_driver().AcknowledgeSend(remove_message_id
);
829 GCMAccountMapper::AccountMappings mappings
= GetAccounts();
830 GCMAccountMapper::AccountMappings::const_iterator iter
= mappings
.begin();
831 EXPECT_EQ(mapping
.email
, iter
->email
);
832 EXPECT_EQ(mapping
.account_id
, iter
->account_id
);
833 EXPECT_FALSE(iter
->access_token
.empty());
834 EXPECT_EQ(AccountMapping::MAPPED
, iter
->status
);
835 // Status change timestamp is set to very long time ago, to make sure the next
836 // round of mapping picks it up.
837 EXPECT_EQ(base::Time(), iter
->status_change_timestamp
);
838 EXPECT_EQ(add_message_id
, iter
->last_message_id
);
841 // Tests adding/removing works for multiple accounts, after a restart and when
842 // tokens are periodically delierverd.
843 TEST_F(GCMAccountMapperTest
, MultipleAccountMappings
) {
844 clock()->SetNow(base::Time::Now());
845 base::Time half_hour_ago
= clock()->Now() - base::TimeDelta::FromMinutes(30);
846 GCMAccountMapper::AccountMappings stored_mappings
;
847 stored_mappings
.push_back(MakeAccountMapping(
848 "acc_id_0", AccountMapping::ADDING
, half_hour_ago
, "acc_id_0_msg"));
849 stored_mappings
.push_back(MakeAccountMapping(
850 "acc_id_1", AccountMapping::MAPPED
, half_hour_ago
, "acc_id_1_msg"));
851 stored_mappings
.push_back(MakeAccountMapping(
852 "acc_id_2", AccountMapping::REMOVING
, half_hour_ago
, "acc_id_2_msg"));
854 Initialize(stored_mappings
);
855 gcm_driver().AddAppHandler(kGCMAccountMapperAppId
, mapper());
856 gcm_driver().CompleteRegister(kRegistrationId
, GCMClient::SUCCESS
);
858 GCMAccountMapper::AccountMappings
expected_mappings(stored_mappings
);
860 // Finish messages after a restart.
861 clock()->SetNow(base::Time::Now());
862 gcm_driver().AcknowledgeSend(expected_mappings
[0].last_message_id
);
863 expected_mappings
[0].status_change_timestamp
= clock()->Now();
864 expected_mappings
[0].status
= AccountMapping::MAPPED
;
865 expected_mappings
[0].last_message_id
.clear();
867 clock()->SetNow(base::Time::Now());
868 gcm_driver().AcknowledgeSend(expected_mappings
[1].last_message_id
);
869 expected_mappings
[1].status_change_timestamp
= clock()->Now();
870 expected_mappings
[1].status
= AccountMapping::MAPPED
;
871 expected_mappings
[1].last_message_id
.clear();
873 // Upon success last element is removed.
874 clock()->SetNow(base::Time::Now());
875 gcm_driver().AcknowledgeSend(expected_mappings
[2].last_message_id
);
876 expected_mappings
.pop_back();
878 VerifyMappings(expected_mappings
, GetAccounts(), "Step 1, After restart");
880 // One of accounts gets removed.
881 std::vector
<GCMClient::AccountTokenInfo
> account_tokens
;
882 account_tokens
.push_back(MakeAccountTokenInfo("acc_id_0"));
884 // Advance a day to make sure existing mappings will be reported.
885 clock()->SetNow(clock()->Now() + base::TimeDelta::FromDays(1));
886 mapper()->SetAccountTokens(account_tokens
);
888 expected_mappings
[0].status
= AccountMapping::MAPPED
;
889 expected_mappings
[1].status
= AccountMapping::REMOVING
;
890 expected_mappings
[1].status_change_timestamp
= clock()->Now();
892 gcm_driver().CompleteSendAllMessages();
895 expected_mappings
, GetAccounts(), "Step 2, One account is being removed");
897 clock()->SetNow(clock()->Now() + base::TimeDelta::FromSeconds(5));
898 gcm_driver().AcknowledgeSendAllMessages();
900 expected_mappings
[0].status_change_timestamp
= clock()->Now();
901 expected_mappings
.pop_back();
904 expected_mappings
, GetAccounts(), "Step 3, Removing completed");
906 account_tokens
.clear();
907 account_tokens
.push_back(MakeAccountTokenInfo("acc_id_0"));
908 account_tokens
.push_back(MakeAccountTokenInfo("acc_id_3"));
909 account_tokens
.push_back(MakeAccountTokenInfo("acc_id_4"));
911 // Advance a day to make sure existing mappings will be reported.
912 clock()->SetNow(clock()->Now() + base::TimeDelta::FromDays(1));
913 mapper()->SetAccountTokens(account_tokens
);
915 // Mapping from acc_id_0 still in position 0
916 expected_mappings
.push_back(MakeAccountMapping(
917 "acc_id_3", AccountMapping::NEW
, base::Time(), std::string()));
918 expected_mappings
.push_back(MakeAccountMapping(
919 "acc_id_4", AccountMapping::NEW
, base::Time(), std::string()));
921 VerifyMappings(expected_mappings
, GetAccounts(), "Step 4, Two new accounts");
923 clock()->SetNow(clock()->Now() + base::TimeDelta::FromSeconds(1));
924 gcm_driver().CompleteSendAllMessages();
926 expected_mappings
[1].status
= AccountMapping::ADDING
;
927 expected_mappings
[1].status_change_timestamp
= clock()->Now();
928 expected_mappings
[2].status
= AccountMapping::ADDING
;
929 expected_mappings
[2].status_change_timestamp
= clock()->Now();
932 expected_mappings
, GetAccounts(), "Step 5, Two accounts being added");
934 clock()->SetNow(clock()->Now() + base::TimeDelta::FromSeconds(5));
935 gcm_driver().AcknowledgeSendAllMessages();
937 expected_mappings
[0].status_change_timestamp
= clock()->Now();
938 expected_mappings
[1].status_change_timestamp
= clock()->Now();
939 expected_mappings
[1].status
= AccountMapping::MAPPED
;
940 expected_mappings
[2].status_change_timestamp
= clock()->Now();
941 expected_mappings
[2].status
= AccountMapping::MAPPED
;
944 expected_mappings
, GetAccounts(), "Step 6, Three mapped accounts");
947 TEST_F(GCMAccountMapperTest
, DispatchMessageSentToGaiaID
) {
948 Initialize(GCMAccountMapper::AccountMappings());
949 gcm_driver().AddAppHandler(kGCMAccountMapperAppId
, mapper());
950 GCMClient::IncomingMessage message
;
951 message
.data
[kEmbeddedAppIdKey
] = kTestAppId
;
952 message
.data
[kTestDataKey
] = kTestDataValue
;
953 message
.collapse_key
= kTestCollapseKey
;
954 message
.sender_id
= kTestSenderId
;
955 mapper()->OnMessage(kGCMAccountMapperAppId
, message
);
957 EXPECT_EQ(kTestAppId
, last_received_app_id());
958 EXPECT_EQ(1UL, last_received_message().data
.size());
959 GCMClient::MessageData::const_iterator it
=
960 last_received_message().data
.find(kTestDataKey
);
961 EXPECT_TRUE(it
!= last_received_message().data
.end());
962 EXPECT_EQ(kTestDataValue
, it
->second
);
963 EXPECT_EQ(kTestCollapseKey
, last_received_message().collapse_key
);
964 EXPECT_EQ(kTestSenderId
, last_received_message().sender_id
);