blob: 7b76b36ca4a938cffd3ea26fa2af51314dcfc6ce [file] [log] [blame]
fgorskic1047312014-09-04 16:48:541// 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.
4
5#include "components/gcm_driver/gcm_account_mapper.h"
6
fgorski47869f02015-02-27 23:16:037#include "base/bind.h"
fgorskic1047312014-09-04 16:48:548#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"
14
15namespace gcm {
16
17namespace {
18
19const char kGCMAccountMapperSenderId[] = "745476177629";
fgorskiec85dd42015-02-13 00:15:4320const char kGCMAccountMapperSendTo[] = "google.com";
fgorskic1047312014-09-04 16:48:5421const char kRegistrationId[] = "reg_id";
fgorski47869f02015-02-27 23:16:0322const char kEmbeddedAppIdKey[] = "gcmb";
23const char kTestAppId[] = "test_app_id";
24const char kTestDataKey[] = "data_key";
25const char kTestDataValue[] = "data_value";
26const char kTestCollapseKey[] = "test_collapse_key";
27const char kTestSenderId[] = "test_sender_id";
28
fgorskic1047312014-09-04 16:48:5429
30AccountMapping 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;
42}
43
44GCMClient::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;
51}
52
fgorski93f48642014-09-10 23:32:5353void 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;
77 }
78}
79
fgorskic1047312014-09-04 16:48:5480class CustomFakeGCMDriver : public FakeGCMDriver {
81 public:
fgorski93f48642014-09-10 23:32:5382 enum LastMessageAction {
83 NONE,
84 SEND_STARTED,
85 SEND_FINISHED,
86 SEND_ACKNOWLEDGED
87 };
88
fgorskic1047312014-09-04 16:48:5489 CustomFakeGCMDriver();
dcheng00ea022b2014-10-21 11:24:5690 ~CustomFakeGCMDriver() override;
fgorskic1047312014-09-04 16:48:5491
fgorski47869f02015-02-27 23:16:0392 // GCMDriver implementation:
dcheng00ea022b2014-10-21 11:24:5693 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;
fgorskic1047312014-09-04 16:48:54100
fgorskiba729da2014-09-20 20:55:55101 void CompleteRegister(const std::string& registration_id,
102 GCMClient::Result result);
fgorskic1047312014-09-04 16:48:54103 void CompleteSend(const std::string& message_id, GCMClient::Result result);
fgorski93f48642014-09-10 23:32:53104 void AcknowledgeSend(const std::string& message_id);
fgorskic1047312014-09-04 16:48:54105 void MessageSendError(const std::string& message_id);
106
fgorski93f48642014-09-10 23:32:53107 void CompleteSendAllMessages();
108 void AcknowledgeSendAllMessages();
fgorski93f48642014-09-10 23:32:53109 void SetLastMessageAction(const std::string& message_id,
110 LastMessageAction action);
111 void Clear();
112
fgorskic1047312014-09-04 16:48:54113 const AccountMapping& last_account_mapping() const {
114 return account_mapping_;
115 }
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_;
119 }
fgorski93f48642014-09-10 23:32:53120 LastMessageAction last_action() const { return last_action_; }
fgorskiba729da2014-09-20 20:55:55121 bool registration_id_requested() const { return registration_id_requested_; }
fgorskic1047312014-09-04 16:48:54122
123 protected:
dcheng00ea022b2014-10-21 11:24:56124 void SendImpl(const std::string& app_id,
125 const std::string& receiver_id,
mvanouwerkerkf8633deb2015-07-13 11:04:06126 const OutgoingMessage& message) override;
fgorskic1047312014-09-04 16:48:54127
128 private:
129 AccountMapping account_mapping_;
130 std::string last_message_id_;
131 std::string last_removed_account_id_;
fgorski93f48642014-09-10 23:32:53132 LastMessageAction last_action_;
133 std::map<std::string, LastMessageAction> all_messages_;
fgorskiba729da2014-09-20 20:55:55134 bool registration_id_requested_;
fgorskic1047312014-09-04 16:48:54135};
136
fgorskiba729da2014-09-20 20:55:55137CustomFakeGCMDriver::CustomFakeGCMDriver()
138 : last_action_(NONE), registration_id_requested_(false) {
fgorskic1047312014-09-04 16:48:54139}
140
141CustomFakeGCMDriver::~CustomFakeGCMDriver() {
142}
143
144void 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;
153}
154
155void CustomFakeGCMDriver::RemoveAccountMapping(const std::string& account_id) {
156 last_removed_account_id_ = account_id;
157}
158
159void CustomFakeGCMDriver::AddAppHandler(const std::string& app_id,
160 GCMAppHandler* handler) {
161 GCMDriver::AddAppHandler(app_id, handler);
162}
163
164void CustomFakeGCMDriver::RemoveAppHandler(const std::string& app_id) {
165 GCMDriver::RemoveAppHandler(app_id);
166}
167
fgorskiba729da2014-09-20 20:55:55168void 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;
175}
176
177void CustomFakeGCMDriver::CompleteRegister(const std::string& registration_id,
178 GCMClient::Result result) {
179 RegisterFinished(kGCMAccountMapperAppId, registration_id, result);
180}
181
fgorskic1047312014-09-04 16:48:54182void CustomFakeGCMDriver::CompleteSend(const std::string& message_id,
183 GCMClient::Result result) {
184 SendFinished(kGCMAccountMapperAppId, message_id, result);
fgorski93f48642014-09-10 23:32:53185 SetLastMessageAction(message_id, SEND_FINISHED);
fgorskic1047312014-09-04 16:48:54186}
187
fgorski93f48642014-09-10 23:32:53188void CustomFakeGCMDriver::AcknowledgeSend(const std::string& message_id) {
fgorskic1047312014-09-04 16:48:54189 GetAppHandler(kGCMAccountMapperAppId)
190 ->OnSendAcknowledged(kGCMAccountMapperAppId, message_id);
fgorski93f48642014-09-10 23:32:53191 SetLastMessageAction(message_id, SEND_ACKNOWLEDGED);
fgorskic1047312014-09-04 16:48:54192}
193
194void 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);
200}
201
202void CustomFakeGCMDriver::SendImpl(const std::string& app_id,
203 const std::string& receiver_id,
mvanouwerkerkf8633deb2015-07-13 11:04:06204 const OutgoingMessage& message) {
fgorskic1047312014-09-04 16:48:54205 DCHECK_EQ(kGCMAccountMapperAppId, app_id);
fgorskiec85dd42015-02-13 00:15:43206 DCHECK_EQ(kGCMAccountMapperSendTo, receiver_id);
fgorskic1047312014-09-04 16:48:54207
fgorski93f48642014-09-10 23:32:53208 SetLastMessageAction(message.id, SEND_STARTED);
209}
210
211void 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);
218 }
219}
220
221void 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);
228 }
229}
230
231void CustomFakeGCMDriver::Clear() {
232 account_mapping_ = AccountMapping();
233 last_message_id_.clear();
234 last_removed_account_id_.clear();
235 last_action_ = NONE;
fgorskiba729da2014-09-20 20:55:55236 registration_id_requested_ = false;
fgorski93f48642014-09-10 23:32:53237}
238
239void 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;
fgorskic1047312014-09-04 16:48:54244}
245
246} // namespace
247
248class GCMAccountMapperTest : public testing::Test {
249 public:
250 GCMAccountMapperTest();
dcheng30a1b1542014-10-29 21:27:50251 ~GCMAccountMapperTest() override;
fgorskic1047312014-09-04 16:48:54252
253 void Restart();
254
fgorski47869f02015-02-27 23:16:03255 void Initialize(const GCMAccountMapper::AccountMappings mappings);
fgorski93f48642014-09-10 23:32:53256 const GCMAccountMapper::AccountMappings& GetAccounts() const {
fgorskic1047312014-09-04 16:48:54257 return account_mapper_->accounts_;
258 }
fgorski47869f02015-02-27 23:16:03259 void MessageReceived(const std::string& app_id,
mvanouwerkerkf8633deb2015-07-13 11:04:06260 const IncomingMessage& message);
fgorskic1047312014-09-04 16:48:54261
262 GCMAccountMapper* mapper() { return account_mapper_.get(); }
263
264 CustomFakeGCMDriver& gcm_driver() { return gcm_driver_; }
265
266 base::SimpleTestClock* clock() { return clock_; }
fgorski47869f02015-02-27 23:16:03267 const std::string& last_received_app_id() const {
268 return last_received_app_id_;
269 }
mvanouwerkerkf8633deb2015-07-13 11:04:06270 const IncomingMessage& last_received_message() const {
fgorski47869f02015-02-27 23:16:03271 return last_received_message_;
272 }
fgorskic1047312014-09-04 16:48:54273
274 private:
275 CustomFakeGCMDriver gcm_driver_;
276 scoped_ptr<GCMAccountMapper> account_mapper_;
277 base::SimpleTestClock* clock_;
fgorski47869f02015-02-27 23:16:03278 std::string last_received_app_id_;
mvanouwerkerkf8633deb2015-07-13 11:04:06279 IncomingMessage last_received_message_;
fgorskic1047312014-09-04 16:48:54280};
281
282GCMAccountMapperTest::GCMAccountMapperTest() {
283 Restart();
284}
285
286GCMAccountMapperTest::~GCMAccountMapperTest() {
287}
288
289void GCMAccountMapperTest::Restart() {
290 if (account_mapper_)
291 account_mapper_->ShutdownHandler();
fgorski83afd872014-10-16 01:11:52292 gcm_driver_.RemoveAppHandler(kGCMAccountMapperAppId);
fgorskic1047312014-09-04 16:48:54293 account_mapper_.reset(new GCMAccountMapper(&gcm_driver_));
294 scoped_ptr<base::SimpleTestClock> clock(new base::SimpleTestClock);
295 clock_ = clock.get();
dcheng1d86a702014-10-15 17:26:56296 account_mapper_->SetClockForTesting(clock.Pass());
fgorskic1047312014-09-04 16:48:54297}
298
fgorski47869f02015-02-27 23:16:03299void GCMAccountMapperTest::Initialize(
300 const GCMAccountMapper::AccountMappings mappings) {
301 mapper()->Initialize(mappings,
302 base::Bind(&GCMAccountMapperTest::MessageReceived,
303 base::Unretained(this)));
304}
305
mvanouwerkerkf8633deb2015-07-13 11:04:06306void GCMAccountMapperTest::MessageReceived(const std::string& app_id,
307 const IncomingMessage& message) {
fgorski47869f02015-02-27 23:16:03308 last_received_app_id_ = app_id;
309 last_received_message_ = message;
310}
311
fgorskic1047312014-09-04 16:48:54312// Tests the initialization of account mappings (from the store) when empty.
fgorskiba729da2014-09-20 20:55:55313// It also checks that initialization triggers registration ID request.
fgorskic1047312014-09-04 16:48:54314TEST_F(GCMAccountMapperTest, InitializeAccountMappingsEmpty) {
fgorskiba729da2014-09-20 20:55:55315 EXPECT_FALSE(gcm_driver().registration_id_requested());
fgorski47869f02015-02-27 23:16:03316 Initialize(GCMAccountMapper::AccountMappings());
fgorskic1047312014-09-04 16:48:54317 EXPECT_TRUE(GetAccounts().empty());
fgorskiba729da2014-09-20 20:55:55318 EXPECT_TRUE(gcm_driver().registration_id_requested());
319}
320
321// Tests that registration is retried, when new tokens are delivered and in no
322// other circumstances.
323TEST_F(GCMAccountMapperTest, RegistrationRetryUponFailure) {
fgorski47869f02015-02-27 23:16:03324 Initialize(GCMAccountMapper::AccountMappings());
fgorskiba729da2014-09-20 20:55:55325 EXPECT_TRUE(gcm_driver().registration_id_requested());
326 gcm_driver().Clear();
327
328 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::UNKNOWN_ERROR);
329 EXPECT_FALSE(gcm_driver().registration_id_requested());
330 gcm_driver().Clear();
331
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();
337
338 gcm_driver().CompleteRegister(kRegistrationId,
339 GCMClient::ASYNC_OPERATION_PENDING);
340 EXPECT_FALSE(gcm_driver().registration_id_requested());
fgorskic1047312014-09-04 16:48:54341}
342
343// Tests the initialization of account mappings (from the store).
344TEST_F(GCMAccountMapperTest, InitializeAccountMappings) {
fgorski93f48642014-09-10 23:32:53345 GCMAccountMapper::AccountMappings account_mappings;
fgorskic1047312014-09-04 16:48:54346 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);
356
fgorski47869f02015-02-27 23:16:03357 Initialize(account_mappings);
fgorskic1047312014-09-04 16:48:54358
fgorski93f48642014-09-10 23:32:53359 GCMAccountMapper::AccountMappings mappings = GetAccounts();
fgorskic1047312014-09-04 16:48:54360 EXPECT_EQ(2UL, mappings.size());
fgorski93f48642014-09-10 23:32:53361 GCMAccountMapper::AccountMappings::const_iterator iter = mappings.begin();
fgorskic1047312014-09-04 16:48:54362
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());
370
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);
379}
380
fgorskiba729da2014-09-20 20:55:55381// Tests that account tokens are not processed until registration ID is
382// available.
383TEST_F(GCMAccountMapperTest, SetAccountTokensOnlyWorksWithRegisterationId) {
384 // Start with empty list.
fgorski47869f02015-02-27 23:16:03385 Initialize(GCMAccountMapper::AccountMappings());
fgorskiba729da2014-09-20 20:55:55386
387 std::vector<GCMClient::AccountTokenInfo> account_tokens;
388 account_tokens.push_back(MakeAccountTokenInfo("acc_id"));
389 mapper()->SetAccountTokens(account_tokens);
390
391 EXPECT_TRUE(GetAccounts().empty());
392
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);
397
398 EXPECT_TRUE(GetAccounts().empty());
399
400 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
401
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);
406}
407
fgorskic1047312014-09-04 16:48:54408// Tests the part where a new account is added with a token, to the point when
409// GCM message is sent.
410TEST_F(GCMAccountMapperTest, AddMappingToMessageSent) {
fgorski47869f02015-02-27 23:16:03411 Initialize(GCMAccountMapper::AccountMappings());
fgorskiba729da2014-09-20 20:55:55412 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
fgorskic1047312014-09-04 16:48:54413
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);
418
fgorski93f48642014-09-10 23:32:53419 GCMAccountMapper::AccountMappings mappings = GetAccounts();
fgorskic1047312014-09-04 16:48:54420 EXPECT_EQ(1UL, mappings.size());
fgorski93f48642014-09-10 23:32:53421 GCMAccountMapper::AccountMappings::const_iterator iter = mappings.begin();
fgorskic1047312014-09-04 16:48:54422 EXPECT_EQ("acc_id", iter->account_id);
423 EXPECT_EQ("[email protected]", 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);
427
428 EXPECT_TRUE(!gcm_driver().last_message_id().empty());
429}
430
431// Tests the part where GCM message is successfully queued.
432TEST_F(GCMAccountMapperTest, AddMappingMessageQueued) {
fgorski47869f02015-02-27 23:16:03433 Initialize(GCMAccountMapper::AccountMappings());
fgorskiba729da2014-09-20 20:55:55434 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
fgorskic1047312014-09-04 16:48:54435
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);
440
441 clock()->SetNow(base::Time::Now());
442 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS);
443
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);
454
fgorski93f48642014-09-10 23:32:53455 GCMAccountMapper::AccountMappings mappings = GetAccounts();
456 GCMAccountMapper::AccountMappings::const_iterator iter = mappings.begin();
fgorskic1047312014-09-04 16:48:54457 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);
463}
464
465// Tests status change from ADDING to MAPPED (Message is acknowledged).
466TEST_F(GCMAccountMapperTest, AddMappingMessageAcknowledged) {
fgorski47869f02015-02-27 23:16:03467 Initialize(GCMAccountMapper::AccountMappings());
fgorski83afd872014-10-16 01:11:52468 gcm_driver().AddAppHandler(kGCMAccountMapperAppId, mapper());
fgorskiba729da2014-09-20 20:55:55469 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
fgorskic1047312014-09-04 16:48:54470
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);
475
476 clock()->SetNow(base::Time::Now());
477 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS);
478 clock()->SetNow(base::Time::Now());
fgorski93f48642014-09-10 23:32:53479 gcm_driver().AcknowledgeSend(gcm_driver().last_message_id());
fgorskic1047312014-09-04 16:48:54480
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());
490
fgorski93f48642014-09-10 23:32:53491 GCMAccountMapper::AccountMappings mappings = GetAccounts();
492 GCMAccountMapper::AccountMappings::const_iterator iter = mappings.begin();
fgorskic1047312014-09-04 16:48:54493 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());
499}
500
501// Tests status change form ADDING to MAPPED (When message was acknowledged,
502// after Chrome was restarted).
503TEST_F(GCMAccountMapperTest, AddMappingMessageAckedAfterRestart) {
fgorski47869f02015-02-27 23:16:03504 Initialize(GCMAccountMapper::AccountMappings());
fgorski83afd872014-10-16 01:11:52505 gcm_driver().AddAppHandler(kGCMAccountMapperAppId, mapper());
fgorskiba729da2014-09-20 20:55:55506 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
fgorskic1047312014-09-04 16:48:54507
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);
512
513 clock()->SetNow(base::Time::Now());
514 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS);
515
516 Restart();
fgorski93f48642014-09-10 23:32:53517 GCMAccountMapper::AccountMappings stored_mappings;
fgorskic1047312014-09-04 16:48:54518 stored_mappings.push_back(gcm_driver().last_account_mapping());
fgorski47869f02015-02-27 23:16:03519 Initialize(stored_mappings);
fgorski83afd872014-10-16 01:11:52520 gcm_driver().AddAppHandler(kGCMAccountMapperAppId, mapper());
fgorskic1047312014-09-04 16:48:54521
522 clock()->SetNow(base::Time::Now());
fgorski93f48642014-09-10 23:32:53523 gcm_driver().AcknowledgeSend(gcm_driver().last_message_id());
fgorskic1047312014-09-04 16:48:54524
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());
534
fgorski93f48642014-09-10 23:32:53535 GCMAccountMapper::AccountMappings mappings = GetAccounts();
536 GCMAccountMapper::AccountMappings::const_iterator iter = mappings.begin();
fgorskic1047312014-09-04 16:48:54537 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());
543}
544
545// Tests a case when ADD message times out for a new account.
546TEST_F(GCMAccountMapperTest, AddMappingMessageSendErrorForNewAccount) {
fgorski47869f02015-02-27 23:16:03547 Initialize(GCMAccountMapper::AccountMappings());
fgorski83afd872014-10-16 01:11:52548 gcm_driver().AddAppHandler(kGCMAccountMapperAppId, mapper());
fgorskiba729da2014-09-20 20:55:55549 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
fgorskic1047312014-09-04 16:48:54550
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);
555
556 clock()->SetNow(base::Time::Now());
557 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS);
558
559 clock()->SetNow(base::Time::Now());
560 std::string old_message_id = gcm_driver().last_message_id();
561 gcm_driver().MessageSendError(old_message_id);
562
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());
568}
569
570/// Tests a case when ADD message times out for a MAPPED account.
571TEST_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");
578
579 GCMAccountMapper::AccountMappings stored_mappings;
580 stored_mappings.push_back(mapping);
fgorski47869f02015-02-27 23:16:03581 Initialize(stored_mappings);
fgorski83afd872014-10-16 01:11:52582 gcm_driver().AddAppHandler(kGCMAccountMapperAppId, mapper());
fgorskiba729da2014-09-20 20:55:55583 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
fgorskic1047312014-09-04 16:48:54584
585 clock()->SetNow(base::Time::Now());
586 gcm_driver().MessageSendError("add_message_id");
587
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());
591
fgorski93f48642014-09-10 23:32:53592 GCMAccountMapper::AccountMappings mappings = GetAccounts();
593 GCMAccountMapper::AccountMappings::const_iterator iter = mappings.begin();
fgorskic1047312014-09-04 16:48:54594 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());
600}
601
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.
604TEST_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());
610
611 GCMAccountMapper::AccountMappings stored_mappings;
612 stored_mappings.push_back(mapping);
fgorski47869f02015-02-27 23:16:03613 Initialize(stored_mappings);
fgorskiba729da2014-09-20 20:55:55614 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
fgorskic1047312014-09-04 16:48:54615 clock()->SetNow(base::Time::Now());
616
617 mapper()->SetAccountTokens(std::vector<GCMClient::AccountTokenInfo>());
618
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());
626
fgorski93f48642014-09-10 23:32:53627 GCMAccountMapper::AccountMappings mappings = GetAccounts();
628 GCMAccountMapper::AccountMappings::const_iterator iter = mappings.begin();
fgorskic1047312014-09-04 16:48:54629 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());
635}
636
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.
639TEST_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());
645
646 GCMAccountMapper::AccountMappings stored_mappings;
647 stored_mappings.push_back(mapping);
fgorski47869f02015-02-27 23:16:03648 Initialize(stored_mappings);
fgorskiba729da2014-09-20 20:55:55649 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
fgorskic1047312014-09-04 16:48:54650 clock()->SetNow(base::Time::Now());
651 base::Time status_change_timestamp = clock()->Now();
652
653 mapper()->SetAccountTokens(std::vector<GCMClient::AccountTokenInfo>());
654 clock()->SetNow(base::Time::Now());
655 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS);
656
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());
664
fgorski93f48642014-09-10 23:32:53665 GCMAccountMapper::AccountMappings mappings = GetAccounts();
666 GCMAccountMapper::AccountMappings::const_iterator iter = mappings.begin();
fgorskic1047312014-09-04 16:48:54667 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);
674}
675
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.
680TEST_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());
686
687 GCMAccountMapper::AccountMappings stored_mappings;
688 stored_mappings.push_back(mapping);
fgorski47869f02015-02-27 23:16:03689 Initialize(stored_mappings);
fgorski83afd872014-10-16 01:11:52690 gcm_driver().AddAppHandler(kGCMAccountMapperAppId, mapper());
fgorskiba729da2014-09-20 20:55:55691 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
fgorskic1047312014-09-04 16:48:54692 clock()->SetNow(base::Time::Now());
693
694 mapper()->SetAccountTokens(std::vector<GCMClient::AccountTokenInfo>());
695 gcm_driver().CompleteSend(gcm_driver().last_message_id(), GCMClient::SUCCESS);
fgorski93f48642014-09-10 23:32:53696 gcm_driver().AcknowledgeSend(gcm_driver().last_message_id());
fgorskic1047312014-09-04 16:48:54697
698 EXPECT_EQ(mapping.account_id, gcm_driver().last_removed_account_id());
699
fgorski93f48642014-09-10 23:32:53700 GCMAccountMapper::AccountMappings mappings = GetAccounts();
fgorskic1047312014-09-04 16:48:54701 EXPECT_TRUE(mappings.empty());
702}
703
704// Tests that account removing proceeds, when a removing message is acked after
705// Chrome was restarted.
706TEST_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");
712
713 GCMAccountMapper::AccountMappings stored_mappings;
714 stored_mappings.push_back(mapping);
fgorski47869f02015-02-27 23:16:03715 Initialize(stored_mappings);
fgorski83afd872014-10-16 01:11:52716 gcm_driver().AddAppHandler(kGCMAccountMapperAppId, mapper());
fgorskic1047312014-09-04 16:48:54717
fgorski93f48642014-09-10 23:32:53718 gcm_driver().AcknowledgeSend("remove_message_id");
fgorskic1047312014-09-04 16:48:54719
720 EXPECT_EQ(mapping.account_id, gcm_driver().last_removed_account_id());
721
fgorski93f48642014-09-10 23:32:53722 GCMAccountMapper::AccountMappings mappings = GetAccounts();
fgorskic1047312014-09-04 16:48:54723 EXPECT_TRUE(mappings.empty());
724}
725
726// Tests that account removing proceeds, when a removing message is acked after
727// Chrome was restarted.
728TEST_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");
735
736 GCMAccountMapper::AccountMappings stored_mappings;
737 stored_mappings.push_back(mapping);
fgorski47869f02015-02-27 23:16:03738 Initialize(stored_mappings);
fgorski83afd872014-10-16 01:11:52739 gcm_driver().AddAppHandler(kGCMAccountMapperAppId, mapper());
fgorskic1047312014-09-04 16:48:54740
741 clock()->SetNow(base::Time::Now());
742 gcm_driver().MessageSendError("remove_message_id");
743
744 EXPECT_TRUE(gcm_driver().last_removed_account_id().empty());
745
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());
754
fgorski93f48642014-09-10 23:32:53755 GCMAccountMapper::AccountMappings mappings = GetAccounts();
756 GCMAccountMapper::AccountMappings::const_iterator iter = mappings.begin();
fgorskic1047312014-09-04 16:48:54757 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());
763}
764
fgorski93f48642014-09-10 23:32:53765// 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.
768TEST_F(GCMAccountMapperTest, TokenIsRefreshedWhenAdding) {
fgorski47869f02015-02-27 23:16:03769 Initialize(GCMAccountMapper::AccountMappings());
fgorskiba729da2014-09-20 20:55:55770 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
fgorski93f48642014-09-10 23:32:53771
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());
778
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());
782
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());
787}
788
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.
792TEST_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());
796
797 GCMAccountMapper::AccountMappings stored_mappings;
798 stored_mappings.push_back(mapping);
fgorski47869f02015-02-27 23:16:03799 Initialize(stored_mappings);
fgorskiba729da2014-09-20 20:55:55800 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
fgorski93f48642014-09-10 23:32:53801 clock()->SetNow(base::Time::Now());
802
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());
808
809 std::string remove_message_id = gcm_driver().last_message_id();
810 gcm_driver().Clear();
811
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());
822
823 std::string add_message_id = gcm_driver().last_message_id();
824
825 // A remove message confirmation arrives now, but should be ignored.
826 gcm_driver().AcknowledgeSend(remove_message_id);
827
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);
838}
839
840// Tests adding/removing works for multiple accounts, after a restart and when
841// tokens are periodically delierverd.
842TEST_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"));
852
fgorski47869f02015-02-27 23:16:03853 Initialize(stored_mappings);
fgorski83afd872014-10-16 01:11:52854 gcm_driver().AddAppHandler(kGCMAccountMapperAppId, mapper());
fgorskiba729da2014-09-20 20:55:55855 gcm_driver().CompleteRegister(kRegistrationId, GCMClient::SUCCESS);
fgorski93f48642014-09-10 23:32:53856
857 GCMAccountMapper::AccountMappings expected_mappings(stored_mappings);
858
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();
865
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();
871
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();
876
877 VerifyMappings(expected_mappings, GetAccounts(), "Step 1, After restart");
878
879 // One of accounts gets removed.
880 std::vector<GCMClient::AccountTokenInfo> account_tokens;
881 account_tokens.push_back(MakeAccountTokenInfo("acc_id_0"));
882
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);
886
887 expected_mappings[0].status = AccountMapping::MAPPED;
888 expected_mappings[1].status = AccountMapping::REMOVING;
889 expected_mappings[1].status_change_timestamp = clock()->Now();
890
891 gcm_driver().CompleteSendAllMessages();
892
893 VerifyMappings(
894 expected_mappings, GetAccounts(), "Step 2, One account is being removed");
895
896 clock()->SetNow(clock()->Now() + base::TimeDelta::FromSeconds(5));
897 gcm_driver().AcknowledgeSendAllMessages();
898
899 expected_mappings[0].status_change_timestamp = clock()->Now();
900 expected_mappings.pop_back();
901
902 VerifyMappings(
903 expected_mappings, GetAccounts(), "Step 3, Removing completed");
904
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"));
909
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);
913
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()));
919
920 VerifyMappings(expected_mappings, GetAccounts(), "Step 4, Two new accounts");
921
922 clock()->SetNow(clock()->Now() + base::TimeDelta::FromSeconds(1));
923 gcm_driver().CompleteSendAllMessages();
924
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();
929
930 VerifyMappings(
931 expected_mappings, GetAccounts(), "Step 5, Two accounts being added");
932
933 clock()->SetNow(clock()->Now() + base::TimeDelta::FromSeconds(5));
934 gcm_driver().AcknowledgeSendAllMessages();
935
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;
941
942 VerifyMappings(
943 expected_mappings, GetAccounts(), "Step 6, Three mapped accounts");
944}
945
fgorski47869f02015-02-27 23:16:03946TEST_F(GCMAccountMapperTest, DispatchMessageSentToGaiaID) {
947 Initialize(GCMAccountMapper::AccountMappings());
948 gcm_driver().AddAppHandler(kGCMAccountMapperAppId, mapper());
mvanouwerkerkf8633deb2015-07-13 11:04:06949 IncomingMessage message;
fgorski47869f02015-02-27 23:16:03950 message.data[kEmbeddedAppIdKey] = kTestAppId;
951 message.data[kTestDataKey] = kTestDataValue;
952 message.collapse_key = kTestCollapseKey;
953 message.sender_id = kTestSenderId;
954 mapper()->OnMessage(kGCMAccountMapperAppId, message);
955
956 EXPECT_EQ(kTestAppId, last_received_app_id());
957 EXPECT_EQ(1UL, last_received_message().data.size());
mvanouwerkerkf8633deb2015-07-13 11:04:06958 MessageData::const_iterator it =
fgorski47869f02015-02-27 23:16:03959 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);
964}
965
fgorskic1047312014-09-04 16:48:54966} // namespace gcm