Explicitly add python-numpy dependency to install-build-deps.
[chromium-blink-merge.git] / components / gcm_driver / gcm_account_mapper_unittest.cc
blob665e0f9ebdb42580f954900192976b72beb8011d
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/test/simple_test_clock.h"
8 #include "base/time/time.h"
9 #include "components/gcm_driver/fake_gcm_driver.h"
10 #include "google_apis/gcm/engine/account_mapping.h"
11 #include "google_apis/gcm/engine/gcm_store.h"
12 #include "testing/gtest/include/gtest/gtest.h"
14 namespace gcm {
16 namespace {
18 const char kGCMAccountMapperSenderId[] = "745476177629";
19 const char kRegistrationId[] = "reg_id";
21 AccountMapping MakeAccountMapping(const std::string& account_id,
22 AccountMapping::MappingStatus status,
23 const base::Time& status_change_timestamp,
24 const std::string& last_message_id) {
25 AccountMapping account_mapping;
26 account_mapping.account_id = account_id;
27 account_mapping.email = account_id + "@gmail.com";
28 // account_mapping.access_token intentionally left empty.
29 account_mapping.status = status;
30 account_mapping.status_change_timestamp = status_change_timestamp;
31 account_mapping.last_message_id = last_message_id;
32 return account_mapping;
35 GCMClient::AccountTokenInfo MakeAccountTokenInfo(
36 const std::string& account_id) {
37 GCMClient::AccountTokenInfo account_token;
38 account_token.account_id = account_id;
39 account_token.email = account_id + "@gmail.com";
40 account_token.access_token = account_id + "_token";
41 return account_token;
44 void VerifyMappings(const GCMAccountMapper::AccountMappings& expected_mappings,
45 const GCMAccountMapper::AccountMappings& actual_mappings,
46 const std::string& verification_info) {
47 EXPECT_EQ(expected_mappings.size(), actual_mappings.size())
48 << "Verification Info: " << verification_info;
49 GCMAccountMapper::AccountMappings::const_iterator expected_iter =
50 expected_mappings.begin();
51 GCMAccountMapper::AccountMappings::const_iterator actual_iter =
52 actual_mappings.begin();
53 for (; expected_iter != expected_mappings.end() &&
54 actual_iter != actual_mappings.end();
55 ++expected_iter, ++actual_iter) {
56 EXPECT_EQ(expected_iter->email, actual_iter->email)
57 << "Verification Info: " << verification_info
58 << "; Account ID of expected: " << expected_iter->account_id;
59 EXPECT_EQ(expected_iter->account_id, actual_iter->account_id)
60 << "Verification Info: " << verification_info;
61 EXPECT_EQ(expected_iter->status, actual_iter->status)
62 << "Verification Info: " << verification_info
63 << "; Account ID of expected: " << expected_iter->account_id;
64 EXPECT_EQ(expected_iter->status_change_timestamp,
65 actual_iter->status_change_timestamp)
66 << "Verification Info: " << verification_info
67 << "; Account ID of expected: " << expected_iter->account_id;
71 class CustomFakeGCMDriver : public FakeGCMDriver {
72 public:
73 enum LastMessageAction {
74 NONE,
75 SEND_STARTED,
76 SEND_FINISHED,
77 SEND_ACKNOWLEDGED
80 CustomFakeGCMDriver();
81 ~CustomFakeGCMDriver() override;
83 void UpdateAccountMapping(const AccountMapping& account_mapping) override;
84 void RemoveAccountMapping(const std::string& account_id) override;
85 void AddAppHandler(const std::string& app_id,
86 GCMAppHandler* handler) override;
87 void RemoveAppHandler(const std::string& app_id) override;
88 void RegisterImpl(const std::string& app_id,
89 const std::vector<std::string>& sender_ids) override;
91 void CompleteRegister(const std::string& registration_id,
92 GCMClient::Result result);
93 void CompleteSend(const std::string& message_id, GCMClient::Result result);
94 void AcknowledgeSend(const std::string& message_id);
95 void MessageSendError(const std::string& message_id);
97 void CompleteSendAllMessages();
98 void AcknowledgeSendAllMessages();
100 void SetLastMessageAction(const std::string& message_id,
101 LastMessageAction action);
102 void Clear();
104 const AccountMapping& last_account_mapping() const {
105 return account_mapping_;
107 const std::string& last_message_id() const { return last_message_id_; }
108 const std::string& last_removed_account_id() const {
109 return last_removed_account_id_;
111 LastMessageAction last_action() const { return last_action_; }
112 bool registration_id_requested() const { return registration_id_requested_; }
114 protected:
115 void SendImpl(const std::string& app_id,
116 const std::string& receiver_id,
117 const GCMClient::OutgoingMessage& message) override;
119 private:
120 AccountMapping account_mapping_;
121 std::string last_message_id_;
122 std::string last_removed_account_id_;
123 LastMessageAction last_action_;
124 std::map<std::string, LastMessageAction> all_messages_;
125 bool registration_id_requested_;
128 CustomFakeGCMDriver::CustomFakeGCMDriver()
129 : last_action_(NONE), registration_id_requested_(false) {
132 CustomFakeGCMDriver::~CustomFakeGCMDriver() {
135 void CustomFakeGCMDriver::UpdateAccountMapping(
136 const AccountMapping& account_mapping) {
137 account_mapping_.email = account_mapping.email;
138 account_mapping_.account_id = account_mapping.account_id;
139 account_mapping_.access_token = account_mapping.access_token;
140 account_mapping_.status = account_mapping.status;
141 account_mapping_.status_change_timestamp =
142 account_mapping.status_change_timestamp;
143 account_mapping_.last_message_id = account_mapping.last_message_id;
146 void CustomFakeGCMDriver::RemoveAccountMapping(const std::string& account_id) {
147 last_removed_account_id_ = account_id;
150 void CustomFakeGCMDriver::AddAppHandler(const std::string& app_id,
151 GCMAppHandler* handler) {
152 GCMDriver::AddAppHandler(app_id, handler);
155 void CustomFakeGCMDriver::RemoveAppHandler(const std::string& app_id) {
156 GCMDriver::RemoveAppHandler(app_id);
159 void CustomFakeGCMDriver::RegisterImpl(
160 const std::string& app_id,
161 const std::vector<std::string>& sender_ids) {
162 DCHECK_EQ(kGCMAccountMapperAppId, app_id);
163 DCHECK_EQ(1u, sender_ids.size());
164 DCHECK_EQ(kGCMAccountMapperSenderId, sender_ids[0]);
165 registration_id_requested_ = true;
168 void CustomFakeGCMDriver::CompleteRegister(const std::string& registration_id,
169 GCMClient::Result result) {
170 RegisterFinished(kGCMAccountMapperAppId, registration_id, result);
173 void CustomFakeGCMDriver::CompleteSend(const std::string& message_id,
174 GCMClient::Result result) {
175 SendFinished(kGCMAccountMapperAppId, message_id, result);
176 SetLastMessageAction(message_id, SEND_FINISHED);
179 void CustomFakeGCMDriver::AcknowledgeSend(const std::string& message_id) {
180 GetAppHandler(kGCMAccountMapperAppId)
181 ->OnSendAcknowledged(kGCMAccountMapperAppId, message_id);
182 SetLastMessageAction(message_id, SEND_ACKNOWLEDGED);
185 void CustomFakeGCMDriver::MessageSendError(const std::string& message_id) {
186 GCMClient::SendErrorDetails send_error;
187 send_error.message_id = message_id;
188 send_error.result = GCMClient::TTL_EXCEEDED;
189 GetAppHandler(kGCMAccountMapperAppId)
190 ->OnSendError(kGCMAccountMapperAppId, send_error);
193 void CustomFakeGCMDriver::SendImpl(const std::string& app_id,
194 const std::string& receiver_id,
195 const GCMClient::OutgoingMessage& message) {
196 DCHECK_EQ(kGCMAccountMapperAppId, app_id);
197 DCHECK_EQ(kGCMAccountMapperSenderId, receiver_id);
199 SetLastMessageAction(message.id, SEND_STARTED);
202 void CustomFakeGCMDriver::CompleteSendAllMessages() {
203 for (std::map<std::string, LastMessageAction>::const_iterator iter =
204 all_messages_.begin();
205 iter != all_messages_.end();
206 ++iter) {
207 if (iter->second == SEND_STARTED)
208 CompleteSend(iter->first, GCMClient::SUCCESS);
212 void CustomFakeGCMDriver::AcknowledgeSendAllMessages() {
213 for (std::map<std::string, LastMessageAction>::const_iterator iter =
214 all_messages_.begin();
215 iter != all_messages_.end();
216 ++iter) {
217 if (iter->second == SEND_FINISHED)
218 AcknowledgeSend(iter->first);
222 void CustomFakeGCMDriver::Clear() {
223 account_mapping_ = AccountMapping();
224 last_message_id_.clear();
225 last_removed_account_id_.clear();
226 last_action_ = NONE;
227 registration_id_requested_ = false;
230 void CustomFakeGCMDriver::SetLastMessageAction(const std::string& message_id,
231 LastMessageAction action) {
232 last_action_ = action;
233 last_message_id_ = message_id;
234 all_messages_[message_id] = action;
237 } // namespace
239 class GCMAccountMapperTest : public testing::Test {
240 public:
241 GCMAccountMapperTest();
242 ~GCMAccountMapperTest() override;
244 void Restart();
246 const GCMAccountMapper::AccountMappings& GetAccounts() const {
247 return account_mapper_->accounts_;
250 GCMAccountMapper* mapper() { return account_mapper_.get(); }
252 CustomFakeGCMDriver& gcm_driver() { return gcm_driver_; }
254 base::SimpleTestClock* clock() { return clock_; }
256 private:
257 CustomFakeGCMDriver gcm_driver_;
258 scoped_ptr<GCMAccountMapper> account_mapper_;
259 base::SimpleTestClock* clock_;
262 GCMAccountMapperTest::GCMAccountMapperTest() {
263 Restart();
266 GCMAccountMapperTest::~GCMAccountMapperTest() {
269 void GCMAccountMapperTest::Restart() {
270 if (account_mapper_)
271 account_mapper_->ShutdownHandler();
272 gcm_driver_.RemoveAppHandler(kGCMAccountMapperAppId);
273 account_mapper_.reset(new GCMAccountMapper(&gcm_driver_));
274 scoped_ptr<base::SimpleTestClock> clock(new base::SimpleTestClock);
275 clock_ = clock.get();
276 account_mapper_->SetClockForTesting(clock.Pass());
279 // Tests the initialization of account mappings (from the store) when empty.
280 // It also checks that initialization triggers registration ID request.
281 TEST_F(GCMAccountMapperTest, InitializeAccountMappingsEmpty) {
282 EXPECT_FALSE(gcm_driver().registration_id_requested());
283 mapper()->Initialize(GCMAccountMapper::AccountMappings());
284 EXPECT_TRUE(GetAccounts().empty());
285 EXPECT_TRUE(gcm_driver().registration_id_requested());
288 // Tests that registration is retried, when new tokens are delivered and in no
289 // other circumstances.
290 TEST_F(GCMAccountMapperTest, RegistrationRetryUponFailure) {
291 mapper()->Initialize(GCMAccountMapper::AccountMappings());
292 EXPECT_TRUE(gcm_driver().registration_id_requested());
293 gcm_driver().Clear();
295 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::UNKNOWN_ERROR);
296 EXPECT_FALSE(gcm_driver().registration_id_requested());
297 gcm_driver().Clear();
299 std::vector<GCMClient::AccountTokenInfo> account_tokens;
300 account_tokens.push_back(MakeAccountTokenInfo("acc_id2"));
301 mapper()->SetAccountTokens(account_tokens);
302 EXPECT_TRUE(gcm_driver().registration_id_requested());
303 gcm_driver().Clear();
305 gcm_driver().CompleteRegister(kRegistrationId,
306 GCMClient::ASYNC_OPERATION_PENDING);
307 EXPECT_FALSE(gcm_driver().registration_id_requested());
310 // Tests the initialization of account mappings (from the store).
311 TEST_F(GCMAccountMapperTest, InitializeAccountMappings) {
312 GCMAccountMapper::AccountMappings account_mappings;
313 AccountMapping account_mapping1 = MakeAccountMapping("acc_id1",
314 AccountMapping::MAPPED,
315 base::Time::Now(),
316 std::string());
317 AccountMapping account_mapping2 = MakeAccountMapping("acc_id2",
318 AccountMapping::ADDING,
319 base::Time::Now(),
320 "add_message_1");
321 account_mappings.push_back(account_mapping1);
322 account_mappings.push_back(account_mapping2);
324 mapper()->Initialize(account_mappings);
326 GCMAccountMapper::AccountMappings mappings = GetAccounts();
327 EXPECT_EQ(2UL, mappings.size());
328 GCMAccountMapper::AccountMappings::const_iterator iter = mappings.begin();
330 EXPECT_EQ(account_mapping1.account_id, iter->account_id);
331 EXPECT_EQ(account_mapping1.email, iter->email);
332 EXPECT_TRUE(account_mapping1.access_token.empty());
333 EXPECT_EQ(account_mapping1.status, iter->status);
334 EXPECT_EQ(account_mapping1.status_change_timestamp,
335 iter->status_change_timestamp);
336 EXPECT_TRUE(account_mapping1.last_message_id.empty());
338 ++iter;
339 EXPECT_EQ(account_mapping2.account_id, iter->account_id);
340 EXPECT_EQ(account_mapping2.email, iter->email);
341 EXPECT_TRUE(account_mapping2.access_token.empty());
342 EXPECT_EQ(account_mapping2.status, iter->status);
343 EXPECT_EQ(account_mapping2.status_change_timestamp,
344 iter->status_change_timestamp);
345 EXPECT_EQ(account_mapping2.last_message_id, iter->last_message_id);
348 // Tests that account tokens are not processed until registration ID is
349 // available.
350 TEST_F(GCMAccountMapperTest, SetAccountTokensOnlyWorksWithRegisterationId) {
351 // Start with empty list.
352 mapper()->Initialize(GCMAccountMapper::AccountMappings());
354 std::vector<GCMClient::AccountTokenInfo> account_tokens;
355 account_tokens.push_back(MakeAccountTokenInfo("acc_id"));
356 mapper()->SetAccountTokens(account_tokens);
358 EXPECT_TRUE(GetAccounts().empty());
360 account_tokens.clear();
361 account_tokens.push_back(MakeAccountTokenInfo("acc_id1"));
362 account_tokens.push_back(MakeAccountTokenInfo("acc_id2"));
363 mapper()->SetAccountTokens(account_tokens);
365 EXPECT_TRUE(GetAccounts().empty());
367 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
369 GCMAccountMapper::AccountMappings mappings = GetAccounts();
370 EXPECT_EQ(2UL, mappings.size());
371 EXPECT_EQ("acc_id1", mappings[0].account_id);
372 EXPECT_EQ("acc_id2", mappings[1].account_id);
375 // Tests the part where a new account is added with a token, to the point when
376 // GCM message is sent.
377 TEST_F(GCMAccountMapperTest, AddMappingToMessageSent) {
378 mapper()->Initialize(GCMAccountMapper::AccountMappings());
379 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
381 std::vector<GCMClient::AccountTokenInfo> account_tokens;
382 GCMClient::AccountTokenInfo account_token = MakeAccountTokenInfo("acc_id");
383 account_tokens.push_back(account_token);
384 mapper()->SetAccountTokens(account_tokens);
386 GCMAccountMapper::AccountMappings mappings = GetAccounts();
387 EXPECT_EQ(1UL, mappings.size());
388 GCMAccountMapper::AccountMappings::const_iterator iter = mappings.begin();
389 EXPECT_EQ("acc_id", iter->account_id);
390 EXPECT_EQ("acc_id@gmail.com", iter->email);
391 EXPECT_EQ("acc_id_token", iter->access_token);
392 EXPECT_EQ(AccountMapping::NEW, iter->status);
393 EXPECT_EQ(base::Time(), iter->status_change_timestamp);
395 EXPECT_TRUE(!gcm_driver().last_message_id().empty());
398 // Tests the part where GCM message is successfully queued.
399 TEST_F(GCMAccountMapperTest, AddMappingMessageQueued) {
400 mapper()->Initialize(GCMAccountMapper::AccountMappings());
401 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
403 std::vector<GCMClient::AccountTokenInfo> account_tokens;
404 GCMClient::AccountTokenInfo account_token = MakeAccountTokenInfo("acc_id");
405 account_tokens.push_back(account_token);
406 mapper()->SetAccountTokens(account_tokens);
408 clock()->SetNow(base::Time::Now());
409 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS);
411 EXPECT_EQ(account_token.email, gcm_driver().last_account_mapping().email);
412 EXPECT_EQ(account_token.account_id,
413 gcm_driver().last_account_mapping().account_id);
414 EXPECT_EQ(account_token.access_token,
415 gcm_driver().last_account_mapping().access_token);
416 EXPECT_EQ(AccountMapping::ADDING, gcm_driver().last_account_mapping().status);
417 EXPECT_EQ(clock()->Now(),
418 gcm_driver().last_account_mapping().status_change_timestamp);
419 EXPECT_EQ(gcm_driver().last_message_id(),
420 gcm_driver().last_account_mapping().last_message_id);
422 GCMAccountMapper::AccountMappings mappings = GetAccounts();
423 GCMAccountMapper::AccountMappings::const_iterator iter = mappings.begin();
424 EXPECT_EQ(account_token.email, iter->email);
425 EXPECT_EQ(account_token.account_id, iter->account_id);
426 EXPECT_EQ(account_token.access_token, iter->access_token);
427 EXPECT_EQ(AccountMapping::ADDING, iter->status);
428 EXPECT_EQ(clock()->Now(), iter->status_change_timestamp);
429 EXPECT_EQ(gcm_driver().last_message_id(), iter->last_message_id);
432 // Tests status change from ADDING to MAPPED (Message is acknowledged).
433 TEST_F(GCMAccountMapperTest, AddMappingMessageAcknowledged) {
434 mapper()->Initialize(GCMAccountMapper::AccountMappings());
435 gcm_driver().AddAppHandler(kGCMAccountMapperAppId, mapper());
436 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
438 std::vector<GCMClient::AccountTokenInfo> account_tokens;
439 GCMClient::AccountTokenInfo account_token = MakeAccountTokenInfo("acc_id");
440 account_tokens.push_back(account_token);
441 mapper()->SetAccountTokens(account_tokens);
443 clock()->SetNow(base::Time::Now());
444 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS);
445 clock()->SetNow(base::Time::Now());
446 gcm_driver().AcknowledgeSend(gcm_driver().last_message_id());
448 EXPECT_EQ(account_token.email, gcm_driver().last_account_mapping().email);
449 EXPECT_EQ(account_token.account_id,
450 gcm_driver().last_account_mapping().account_id);
451 EXPECT_EQ(account_token.access_token,
452 gcm_driver().last_account_mapping().access_token);
453 EXPECT_EQ(AccountMapping::MAPPED, gcm_driver().last_account_mapping().status);
454 EXPECT_EQ(clock()->Now(),
455 gcm_driver().last_account_mapping().status_change_timestamp);
456 EXPECT_TRUE(gcm_driver().last_account_mapping().last_message_id.empty());
458 GCMAccountMapper::AccountMappings mappings = GetAccounts();
459 GCMAccountMapper::AccountMappings::const_iterator iter = mappings.begin();
460 EXPECT_EQ(account_token.email, iter->email);
461 EXPECT_EQ(account_token.account_id, iter->account_id);
462 EXPECT_EQ(account_token.access_token, iter->access_token);
463 EXPECT_EQ(AccountMapping::MAPPED, iter->status);
464 EXPECT_EQ(clock()->Now(), iter->status_change_timestamp);
465 EXPECT_TRUE(iter->last_message_id.empty());
468 // Tests status change form ADDING to MAPPED (When message was acknowledged,
469 // after Chrome was restarted).
470 TEST_F(GCMAccountMapperTest, AddMappingMessageAckedAfterRestart) {
471 mapper()->Initialize(GCMAccountMapper::AccountMappings());
472 gcm_driver().AddAppHandler(kGCMAccountMapperAppId, mapper());
473 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
475 std::vector<GCMClient::AccountTokenInfo> account_tokens;
476 GCMClient::AccountTokenInfo account_token = MakeAccountTokenInfo("acc_id");
477 account_tokens.push_back(account_token);
478 mapper()->SetAccountTokens(account_tokens);
480 clock()->SetNow(base::Time::Now());
481 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS);
483 Restart();
484 GCMAccountMapper::AccountMappings stored_mappings;
485 stored_mappings.push_back(gcm_driver().last_account_mapping());
486 mapper()->Initialize(stored_mappings);
487 gcm_driver().AddAppHandler(kGCMAccountMapperAppId, mapper());
489 clock()->SetNow(base::Time::Now());
490 gcm_driver().AcknowledgeSend(gcm_driver().last_message_id());
492 EXPECT_EQ(account_token.email, gcm_driver().last_account_mapping().email);
493 EXPECT_EQ(account_token.account_id,
494 gcm_driver().last_account_mapping().account_id);
495 EXPECT_EQ(account_token.access_token,
496 gcm_driver().last_account_mapping().access_token);
497 EXPECT_EQ(AccountMapping::MAPPED, gcm_driver().last_account_mapping().status);
498 EXPECT_EQ(clock()->Now(),
499 gcm_driver().last_account_mapping().status_change_timestamp);
500 EXPECT_TRUE(gcm_driver().last_account_mapping().last_message_id.empty());
502 GCMAccountMapper::AccountMappings mappings = GetAccounts();
503 GCMAccountMapper::AccountMappings::const_iterator iter = mappings.begin();
504 EXPECT_EQ(account_token.email, iter->email);
505 EXPECT_EQ(account_token.account_id, iter->account_id);
506 EXPECT_EQ(account_token.access_token, iter->access_token);
507 EXPECT_EQ(AccountMapping::MAPPED, iter->status);
508 EXPECT_EQ(clock()->Now(), iter->status_change_timestamp);
509 EXPECT_TRUE(iter->last_message_id.empty());
512 // Tests a case when ADD message times out for a new account.
513 TEST_F(GCMAccountMapperTest, AddMappingMessageSendErrorForNewAccount) {
514 mapper()->Initialize(GCMAccountMapper::AccountMappings());
515 gcm_driver().AddAppHandler(kGCMAccountMapperAppId, mapper());
516 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
518 std::vector<GCMClient::AccountTokenInfo> account_tokens;
519 GCMClient::AccountTokenInfo account_token = MakeAccountTokenInfo("acc_id");
520 account_tokens.push_back(account_token);
521 mapper()->SetAccountTokens(account_tokens);
523 clock()->SetNow(base::Time::Now());
524 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS);
526 clock()->SetNow(base::Time::Now());
527 std::string old_message_id = gcm_driver().last_message_id();
528 gcm_driver().MessageSendError(old_message_id);
530 // No new message is sent because of the send error, as the token is stale.
531 // Because the account was new, the entry should be deleted.
532 EXPECT_EQ(old_message_id, gcm_driver().last_message_id());
533 EXPECT_EQ(account_token.account_id, gcm_driver().last_removed_account_id());
534 EXPECT_TRUE(GetAccounts().empty());
537 /// Tests a case when ADD message times out for a MAPPED account.
538 TEST_F(GCMAccountMapperTest, AddMappingMessageSendErrorForMappedAccount) {
539 // Start with one account that is mapped.
540 base::Time status_change_timestamp = base::Time::Now();
541 AccountMapping mapping = MakeAccountMapping("acc_id",
542 AccountMapping::MAPPED,
543 status_change_timestamp,
544 "add_message_id");
546 GCMAccountMapper::AccountMappings stored_mappings;
547 stored_mappings.push_back(mapping);
548 mapper()->Initialize(stored_mappings);
549 gcm_driver().AddAppHandler(kGCMAccountMapperAppId, mapper());
550 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
552 clock()->SetNow(base::Time::Now());
553 gcm_driver().MessageSendError("add_message_id");
555 // No new message is sent because of the send error, as the token is stale.
556 // Because the account was new, the entry should be deleted.
557 EXPECT_TRUE(gcm_driver().last_message_id().empty());
559 GCMAccountMapper::AccountMappings mappings = GetAccounts();
560 GCMAccountMapper::AccountMappings::const_iterator iter = mappings.begin();
561 EXPECT_EQ(mapping.email, iter->email);
562 EXPECT_EQ(mapping.account_id, iter->account_id);
563 EXPECT_EQ(mapping.access_token, iter->access_token);
564 EXPECT_EQ(AccountMapping::MAPPED, iter->status);
565 EXPECT_EQ(status_change_timestamp, iter->status_change_timestamp);
566 EXPECT_TRUE(iter->last_message_id.empty());
569 // Tests that a missing token for an account will trigger removing of that
570 // account. This test goes only until the message is passed to GCM.
571 TEST_F(GCMAccountMapperTest, RemoveMappingToMessageSent) {
572 // Start with one account that is mapped.
573 AccountMapping mapping = MakeAccountMapping("acc_id",
574 AccountMapping::MAPPED,
575 base::Time::Now(),
576 std::string());
578 GCMAccountMapper::AccountMappings stored_mappings;
579 stored_mappings.push_back(mapping);
580 mapper()->Initialize(stored_mappings);
581 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
582 clock()->SetNow(base::Time::Now());
584 mapper()->SetAccountTokens(std::vector<GCMClient::AccountTokenInfo>());
586 EXPECT_EQ(mapping.account_id, gcm_driver().last_account_mapping().account_id);
587 EXPECT_EQ(mapping.email, gcm_driver().last_account_mapping().email);
588 EXPECT_EQ(AccountMapping::REMOVING,
589 gcm_driver().last_account_mapping().status);
590 EXPECT_EQ(clock()->Now(),
591 gcm_driver().last_account_mapping().status_change_timestamp);
592 EXPECT_TRUE(gcm_driver().last_account_mapping().last_message_id.empty());
594 GCMAccountMapper::AccountMappings mappings = GetAccounts();
595 GCMAccountMapper::AccountMappings::const_iterator iter = mappings.begin();
596 EXPECT_EQ(mapping.email, iter->email);
597 EXPECT_EQ(mapping.account_id, iter->account_id);
598 EXPECT_EQ(mapping.access_token, iter->access_token);
599 EXPECT_EQ(AccountMapping::REMOVING, iter->status);
600 EXPECT_EQ(clock()->Now(), iter->status_change_timestamp);
601 EXPECT_TRUE(iter->last_message_id.empty());
604 // Tests that a missing token for an account will trigger removing of that
605 // account. This test goes until the message is queued by GCM.
606 TEST_F(GCMAccountMapperTest, RemoveMappingMessageQueued) {
607 // Start with one account that is mapped.
608 AccountMapping mapping = MakeAccountMapping("acc_id",
609 AccountMapping::MAPPED,
610 base::Time::Now(),
611 std::string());
613 GCMAccountMapper::AccountMappings stored_mappings;
614 stored_mappings.push_back(mapping);
615 mapper()->Initialize(stored_mappings);
616 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
617 clock()->SetNow(base::Time::Now());
618 base::Time status_change_timestamp = clock()->Now();
620 mapper()->SetAccountTokens(std::vector<GCMClient::AccountTokenInfo>());
621 clock()->SetNow(base::Time::Now());
622 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS);
624 EXPECT_EQ(mapping.account_id, gcm_driver().last_account_mapping().account_id);
625 EXPECT_EQ(mapping.email, gcm_driver().last_account_mapping().email);
626 EXPECT_EQ(AccountMapping::REMOVING,
627 gcm_driver().last_account_mapping().status);
628 EXPECT_EQ(status_change_timestamp,
629 gcm_driver().last_account_mapping().status_change_timestamp);
630 EXPECT_TRUE(!gcm_driver().last_account_mapping().last_message_id.empty());
632 GCMAccountMapper::AccountMappings mappings = GetAccounts();
633 GCMAccountMapper::AccountMappings::const_iterator iter = mappings.begin();
634 EXPECT_EQ(mapping.email, iter->email);
635 EXPECT_EQ(mapping.account_id, iter->account_id);
636 EXPECT_EQ(mapping.access_token, iter->access_token);
637 EXPECT_EQ(AccountMapping::REMOVING, iter->status);
638 EXPECT_EQ(status_change_timestamp, iter->status_change_timestamp);
639 EXPECT_EQ(gcm_driver().last_account_mapping().last_message_id,
640 iter->last_message_id);
643 // Tests that a missing token for an account will trigger removing of that
644 // account. This test goes until the message is acknowledged by GCM.
645 // This is a complete success scenario for account removal, and it end with
646 // account mapping being completely gone.
647 TEST_F(GCMAccountMapperTest, RemoveMappingMessageAcknowledged) {
648 // Start with one account that is mapped.
649 AccountMapping mapping = MakeAccountMapping("acc_id",
650 AccountMapping::MAPPED,
651 base::Time::Now(),
652 std::string());
654 GCMAccountMapper::AccountMappings stored_mappings;
655 stored_mappings.push_back(mapping);
656 mapper()->Initialize(stored_mappings);
657 gcm_driver().AddAppHandler(kGCMAccountMapperAppId, mapper());
658 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
659 clock()->SetNow(base::Time::Now());
661 mapper()->SetAccountTokens(std::vector<GCMClient::AccountTokenInfo>());
662 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS);
663 gcm_driver().AcknowledgeSend(gcm_driver().last_message_id());
665 EXPECT_EQ(mapping.account_id, gcm_driver().last_removed_account_id());
667 GCMAccountMapper::AccountMappings mappings = GetAccounts();
668 EXPECT_TRUE(mappings.empty());
671 // Tests that account removing proceeds, when a removing message is acked after
672 // Chrome was restarted.
673 TEST_F(GCMAccountMapperTest, RemoveMappingMessageAckedAfterRestart) {
674 // Start with one account that is mapped.
675 AccountMapping mapping = MakeAccountMapping("acc_id",
676 AccountMapping::REMOVING,
677 base::Time::Now(),
678 "remove_message_id");
680 GCMAccountMapper::AccountMappings stored_mappings;
681 stored_mappings.push_back(mapping);
682 mapper()->Initialize(stored_mappings);
683 gcm_driver().AddAppHandler(kGCMAccountMapperAppId, mapper());
685 gcm_driver().AcknowledgeSend("remove_message_id");
687 EXPECT_EQ(mapping.account_id, gcm_driver().last_removed_account_id());
689 GCMAccountMapper::AccountMappings mappings = GetAccounts();
690 EXPECT_TRUE(mappings.empty());
693 // Tests that account removing proceeds, when a removing message is acked after
694 // Chrome was restarted.
695 TEST_F(GCMAccountMapperTest, RemoveMappingMessageSendError) {
696 // Start with one account that is mapped.
697 base::Time status_change_timestamp = base::Time::Now();
698 AccountMapping mapping = MakeAccountMapping("acc_id",
699 AccountMapping::REMOVING,
700 status_change_timestamp,
701 "remove_message_id");
703 GCMAccountMapper::AccountMappings stored_mappings;
704 stored_mappings.push_back(mapping);
705 mapper()->Initialize(stored_mappings);
706 gcm_driver().AddAppHandler(kGCMAccountMapperAppId, mapper());
708 clock()->SetNow(base::Time::Now());
709 gcm_driver().MessageSendError("remove_message_id");
711 EXPECT_TRUE(gcm_driver().last_removed_account_id().empty());
713 EXPECT_EQ(mapping.account_id, gcm_driver().last_account_mapping().account_id);
714 EXPECT_EQ(mapping.email, gcm_driver().last_account_mapping().email);
715 EXPECT_EQ(AccountMapping::REMOVING,
716 gcm_driver().last_account_mapping().status);
717 EXPECT_EQ(status_change_timestamp,
718 gcm_driver().last_account_mapping().status_change_timestamp);
719 // Message is not persisted, until send is completed.
720 EXPECT_TRUE(gcm_driver().last_account_mapping().last_message_id.empty());
722 GCMAccountMapper::AccountMappings mappings = GetAccounts();
723 GCMAccountMapper::AccountMappings::const_iterator iter = mappings.begin();
724 EXPECT_EQ(mapping.email, iter->email);
725 EXPECT_EQ(mapping.account_id, iter->account_id);
726 EXPECT_TRUE(iter->access_token.empty());
727 EXPECT_EQ(AccountMapping::REMOVING, iter->status);
728 EXPECT_EQ(status_change_timestamp, iter->status_change_timestamp);
729 EXPECT_TRUE(iter->last_message_id.empty());
732 // Tests that, if a new token arrives when the adding message is in progress
733 // no new message is sent and account mapper still waits for the first one to
734 // complete.
735 TEST_F(GCMAccountMapperTest, TokenIsRefreshedWhenAdding) {
736 mapper()->Initialize(GCMAccountMapper::AccountMappings());
737 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
739 clock()->SetNow(base::Time::Now());
740 std::vector<GCMClient::AccountTokenInfo> account_tokens;
741 GCMClient::AccountTokenInfo account_token = MakeAccountTokenInfo("acc_id");
742 account_tokens.push_back(account_token);
743 mapper()->SetAccountTokens(account_tokens);
744 DCHECK_EQ(CustomFakeGCMDriver::SEND_STARTED, gcm_driver().last_action());
746 clock()->SetNow(base::Time::Now());
747 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS);
748 DCHECK_EQ(CustomFakeGCMDriver::SEND_FINISHED, gcm_driver().last_action());
750 // Providing another token and clearing status.
751 gcm_driver().Clear();
752 mapper()->SetAccountTokens(account_tokens);
753 DCHECK_EQ(CustomFakeGCMDriver::NONE, gcm_driver().last_action());
756 // Tests that, if a new token arrives when a removing message is in progress
757 // a new adding message is sent and while account mapping status is changed to
758 // mapped. If the original Removing message arrives it is discarded.
759 TEST_F(GCMAccountMapperTest, TokenIsRefreshedWhenRemoving) {
760 // Start with one account that is mapped.
761 AccountMapping mapping = MakeAccountMapping(
762 "acc_id", AccountMapping::MAPPED, base::Time::Now(), std::string());
764 GCMAccountMapper::AccountMappings stored_mappings;
765 stored_mappings.push_back(mapping);
766 mapper()->Initialize(stored_mappings);
767 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
768 clock()->SetNow(base::Time::Now());
770 // Remove the token to trigger a remove message to be sent
771 mapper()->SetAccountTokens(std::vector<GCMClient::AccountTokenInfo>());
772 EXPECT_EQ(CustomFakeGCMDriver::SEND_STARTED, gcm_driver().last_action());
773 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS);
774 EXPECT_EQ(CustomFakeGCMDriver::SEND_FINISHED, gcm_driver().last_action());
776 std::string remove_message_id = gcm_driver().last_message_id();
777 gcm_driver().Clear();
779 // The account mapping for acc_id is now in status REMOVING.
780 // Adding the token for that account.
781 clock()->SetNow(base::Time::Now());
782 std::vector<GCMClient::AccountTokenInfo> account_tokens;
783 GCMClient::AccountTokenInfo account_token = MakeAccountTokenInfo("acc_id");
784 account_tokens.push_back(account_token);
785 mapper()->SetAccountTokens(account_tokens);
786 DCHECK_EQ(CustomFakeGCMDriver::SEND_STARTED, gcm_driver().last_action());
787 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS);
788 EXPECT_EQ(CustomFakeGCMDriver::SEND_FINISHED, gcm_driver().last_action());
790 std::string add_message_id = gcm_driver().last_message_id();
792 // A remove message confirmation arrives now, but should be ignored.
793 gcm_driver().AcknowledgeSend(remove_message_id);
795 GCMAccountMapper::AccountMappings mappings = GetAccounts();
796 GCMAccountMapper::AccountMappings::const_iterator iter = mappings.begin();
797 EXPECT_EQ(mapping.email, iter->email);
798 EXPECT_EQ(mapping.account_id, iter->account_id);
799 EXPECT_FALSE(iter->access_token.empty());
800 EXPECT_EQ(AccountMapping::MAPPED, iter->status);
801 // Status change timestamp is set to very long time ago, to make sure the next
802 // round of mapping picks it up.
803 EXPECT_EQ(base::Time(), iter->status_change_timestamp);
804 EXPECT_EQ(add_message_id, iter->last_message_id);
807 // Tests adding/removing works for multiple accounts, after a restart and when
808 // tokens are periodically delierverd.
809 TEST_F(GCMAccountMapperTest, MultipleAccountMappings) {
810 clock()->SetNow(base::Time::Now());
811 base::Time half_hour_ago = clock()->Now() - base::TimeDelta::FromMinutes(30);
812 GCMAccountMapper::AccountMappings stored_mappings;
813 stored_mappings.push_back(MakeAccountMapping(
814 "acc_id_0", AccountMapping::ADDING, half_hour_ago, "acc_id_0_msg"));
815 stored_mappings.push_back(MakeAccountMapping(
816 "acc_id_1", AccountMapping::MAPPED, half_hour_ago, "acc_id_1_msg"));
817 stored_mappings.push_back(MakeAccountMapping(
818 "acc_id_2", AccountMapping::REMOVING, half_hour_ago, "acc_id_2_msg"));
820 mapper()->Initialize(stored_mappings);
821 gcm_driver().AddAppHandler(kGCMAccountMapperAppId, mapper());
822 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
824 GCMAccountMapper::AccountMappings expected_mappings(stored_mappings);
826 // Finish messages after a restart.
827 clock()->SetNow(base::Time::Now());
828 gcm_driver().AcknowledgeSend(expected_mappings[0].last_message_id);
829 expected_mappings[0].status_change_timestamp = clock()->Now();
830 expected_mappings[0].status = AccountMapping::MAPPED;
831 expected_mappings[0].last_message_id.clear();
833 clock()->SetNow(base::Time::Now());
834 gcm_driver().AcknowledgeSend(expected_mappings[1].last_message_id);
835 expected_mappings[1].status_change_timestamp = clock()->Now();
836 expected_mappings[1].status = AccountMapping::MAPPED;
837 expected_mappings[1].last_message_id.clear();
839 // Upon success last element is removed.
840 clock()->SetNow(base::Time::Now());
841 gcm_driver().AcknowledgeSend(expected_mappings[2].last_message_id);
842 expected_mappings.pop_back();
844 VerifyMappings(expected_mappings, GetAccounts(), "Step 1, After restart");
846 // One of accounts gets removed.
847 std::vector<GCMClient::AccountTokenInfo> account_tokens;
848 account_tokens.push_back(MakeAccountTokenInfo("acc_id_0"));
850 // Advance a day to make sure existing mappings will be reported.
851 clock()->SetNow(clock()->Now() + base::TimeDelta::FromDays(1));
852 mapper()->SetAccountTokens(account_tokens);
854 expected_mappings[0].status = AccountMapping::MAPPED;
855 expected_mappings[1].status = AccountMapping::REMOVING;
856 expected_mappings[1].status_change_timestamp = clock()->Now();
858 gcm_driver().CompleteSendAllMessages();
860 VerifyMappings(
861 expected_mappings, GetAccounts(), "Step 2, One account is being removed");
863 clock()->SetNow(clock()->Now() + base::TimeDelta::FromSeconds(5));
864 gcm_driver().AcknowledgeSendAllMessages();
866 expected_mappings[0].status_change_timestamp = clock()->Now();
867 expected_mappings.pop_back();
869 VerifyMappings(
870 expected_mappings, GetAccounts(), "Step 3, Removing completed");
872 account_tokens.clear();
873 account_tokens.push_back(MakeAccountTokenInfo("acc_id_0"));
874 account_tokens.push_back(MakeAccountTokenInfo("acc_id_3"));
875 account_tokens.push_back(MakeAccountTokenInfo("acc_id_4"));
877 // Advance a day to make sure existing mappings will be reported.
878 clock()->SetNow(clock()->Now() + base::TimeDelta::FromDays(1));
879 mapper()->SetAccountTokens(account_tokens);
881 // Mapping from acc_id_0 still in position 0
882 expected_mappings.push_back(MakeAccountMapping(
883 "acc_id_3", AccountMapping::NEW, base::Time(), std::string()));
884 expected_mappings.push_back(MakeAccountMapping(
885 "acc_id_4", AccountMapping::NEW, base::Time(), std::string()));
887 VerifyMappings(expected_mappings, GetAccounts(), "Step 4, Two new accounts");
889 clock()->SetNow(clock()->Now() + base::TimeDelta::FromSeconds(1));
890 gcm_driver().CompleteSendAllMessages();
892 expected_mappings[1].status = AccountMapping::ADDING;
893 expected_mappings[1].status_change_timestamp = clock()->Now();
894 expected_mappings[2].status = AccountMapping::ADDING;
895 expected_mappings[2].status_change_timestamp = clock()->Now();
897 VerifyMappings(
898 expected_mappings, GetAccounts(), "Step 5, Two accounts being added");
900 clock()->SetNow(clock()->Now() + base::TimeDelta::FromSeconds(5));
901 gcm_driver().AcknowledgeSendAllMessages();
903 expected_mappings[0].status_change_timestamp = clock()->Now();
904 expected_mappings[1].status_change_timestamp = clock()->Now();
905 expected_mappings[1].status = AccountMapping::MAPPED;
906 expected_mappings[2].status_change_timestamp = clock()->Now();
907 expected_mappings[2].status = AccountMapping::MAPPED;
909 VerifyMappings(
910 expected_mappings, GetAccounts(), "Step 6, Three mapped accounts");
913 } // namespace gcm