Delete chrome.mediaGalleriesPrivate because the functionality unique to it has since...
[chromium-blink-merge.git] / google_apis / gcm / engine / gcm_store_impl_unittest.cc
blobe5690fdc39b16fff6161a8b64b58552d175f7506
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 "google_apis/gcm/engine/gcm_store_impl.h"
7 #include <string>
8 #include <vector>
10 #include "base/bind.h"
11 #include "base/command_line.h"
12 #include "base/files/file_path.h"
13 #include "base/files/scoped_temp_dir.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/run_loop.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "google_apis/gcm/base/fake_encryptor.h"
19 #include "google_apis/gcm/base/mcs_message.h"
20 #include "google_apis/gcm/base/mcs_util.h"
21 #include "google_apis/gcm/protocol/mcs.pb.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 namespace gcm {
26 namespace {
28 // Number of persistent ids to use in tests.
29 const int kNumPersistentIds = 10;
31 // Number of per-app messages in tests.
32 const int kNumMessagesPerApp = 20;
34 // App name for testing.
35 const char kAppName[] = "my_app";
37 // Category name for testing.
38 const char kCategoryName[] = "my_category";
40 const uint64 kDeviceId = 22;
41 const uint64 kDeviceToken = 55;
43 class GCMStoreImplTest : public testing::Test {
44 public:
45 GCMStoreImplTest();
46 ~GCMStoreImplTest() override;
48 scoped_ptr<GCMStore> BuildGCMStore();
50 std::string GetNextPersistentId();
52 void PumpLoop();
54 void LoadCallback(scoped_ptr<GCMStore::LoadResult>* result_dst,
55 scoped_ptr<GCMStore::LoadResult> result);
56 void UpdateCallback(bool success);
58 protected:
59 base::MessageLoop message_loop_;
60 base::ScopedTempDir temp_directory_;
61 bool expected_success_;
62 uint64 next_persistent_id_;
63 scoped_ptr<base::RunLoop> run_loop_;
66 GCMStoreImplTest::GCMStoreImplTest()
67 : expected_success_(true),
68 next_persistent_id_(base::Time::Now().ToInternalValue()) {
69 EXPECT_TRUE(temp_directory_.CreateUniqueTempDir());
70 run_loop_.reset(new base::RunLoop());
73 GCMStoreImplTest::~GCMStoreImplTest() {}
75 scoped_ptr<GCMStore> GCMStoreImplTest::BuildGCMStore() {
76 return scoped_ptr<GCMStore>(new GCMStoreImpl(
77 temp_directory_.path(),
78 message_loop_.message_loop_proxy(),
79 make_scoped_ptr<Encryptor>(new FakeEncryptor)));
82 std::string GCMStoreImplTest::GetNextPersistentId() {
83 return base::Uint64ToString(next_persistent_id_++);
86 void GCMStoreImplTest::PumpLoop() { message_loop_.RunUntilIdle(); }
88 void GCMStoreImplTest::LoadCallback(
89 scoped_ptr<GCMStore::LoadResult>* result_dst,
90 scoped_ptr<GCMStore::LoadResult> result) {
91 ASSERT_TRUE(result->success);
92 *result_dst = result.Pass();
93 run_loop_->Quit();
94 run_loop_.reset(new base::RunLoop());
97 void GCMStoreImplTest::UpdateCallback(bool success) {
98 ASSERT_EQ(expected_success_, success);
101 // Verify creating a new database and loading it.
102 TEST_F(GCMStoreImplTest, LoadNew) {
103 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
104 scoped_ptr<GCMStore::LoadResult> load_result;
105 gcm_store->Load(base::Bind(
106 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
107 PumpLoop();
109 EXPECT_EQ(0U, load_result->device_android_id);
110 EXPECT_EQ(0U, load_result->device_security_token);
111 EXPECT_TRUE(load_result->incoming_messages.empty());
112 EXPECT_TRUE(load_result->outgoing_messages.empty());
113 EXPECT_TRUE(load_result->gservices_settings.empty());
114 EXPECT_EQ(base::Time::FromInternalValue(0LL), load_result->last_checkin_time);
117 TEST_F(GCMStoreImplTest, DeviceCredentials) {
118 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
119 scoped_ptr<GCMStore::LoadResult> load_result;
120 gcm_store->Load(base::Bind(
121 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
122 PumpLoop();
124 gcm_store->SetDeviceCredentials(
125 kDeviceId,
126 kDeviceToken,
127 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
128 PumpLoop();
130 gcm_store = BuildGCMStore().Pass();
131 gcm_store->Load(base::Bind(
132 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
133 PumpLoop();
135 ASSERT_EQ(kDeviceId, load_result->device_android_id);
136 ASSERT_EQ(kDeviceToken, load_result->device_security_token);
139 TEST_F(GCMStoreImplTest, LastCheckinInfo) {
140 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
141 scoped_ptr<GCMStore::LoadResult> load_result;
142 gcm_store->Load(base::Bind(
143 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
144 PumpLoop();
146 base::Time last_checkin_time = base::Time::Now();
147 std::set<std::string> accounts;
148 accounts.insert("test_user1@gmail.com");
149 accounts.insert("test_user2@gmail.com");
151 gcm_store->SetLastCheckinInfo(
152 last_checkin_time,
153 accounts,
154 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
155 PumpLoop();
157 gcm_store = BuildGCMStore().Pass();
158 gcm_store->Load(base::Bind(
159 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
160 PumpLoop();
161 ASSERT_EQ(last_checkin_time, load_result->last_checkin_time);
162 ASSERT_EQ(accounts, load_result->last_checkin_accounts);
165 TEST_F(GCMStoreImplTest, GServicesSettings_ProtocolV2) {
166 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
167 scoped_ptr<GCMStore::LoadResult> load_result;
168 gcm_store->Load(base::Bind(
169 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
170 PumpLoop();
172 std::map<std::string, std::string> settings;
173 settings["checkin_interval"] = "12345";
174 settings["mcs_port"] = "438";
175 settings["checkin_url"] = "http://checkin.google.com";
176 std::string digest = "digest1";
178 gcm_store->SetGServicesSettings(
179 settings,
180 digest,
181 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
182 PumpLoop();
184 gcm_store = BuildGCMStore().Pass();
185 gcm_store->Load(base::Bind(
186 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
187 PumpLoop();
189 ASSERT_EQ(settings, load_result->gservices_settings);
190 ASSERT_EQ(digest, load_result->gservices_digest);
192 // Remove some, and add some.
193 settings.clear();
194 settings["checkin_interval"] = "54321";
195 settings["registration_url"] = "http://registration.google.com";
196 digest = "digest2";
198 gcm_store->SetGServicesSettings(
199 settings,
200 digest,
201 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
202 PumpLoop();
204 gcm_store = BuildGCMStore().Pass();
205 gcm_store->Load(base::Bind(
206 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
207 PumpLoop();
209 ASSERT_EQ(settings, load_result->gservices_settings);
210 ASSERT_EQ(digest, load_result->gservices_digest);
213 TEST_F(GCMStoreImplTest, Registrations) {
214 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
215 scoped_ptr<GCMStore::LoadResult> load_result;
216 gcm_store->Load(base::Bind(
217 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
218 PumpLoop();
220 // Add one registration with one sender.
221 linked_ptr<RegistrationInfo> registration1(new RegistrationInfo);
222 registration1->sender_ids.push_back("sender1");
223 registration1->registration_id = "registration1";
224 gcm_store->AddRegistration(
225 "app1",
226 registration1,
227 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
228 PumpLoop();
230 // Add one registration with multiple senders.
231 linked_ptr<RegistrationInfo> registration2(new RegistrationInfo);
232 registration2->sender_ids.push_back("sender2_1");
233 registration2->sender_ids.push_back("sender2_2");
234 registration2->registration_id = "registration2";
235 gcm_store->AddRegistration(
236 "app2",
237 registration2,
238 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
239 PumpLoop();
241 gcm_store = BuildGCMStore().Pass();
242 gcm_store->Load(base::Bind(
243 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
244 PumpLoop();
246 ASSERT_EQ(2u, load_result->registrations.size());
247 ASSERT_TRUE(load_result->registrations.find("app1") !=
248 load_result->registrations.end());
249 EXPECT_EQ(registration1->registration_id,
250 load_result->registrations["app1"]->registration_id);
251 ASSERT_EQ(1u, load_result->registrations["app1"]->sender_ids.size());
252 EXPECT_EQ(registration1->sender_ids[0],
253 load_result->registrations["app1"]->sender_ids[0]);
254 ASSERT_TRUE(load_result->registrations.find("app2") !=
255 load_result->registrations.end());
256 EXPECT_EQ(registration2->registration_id,
257 load_result->registrations["app2"]->registration_id);
258 ASSERT_EQ(2u, load_result->registrations["app2"]->sender_ids.size());
259 EXPECT_EQ(registration2->sender_ids[0],
260 load_result->registrations["app2"]->sender_ids[0]);
261 EXPECT_EQ(registration2->sender_ids[1],
262 load_result->registrations["app2"]->sender_ids[1]);
264 gcm_store->RemoveRegistration(
265 "app2",
266 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
267 PumpLoop();
269 gcm_store = BuildGCMStore().Pass();
270 gcm_store->Load(base::Bind(
271 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
272 PumpLoop();
274 ASSERT_EQ(1u, load_result->registrations.size());
275 ASSERT_TRUE(load_result->registrations.find("app1") !=
276 load_result->registrations.end());
277 EXPECT_EQ(registration1->registration_id,
278 load_result->registrations["app1"]->registration_id);
279 ASSERT_EQ(1u, load_result->registrations["app1"]->sender_ids.size());
280 EXPECT_EQ(registration1->sender_ids[0],
281 load_result->registrations["app1"]->sender_ids[0]);
284 // Verify saving some incoming messages, reopening the directory, and then
285 // removing those incoming messages.
286 TEST_F(GCMStoreImplTest, IncomingMessages) {
287 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
288 scoped_ptr<GCMStore::LoadResult> load_result;
289 gcm_store->Load(base::Bind(
290 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
291 PumpLoop();
293 std::vector<std::string> persistent_ids;
294 for (int i = 0; i < kNumPersistentIds; ++i) {
295 persistent_ids.push_back(GetNextPersistentId());
296 gcm_store->AddIncomingMessage(
297 persistent_ids.back(),
298 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
299 PumpLoop();
302 gcm_store = BuildGCMStore().Pass();
303 gcm_store->Load(base::Bind(
304 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
305 PumpLoop();
307 ASSERT_EQ(persistent_ids, load_result->incoming_messages);
308 ASSERT_TRUE(load_result->outgoing_messages.empty());
310 gcm_store->RemoveIncomingMessages(
311 persistent_ids,
312 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
313 PumpLoop();
315 gcm_store = BuildGCMStore().Pass();
316 load_result->incoming_messages.clear();
317 gcm_store->Load(base::Bind(
318 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
319 PumpLoop();
321 ASSERT_TRUE(load_result->incoming_messages.empty());
322 ASSERT_TRUE(load_result->outgoing_messages.empty());
325 // Verify saving some outgoing messages, reopening the directory, and then
326 // removing those outgoing messages.
327 TEST_F(GCMStoreImplTest, OutgoingMessages) {
328 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
329 scoped_ptr<GCMStore::LoadResult> load_result;
330 gcm_store->Load(base::Bind(
331 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
332 PumpLoop();
334 std::vector<std::string> persistent_ids;
335 const int kNumPersistentIds = 10;
336 for (int i = 0; i < kNumPersistentIds; ++i) {
337 persistent_ids.push_back(GetNextPersistentId());
338 mcs_proto::DataMessageStanza message;
339 message.set_from(kAppName + persistent_ids.back());
340 message.set_category(kCategoryName + persistent_ids.back());
341 gcm_store->AddOutgoingMessage(
342 persistent_ids.back(),
343 MCSMessage(message),
344 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
345 PumpLoop();
348 gcm_store = BuildGCMStore().Pass();
349 gcm_store->Load(base::Bind(
350 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
351 PumpLoop();
353 ASSERT_TRUE(load_result->incoming_messages.empty());
354 ASSERT_EQ(load_result->outgoing_messages.size(), persistent_ids.size());
355 for (int i = 0; i < kNumPersistentIds; ++i) {
356 std::string id = persistent_ids[i];
357 ASSERT_TRUE(load_result->outgoing_messages[id].get());
358 const mcs_proto::DataMessageStanza* message =
359 reinterpret_cast<mcs_proto::DataMessageStanza*>(
360 load_result->outgoing_messages[id].get());
361 ASSERT_EQ(message->from(), kAppName + id);
362 ASSERT_EQ(message->category(), kCategoryName + id);
365 gcm_store->RemoveOutgoingMessages(
366 persistent_ids,
367 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
368 PumpLoop();
370 gcm_store = BuildGCMStore().Pass();
371 load_result->outgoing_messages.clear();
372 gcm_store->Load(base::Bind(
373 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
374 PumpLoop();
376 ASSERT_TRUE(load_result->incoming_messages.empty());
377 ASSERT_TRUE(load_result->outgoing_messages.empty());
380 // Verify incoming and outgoing messages don't conflict.
381 TEST_F(GCMStoreImplTest, IncomingAndOutgoingMessages) {
382 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
383 scoped_ptr<GCMStore::LoadResult> load_result;
384 gcm_store->Load(base::Bind(
385 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
386 PumpLoop();
388 std::vector<std::string> persistent_ids;
389 const int kNumPersistentIds = 10;
390 for (int i = 0; i < kNumPersistentIds; ++i) {
391 persistent_ids.push_back(GetNextPersistentId());
392 gcm_store->AddIncomingMessage(
393 persistent_ids.back(),
394 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
395 PumpLoop();
397 mcs_proto::DataMessageStanza message;
398 message.set_from(kAppName + persistent_ids.back());
399 message.set_category(kCategoryName + persistent_ids.back());
400 gcm_store->AddOutgoingMessage(
401 persistent_ids.back(),
402 MCSMessage(message),
403 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
404 PumpLoop();
407 gcm_store = BuildGCMStore().Pass();
408 gcm_store->Load(base::Bind(
409 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
410 PumpLoop();
412 ASSERT_EQ(persistent_ids, load_result->incoming_messages);
413 ASSERT_EQ(load_result->outgoing_messages.size(), persistent_ids.size());
414 for (int i = 0; i < kNumPersistentIds; ++i) {
415 std::string id = persistent_ids[i];
416 ASSERT_TRUE(load_result->outgoing_messages[id].get());
417 const mcs_proto::DataMessageStanza* message =
418 reinterpret_cast<mcs_proto::DataMessageStanza*>(
419 load_result->outgoing_messages[id].get());
420 ASSERT_EQ(message->from(), kAppName + id);
421 ASSERT_EQ(message->category(), kCategoryName + id);
424 gcm_store->RemoveIncomingMessages(
425 persistent_ids,
426 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
427 PumpLoop();
428 gcm_store->RemoveOutgoingMessages(
429 persistent_ids,
430 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
431 PumpLoop();
433 gcm_store = BuildGCMStore().Pass();
434 load_result->incoming_messages.clear();
435 load_result->outgoing_messages.clear();
436 gcm_store->Load(base::Bind(
437 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
438 PumpLoop();
440 ASSERT_TRUE(load_result->incoming_messages.empty());
441 ASSERT_TRUE(load_result->outgoing_messages.empty());
444 // Test that per-app message limits are enforced, persisted across restarts,
445 // and updated as messages are removed.
446 TEST_F(GCMStoreImplTest, PerAppMessageLimits) {
447 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
448 scoped_ptr<GCMStore::LoadResult> load_result;
449 gcm_store->Load(base::Bind(&GCMStoreImplTest::LoadCallback,
450 base::Unretained(this),
451 &load_result));
453 // Add the initial (below app limit) messages.
454 for (int i = 0; i < kNumMessagesPerApp; ++i) {
455 mcs_proto::DataMessageStanza message;
456 message.set_from(kAppName);
457 message.set_category(kCategoryName);
458 EXPECT_TRUE(gcm_store->AddOutgoingMessage(
459 base::IntToString(i),
460 MCSMessage(message),
461 base::Bind(&GCMStoreImplTest::UpdateCallback,
462 base::Unretained(this))));
463 PumpLoop();
466 // Attempting to add some more should fail.
467 for (int i = 0; i < kNumMessagesPerApp; ++i) {
468 mcs_proto::DataMessageStanza message;
469 message.set_from(kAppName);
470 message.set_category(kCategoryName);
471 EXPECT_FALSE(gcm_store->AddOutgoingMessage(
472 base::IntToString(i + kNumMessagesPerApp),
473 MCSMessage(message),
474 base::Bind(&GCMStoreImplTest::UpdateCallback,
475 base::Unretained(this))));
476 PumpLoop();
479 // Tear down and restore the database.
480 gcm_store = BuildGCMStore().Pass();
481 gcm_store->Load(base::Bind(&GCMStoreImplTest::LoadCallback,
482 base::Unretained(this),
483 &load_result));
484 PumpLoop();
486 // Adding more messages should still fail.
487 for (int i = 0; i < kNumMessagesPerApp; ++i) {
488 mcs_proto::DataMessageStanza message;
489 message.set_from(kAppName);
490 message.set_category(kCategoryName);
491 EXPECT_FALSE(gcm_store->AddOutgoingMessage(
492 base::IntToString(i + kNumMessagesPerApp),
493 MCSMessage(message),
494 base::Bind(&GCMStoreImplTest::UpdateCallback,
495 base::Unretained(this))));
496 PumpLoop();
499 // Remove the existing messages.
500 for (int i = 0; i < kNumMessagesPerApp; ++i) {
501 gcm_store->RemoveOutgoingMessage(
502 base::IntToString(i),
503 base::Bind(&GCMStoreImplTest::UpdateCallback,
504 base::Unretained(this)));
505 PumpLoop();
508 // Successfully add new messages.
509 for (int i = 0; i < kNumMessagesPerApp; ++i) {
510 mcs_proto::DataMessageStanza message;
511 message.set_from(kAppName);
512 message.set_category(kCategoryName);
513 EXPECT_TRUE(gcm_store->AddOutgoingMessage(
514 base::IntToString(i + kNumMessagesPerApp),
515 MCSMessage(message),
516 base::Bind(&GCMStoreImplTest::UpdateCallback,
517 base::Unretained(this))));
518 PumpLoop();
522 TEST_F(GCMStoreImplTest, AccountMapping) {
523 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
524 scoped_ptr<GCMStore::LoadResult> load_result;
525 gcm_store->Load(base::Bind(
526 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
528 // Add account mappings.
529 AccountMapping account_mapping1;
530 account_mapping1.account_id = "account_id_1";
531 account_mapping1.email = "account_id_1@gmail.com";
532 account_mapping1.access_token = "account_token1";
533 account_mapping1.status = AccountMapping::ADDING;
534 account_mapping1.status_change_timestamp = base::Time();
535 account_mapping1.last_message_id = "message_1";
537 AccountMapping account_mapping2;
538 account_mapping2.account_id = "account_id_2";
539 account_mapping2.email = "account_id_2@gmail.com";
540 account_mapping2.access_token = "account_token1";
541 account_mapping2.status = AccountMapping::REMOVING;
542 account_mapping2.status_change_timestamp =
543 base::Time::FromInternalValue(1305734521259935LL);
544 account_mapping2.last_message_id = "message_2";
546 gcm_store->AddAccountMapping(
547 account_mapping1,
548 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
549 PumpLoop();
550 gcm_store->AddAccountMapping(
551 account_mapping2,
552 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
553 PumpLoop();
555 gcm_store = BuildGCMStore().Pass();
556 gcm_store->Load(base::Bind(
557 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
558 PumpLoop();
560 EXPECT_EQ(2UL, load_result->account_mappings.size());
561 GCMStore::AccountMappings::iterator iter =
562 load_result->account_mappings.begin();
563 EXPECT_EQ(account_mapping1.account_id, iter->account_id);
564 EXPECT_EQ(account_mapping1.email, iter->email);
565 EXPECT_TRUE(iter->access_token.empty());
566 EXPECT_EQ(AccountMapping::ADDING, iter->status);
567 EXPECT_EQ(account_mapping1.status_change_timestamp,
568 iter->status_change_timestamp);
569 EXPECT_EQ(account_mapping1.last_message_id, iter->last_message_id);
570 ++iter;
571 EXPECT_EQ(account_mapping2.account_id, iter->account_id);
572 EXPECT_EQ(account_mapping2.email, iter->email);
573 EXPECT_TRUE(iter->access_token.empty());
574 EXPECT_EQ(AccountMapping::REMOVING, iter->status);
575 EXPECT_EQ(account_mapping2.status_change_timestamp,
576 iter->status_change_timestamp);
577 EXPECT_EQ(account_mapping2.last_message_id, iter->last_message_id);
579 gcm_store->RemoveAccountMapping(
580 account_mapping1.account_id,
581 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
582 PumpLoop();
584 gcm_store = BuildGCMStore().Pass();
585 gcm_store->Load(base::Bind(
586 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
587 PumpLoop();
589 EXPECT_EQ(1UL, load_result->account_mappings.size());
590 iter = load_result->account_mappings.begin();
591 EXPECT_EQ(account_mapping2.account_id, iter->account_id);
592 EXPECT_EQ(account_mapping2.email, iter->email);
593 EXPECT_TRUE(iter->access_token.empty());
594 EXPECT_EQ(AccountMapping::REMOVING, iter->status);
595 EXPECT_EQ(account_mapping2.status_change_timestamp,
596 iter->status_change_timestamp);
597 EXPECT_EQ(account_mapping2.last_message_id, iter->last_message_id);
600 // When the database is destroyed, all database updates should fail. At the
601 // same time, they per-app message counts should not go up, as failures should
602 // result in decrementing the counts.
603 TEST_F(GCMStoreImplTest, AddMessageAfterDestroy) {
604 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
605 scoped_ptr<GCMStore::LoadResult> load_result;
606 gcm_store->Load(base::Bind(&GCMStoreImplTest::LoadCallback,
607 base::Unretained(this),
608 &load_result));
609 PumpLoop();
610 gcm_store->Destroy(base::Bind(&GCMStoreImplTest::UpdateCallback,
611 base::Unretained(this)));
612 PumpLoop();
614 expected_success_ = false;
615 for (int i = 0; i < kNumMessagesPerApp * 2; ++i) {
616 mcs_proto::DataMessageStanza message;
617 message.set_from(kAppName);
618 message.set_category(kCategoryName);
619 // Because all adds are failing, none should hit the per-app message limits.
620 EXPECT_TRUE(gcm_store->AddOutgoingMessage(
621 base::IntToString(i),
622 MCSMessage(message),
623 base::Bind(&GCMStoreImplTest::UpdateCallback,
624 base::Unretained(this))));
625 PumpLoop();
629 TEST_F(GCMStoreImplTest, ReloadAfterClose) {
630 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
631 scoped_ptr<GCMStore::LoadResult> load_result;
632 gcm_store->Load(base::Bind(&GCMStoreImplTest::LoadCallback,
633 base::Unretained(this),
634 &load_result));
635 PumpLoop();
637 gcm_store->Close();
638 PumpLoop();
640 gcm_store->Load(base::Bind(&GCMStoreImplTest::LoadCallback,
641 base::Unretained(this),
642 &load_result));
643 PumpLoop();
646 TEST_F(GCMStoreImplTest, LastTokenFetchTime) {
647 scoped_ptr<GCMStore> gcm_store(BuildGCMStore());
648 scoped_ptr<GCMStore::LoadResult> load_result;
649 gcm_store->Load(base::Bind(
650 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
651 PumpLoop();
652 EXPECT_EQ(base::Time(), load_result->last_token_fetch_time);
654 base::Time last_token_fetch_time = base::Time::Now();
655 gcm_store->SetLastTokenFetchTime(
656 last_token_fetch_time,
657 base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
658 PumpLoop();
660 gcm_store = BuildGCMStore().Pass();
661 gcm_store->Load(base::Bind(
662 &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
663 PumpLoop();
664 EXPECT_EQ(last_token_fetch_time, load_result->last_token_fetch_time);
667 } // namespace
669 } // namespace gcm