Try to work around that clang/win bug in another file.
[chromium-blink-merge.git] / components / gcm_driver / gcm_account_mapper_unittest.cc
blobff160887461f8a9cdb0e6eff78fdcf506a0313eb
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 GCMClient::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 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();
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 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_;
274 private:
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() {
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(
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,
349 base::Time::Now(),
350 std::string());
351 AccountMapping account_mapping2 = MakeAccountMapping("acc_id2",
352 AccountMapping::ADDING,
353 base::Time::Now(),
354 "add_message_1");
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());
372 ++iter;
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
383 // available.
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);
517 Restart();
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,
578 "add_message_id");
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,
609 base::Time::Now(),
610 std::string());
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,
644 base::Time::Now(),
645 std::string());
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,
685 base::Time::Now(),
686 std::string());
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,
711 base::Time::Now(),
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
768 // complete.
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();
894 VerifyMappings(
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();
903 VerifyMappings(
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();
931 VerifyMappings(
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;
943 VerifyMappings(
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);
967 } // namespace gcm