Cleanup: Pass std::string as const reference from pdf/
[chromium-blink-merge.git] / components / gcm_driver / gcm_account_mapper_unittest.cc
blob7b76b36ca4a938cffd3ea26fa2af51314dcfc6ce
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"
7 #include "base/bind.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"
15 namespace gcm {
17 namespace {
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";
50 return account_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 {
81 public:
82 enum LastMessageAction {
83 NONE,
84 SEND_STARTED,
85 SEND_FINISHED,
86 SEND_ACKNOWLEDGED
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);
111 void Clear();
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_; }
123 protected:
124 void SendImpl(const std::string& app_id,
125 const std::string& receiver_id,
126 const OutgoingMessage& message) override;
128 private:
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();
215 ++iter) {
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();
225 ++iter) {
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();
235 last_action_ = NONE;
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;
246 } // namespace
248 class GCMAccountMapperTest : public testing::Test {
249 public:
250 GCMAccountMapperTest();
251 ~GCMAccountMapperTest() override;
253 void Restart();
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_;
274 private:
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() {
283 Restart();
286 GCMAccountMapperTest::~GCMAccountMapperTest() {
289 void GCMAccountMapperTest::Restart() {
290 if (account_mapper_)
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,
348 base::Time::Now(),
349 std::string());
350 AccountMapping account_mapping2 = MakeAccountMapping("acc_id2",
351 AccountMapping::ADDING,
352 base::Time::Now(),
353 "add_message_1");
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());
371 ++iter;
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
382 // available.
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);
516 Restart();
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,
577 "add_message_id");
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,
608 base::Time::Now(),
609 std::string());
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,
643 base::Time::Now(),
644 std::string());
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,
684 base::Time::Now(),
685 std::string());
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,
710 base::Time::Now(),
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
767 // complete.
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();
893 VerifyMappings(
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();
902 VerifyMappings(
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();
930 VerifyMappings(
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;
942 VerifyMappings(
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);
966 } // namespace gcm