1 // Copyright (c) 2013 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 <algorithm> 6 7 #include "base/bind.h" 8 #include "base/command_line.h" 9 #include "base/prefs/pref_service.h" 10 #include "base/run_loop.h" 11 #include "chrome/browser/extensions/state_store.h" 12 #include "chrome/browser/extensions/test_extension_service.h" 13 #include "chrome/browser/extensions/test_extension_system.h" 14 #include "chrome/browser/services/gcm/gcm_client_mock.h" 15 #include "chrome/browser/services/gcm/gcm_event_router.h" 16 #include "chrome/browser/services/gcm/gcm_profile_service.h" 17 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" 18 #include "chrome/browser/signin/fake_signin_manager.h" 19 #include "chrome/browser/signin/signin_manager_factory.h" 20 #include "chrome/browser/ui/browser.h" 21 #include "chrome/common/pref_names.h" 22 #include "chrome/test/base/testing_profile.h" 23 #include "components/webdata/encryptor/encryptor.h" 24 #include "content/public/test/test_browser_thread_bundle.h" 25 #include "extensions/common/extension.h" 26 #include "extensions/common/manifest_constants.h" 27 #include "testing/gtest/include/gtest/gtest.h" 28 29 #if defined(OS_CHROMEOS) 30 #include "chrome/browser/chromeos/login/user_manager.h" 31 #include "chrome/browser/chromeos/settings/cros_settings.h" 32 #include "chrome/browser/chromeos/settings/device_settings_service.h" 33 #endif 34 35 using namespace extensions; 36 37 namespace gcm { 38 39 const char kTestExtensionName[] = "FooBar"; 40 const char kTestingUsername[] = "user (at) example.com"; 41 const char kTestingAppId[] = "test1"; 42 const char kTestingSha1Cert[] = "testing_cert1"; 43 const char kUserId[] = "user2"; 44 45 class GCMProfileServiceTest; 46 47 class GCMEventRouterMock : public GCMEventRouter { 48 public: 49 enum Event { 50 NO_EVENT, 51 MESSAGE_EVENT, 52 MESSAGES_DELETED_EVENT, 53 SEND_ERROR_EVENT 54 }; 55 56 explicit GCMEventRouterMock(GCMProfileServiceTest* test); 57 virtual ~GCMEventRouterMock(); 58 59 virtual void OnMessage(const std::string& app_id, 60 const GCMClient::IncomingMessage& message) OVERRIDE; 61 virtual void OnMessagesDeleted(const std::string& app_id) OVERRIDE; 62 virtual void OnSendError(const std::string& app_id, 63 const std::string& message_id, 64 GCMClient::Result result) OVERRIDE; 65 66 Event received_event() const { return received_event_; } 67 const std::string& app_id() const { return app_id_; } 68 const GCMClient::IncomingMessage incoming_message() const { 69 return incoming_message_; 70 } 71 const std::string& send_message_id() const { return send_error_message_id_; } 72 GCMClient::Result send_result() const { return send_error_result_; } 73 74 private: 75 GCMProfileServiceTest* test_; 76 Event received_event_; 77 std::string app_id_; 78 GCMClient::IncomingMessage incoming_message_; 79 std::string send_error_message_id_; 80 GCMClient::Result send_error_result_; 81 }; 82 83 class GCMProfileServiceTest : public testing::Test, 84 public GCMProfileService::TestingDelegate { 85 public: 86 static BrowserContextKeyedService* BuildGCMProfileService( 87 content::BrowserContext* profile) { 88 return new GCMProfileService( 89 static_cast<Profile*>(profile), gps_testing_delegate_); 90 } 91 92 GCMProfileServiceTest() : extension_service_(NULL) { 93 } 94 95 virtual ~GCMProfileServiceTest() { 96 } 97 98 // Overridden from test::Test: 99 virtual void SetUp() OVERRIDE { 100 profile_.reset(new TestingProfile); 101 102 // Make BrowserThread work in unittest. 103 thread_bundle_.reset(new content::TestBrowserThreadBundle( 104 content::TestBrowserThreadBundle::REAL_IO_THREAD)); 105 106 // This is needed to create extension service under CrOS. 107 #if defined(OS_CHROMEOS) 108 test_user_manager_.reset(new chromeos::ScopedTestUserManager()); 109 #endif 110 111 // Create extension service in order to uninstall the extension. 112 extensions::TestExtensionSystem* extension_system( 113 static_cast<extensions::TestExtensionSystem*>( 114 extensions::ExtensionSystem::Get(profile()))); 115 extension_system->CreateExtensionService( 116 CommandLine::ForCurrentProcess(), base::FilePath(), false); 117 extension_service_ = extension_system->Get(profile())->extension_service(); 118 119 // Mock a signed-in user. 120 SigninManagerBase* signin_manager = 121 SigninManagerFactory::GetForProfile(profile()); 122 signin_manager->SetAuthenticatedUsername(kTestingUsername); 123 124 // Encryptor ends up needing access to the keychain on OS X. So use the mock 125 // keychain to prevent prompts. 126 #if defined(OS_MACOSX) 127 Encryptor::UseMockKeychain(true); 128 #endif 129 130 // Mock a GCMClient. 131 gcm_client_mock_.reset(new GCMClientMock()); 132 GCMClient::SetForTesting(gcm_client_mock_.get()); 133 134 // Mock a GCMEventRouter. 135 gcm_event_router_mock_.reset(new GCMEventRouterMock(this)); 136 137 // Set |gps_testing_delegate_| for it to be picked up by 138 // BuildGCMProfileService and pass it to GCMProfileService. 139 gps_testing_delegate_ = this; 140 141 // This will create GCMProfileService that causes check-in to be initiated. 142 GCMProfileService::enable_gcm_for_testing_ = true; 143 GCMProfileServiceFactory::GetInstance()->SetTestingFactoryAndUse( 144 profile(), &GCMProfileServiceTest::BuildGCMProfileService); 145 146 // Wait till the asynchronous check-in is done. 147 WaitForCompleted(); 148 } 149 150 virtual void TearDown() OVERRIDE { 151 GCMClient::SetForTesting(NULL); 152 153 #if defined(OS_CHROMEOS) 154 test_user_manager_.reset(); 155 #endif 156 157 extension_service_ = NULL; 158 profile_.reset(); 159 base::RunLoop().RunUntilIdle(); 160 } 161 162 // Overridden from GCMProfileService::TestingDelegate: 163 virtual GCMEventRouter* GetEventRouter() const OVERRIDE { 164 return gcm_event_router_mock_.get(); 165 } 166 167 virtual void CheckInFinished(const GCMClient::CheckInInfo& checkin_info, 168 GCMClient::Result result) OVERRIDE { 169 checkin_info_ = checkin_info; 170 SignalCompleted(); 171 } 172 173 virtual void LoadingFromPersistentStoreFinished() OVERRIDE { 174 SignalCompleted(); 175 } 176 177 // Waits until the asynchrnous operation finishes. 178 void WaitForCompleted() { 179 run_loop_.reset(new base::RunLoop); 180 run_loop_->Run(); 181 } 182 183 // Signals that the asynchrnous operation finishes. 184 void SignalCompleted() { 185 if (run_loop_ && run_loop_->running()) 186 run_loop_->Quit(); 187 } 188 189 // Returns a barebones test extension. 190 scoped_refptr<Extension> CreateExtension() { 191 #if defined(OS_WIN) 192 base::FilePath path(FILE_PATH_LITERAL("c:\\foo")); 193 #elif defined(OS_POSIX) 194 base::FilePath path(FILE_PATH_LITERAL("/foo")); 195 #endif 196 197 DictionaryValue manifest; 198 manifest.SetString(manifest_keys::kVersion, "1.0.0.0"); 199 manifest.SetString(manifest_keys::kName, kTestExtensionName); 200 ListValue* permission_list = new ListValue; 201 permission_list->Append(Value::CreateStringValue("gcm")); 202 manifest.Set(manifest_keys::kPermissions, permission_list); 203 204 std::string error; 205 scoped_refptr<Extension> extension = 206 Extension::Create(path.AppendASCII(kTestExtensionName), 207 Manifest::INVALID_LOCATION, 208 manifest, 209 Extension::NO_FLAGS, 210 &error); 211 EXPECT_TRUE(extension.get()) << error; 212 213 extension_service_->AddExtension(extension.get()); 214 return extension; 215 } 216 217 Profile* profile() const { return profile_.get(); } 218 219 GCMProfileService* GetGCMProfileService() const { 220 return GCMProfileServiceFactory::GetForProfile(profile()); 221 } 222 223 protected: 224 scoped_ptr<TestingProfile> profile_; 225 scoped_ptr<content::TestBrowserThreadBundle> thread_bundle_; 226 ExtensionService* extension_service_; // Not owned. 227 scoped_ptr<GCMClientMock> gcm_client_mock_; 228 scoped_ptr<base::RunLoop> run_loop_; 229 scoped_ptr<GCMEventRouterMock> gcm_event_router_mock_; 230 GCMClient::CheckInInfo checkin_info_; 231 232 #if defined(OS_CHROMEOS) 233 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_; 234 chromeos::ScopedTestCrosSettings test_cros_settings_; 235 scoped_ptr<chromeos::ScopedTestUserManager> test_user_manager_; 236 #endif 237 238 private: 239 static GCMProfileService::TestingDelegate* gps_testing_delegate_; 240 241 DISALLOW_COPY_AND_ASSIGN(GCMProfileServiceTest); 242 }; 243 244 GCMProfileService::TestingDelegate* 245 GCMProfileServiceTest::gps_testing_delegate_ = NULL; 246 247 GCMEventRouterMock::GCMEventRouterMock(GCMProfileServiceTest* test) 248 : test_(test), 249 received_event_(NO_EVENT), 250 send_error_result_(GCMClient::SUCCESS) { 251 } 252 253 GCMEventRouterMock::~GCMEventRouterMock() { 254 } 255 256 void GCMEventRouterMock::OnMessage(const std::string& app_id, 257 const GCMClient::IncomingMessage& message) { 258 received_event_ = MESSAGE_EVENT; 259 app_id_ = app_id; 260 incoming_message_ = message; 261 test_->SignalCompleted(); 262 } 263 264 void GCMEventRouterMock::OnMessagesDeleted(const std::string& app_id) { 265 received_event_ = MESSAGES_DELETED_EVENT; 266 app_id_ = app_id; 267 test_->SignalCompleted(); 268 } 269 270 void GCMEventRouterMock::OnSendError(const std::string& app_id, 271 const std::string& message_id, 272 GCMClient::Result result) { 273 received_event_ = SEND_ERROR_EVENT; 274 app_id_ = app_id; 275 send_error_message_id_ = message_id; 276 send_error_result_ = result; 277 test_->SignalCompleted(); 278 } 279 280 TEST_F(GCMProfileServiceTest, CheckIn) { 281 EXPECT_TRUE(checkin_info_.IsValid()); 282 283 GCMClient::CheckInInfo expected_checkin_info = 284 gcm_client_mock_->GetCheckInInfoFromUsername(kTestingUsername); 285 EXPECT_EQ(expected_checkin_info.android_id, checkin_info_.android_id); 286 EXPECT_EQ(expected_checkin_info.secret, checkin_info_.secret); 287 } 288 289 TEST_F(GCMProfileServiceTest, CheckInFromPrefsStore) { 290 // The first check-in should be successful. 291 EXPECT_TRUE(checkin_info_.IsValid()); 292 GCMClient::CheckInInfo saved_checkin_info = checkin_info_; 293 checkin_info_.Reset(); 294 295 gcm_client_mock_->set_checkin_failure_enabled(true); 296 297 // Recreate GCMProfileService to test reading the check-in info from the 298 // prefs store. 299 GCMProfileServiceFactory::GetInstance()->SetTestingFactoryAndUse( 300 profile(), &GCMProfileServiceTest::BuildGCMProfileService); 301 302 EXPECT_EQ(saved_checkin_info.android_id, checkin_info_.android_id); 303 EXPECT_EQ(saved_checkin_info.secret, checkin_info_.secret); 304 } 305 306 TEST_F(GCMProfileServiceTest, CheckOut) { 307 EXPECT_TRUE(profile()->GetPrefs()->HasPrefPath(prefs::kGCMUserAccountID)); 308 EXPECT_TRUE(profile()->GetPrefs()->HasPrefPath(prefs::kGCMUserToken)); 309 310 GetGCMProfileService()->RemoveUser(); 311 312 EXPECT_FALSE(profile()->GetPrefs()->HasPrefPath(prefs::kGCMUserAccountID)); 313 EXPECT_FALSE(profile()->GetPrefs()->HasPrefPath(prefs::kGCMUserToken)); 314 } 315 316 class GCMProfileServiceRegisterTest : public GCMProfileServiceTest { 317 public: 318 GCMProfileServiceRegisterTest() 319 : result_(GCMClient::SUCCESS), 320 has_persisted_registration_info_(false) { 321 } 322 323 virtual ~GCMProfileServiceRegisterTest() { 324 } 325 326 void Register(const std::string& app_id, 327 const std::vector<std::string>& sender_ids) { 328 GetGCMProfileService()->Register( 329 app_id, 330 sender_ids, 331 kTestingSha1Cert, 332 base::Bind(&GCMProfileServiceRegisterTest::RegisterCompleted, 333 base::Unretained(this))); 334 } 335 336 void RegisterCompleted(const std::string& registration_id, 337 GCMClient::Result result) { 338 registration_id_ = registration_id; 339 result_ = result; 340 SignalCompleted(); 341 } 342 343 bool HasPersistedRegistrationInfo(const std::string& app_id) { 344 StateStore* storage = ExtensionSystem::Get(profile())->state_store(); 345 if (!storage) 346 return false; 347 has_persisted_registration_info_ = false; 348 storage->GetExtensionValue( 349 app_id, 350 GCMProfileService::GetPersistentRegisterKeyForTesting(), 351 base::Bind( 352 &GCMProfileServiceRegisterTest::ReadRegistrationInfoFinished, 353 base::Unretained(this))); 354 WaitForCompleted(); 355 return has_persisted_registration_info_; 356 } 357 358 void ReadRegistrationInfoFinished(scoped_ptr<base::Value> value) { 359 has_persisted_registration_info_ = value.get() != NULL; 360 SignalCompleted(); 361 } 362 363 protected: 364 std::string registration_id_; 365 GCMClient::Result result_; 366 bool has_persisted_registration_info_; 367 368 private: 369 DISALLOW_COPY_AND_ASSIGN(GCMProfileServiceRegisterTest); 370 }; 371 372 TEST_F(GCMProfileServiceRegisterTest, Register) { 373 std::vector<std::string> sender_ids; 374 sender_ids.push_back("sender1"); 375 Register(kTestingAppId, sender_ids); 376 std::string expected_registration_id = 377 gcm_client_mock_->GetRegistrationIdFromSenderIds(sender_ids); 378 379 WaitForCompleted(); 380 EXPECT_FALSE(registration_id_.empty()); 381 EXPECT_EQ(expected_registration_id, registration_id_); 382 EXPECT_EQ(GCMClient::SUCCESS, result_); 383 } 384 385 TEST_F(GCMProfileServiceRegisterTest, DoubleRegister) { 386 std::vector<std::string> sender_ids; 387 sender_ids.push_back("sender1"); 388 Register(kTestingAppId, sender_ids); 389 std::string expected_registration_id = 390 gcm_client_mock_->GetRegistrationIdFromSenderIds(sender_ids); 391 392 // Calling regsiter 2nd time without waiting 1st one to finish will fail 393 // immediately. 394 sender_ids.push_back("sender2"); 395 Register(kTestingAppId, sender_ids); 396 EXPECT_TRUE(registration_id_.empty()); 397 EXPECT_NE(GCMClient::SUCCESS, result_); 398 399 // The 1st register is still doing fine. 400 WaitForCompleted(); 401 EXPECT_FALSE(registration_id_.empty()); 402 EXPECT_EQ(expected_registration_id, registration_id_); 403 EXPECT_EQ(GCMClient::SUCCESS, result_); 404 } 405 406 TEST_F(GCMProfileServiceRegisterTest, RegisterError) { 407 std::vector<std::string> sender_ids; 408 sender_ids.push_back("sender1@error"); 409 Register(kTestingAppId, sender_ids); 410 411 WaitForCompleted(); 412 EXPECT_TRUE(registration_id_.empty()); 413 EXPECT_NE(GCMClient::SUCCESS, result_); 414 } 415 416 TEST_F(GCMProfileServiceRegisterTest, RegisterAgainWithSameSenderIDs) { 417 std::vector<std::string> sender_ids; 418 sender_ids.push_back("sender1"); 419 sender_ids.push_back("sender2"); 420 Register(kTestingAppId, sender_ids); 421 std::string expected_registration_id = 422 gcm_client_mock_->GetRegistrationIdFromSenderIds(sender_ids); 423 424 WaitForCompleted(); 425 EXPECT_EQ(expected_registration_id, registration_id_); 426 EXPECT_EQ(GCMClient::SUCCESS, result_); 427 428 // Clears the results the would be set by the Register callback in preparation 429 // to call register 2nd time. 430 registration_id_.clear(); 431 result_ = GCMClient::UNKNOWN_ERROR; 432 433 // Calling register 2nd time with the same set of sender IDs but different 434 // ordering will get back the same registration ID. There is no need to wait 435 // since register simply returns the cached registration ID. 436 std::vector<std::string> another_sender_ids; 437 another_sender_ids.push_back("sender2"); 438 another_sender_ids.push_back("sender1"); 439 Register(kTestingAppId, another_sender_ids); 440 EXPECT_EQ(expected_registration_id, registration_id_); 441 EXPECT_EQ(GCMClient::SUCCESS, result_); 442 } 443 444 TEST_F(GCMProfileServiceRegisterTest, RegisterAgainWithDifferentSenderIDs) { 445 std::vector<std::string> sender_ids; 446 sender_ids.push_back("sender1"); 447 Register(kTestingAppId, sender_ids); 448 std::string expected_registration_id = 449 gcm_client_mock_->GetRegistrationIdFromSenderIds(sender_ids); 450 451 WaitForCompleted(); 452 EXPECT_EQ(expected_registration_id, registration_id_); 453 EXPECT_EQ(GCMClient::SUCCESS, result_); 454 455 // Make sender IDs different. 456 sender_ids.push_back("sender2"); 457 std::string expected_registration_id2 = 458 gcm_client_mock_->GetRegistrationIdFromSenderIds(sender_ids); 459 460 // Calling register 2nd time with the different sender IDs will get back a new 461 // registration ID. 462 Register(kTestingAppId, sender_ids); 463 WaitForCompleted(); 464 EXPECT_EQ(expected_registration_id2, registration_id_); 465 EXPECT_EQ(GCMClient::SUCCESS, result_); 466 } 467 468 // http://crbug.com/326321 469 #if defined(OS_WIN) 470 #define MAYBE_RegisterFromStateStore DISABLED_RegisterFromStateStore 471 #else 472 #define MAYBE_RegisterFromStateStore RegisterFromStateStore 473 #endif 474 TEST_F(GCMProfileServiceRegisterTest, MAYBE_RegisterFromStateStore) { 475 scoped_refptr<Extension> extension(CreateExtension()); 476 477 std::vector<std::string> sender_ids; 478 sender_ids.push_back("sender1"); 479 Register(extension->id(), sender_ids); 480 481 WaitForCompleted(); 482 EXPECT_FALSE(registration_id_.empty()); 483 EXPECT_EQ(GCMClient::SUCCESS, result_); 484 std::string old_registration_id = registration_id_; 485 486 // Clears the results the would be set by the Register callback in preparation 487 // to call register 2nd time. 488 registration_id_.clear(); 489 result_ = GCMClient::UNKNOWN_ERROR; 490 491 // Simulate start-up by recreating GCMProfileService. 492 GCMProfileServiceFactory::GetInstance()->SetTestingFactoryAndUse( 493 profile(), &GCMProfileServiceTest::BuildGCMProfileService); 494 495 // Simulate start-up by reloading extension. 496 extension_service_->UnloadExtension(extension->id(), 497 UnloadedExtensionInfo::REASON_TERMINATE); 498 extension_service_->AddExtension(extension.get()); 499 500 // TODO(jianli): The waiting would be removed once we support delaying running 501 // register operation until the persistent loading completes. 502 WaitForCompleted(); 503 504 // This should read the registration info from the extension's state store. 505 // There is no need to wait since register returns the registration ID being 506 // read. 507 Register(extension->id(), sender_ids); 508 EXPECT_EQ(old_registration_id, registration_id_); 509 EXPECT_EQ(GCMClient::SUCCESS, result_); 510 } 511 512 TEST_F(GCMProfileServiceRegisterTest, Unregister) { 513 scoped_refptr<Extension> extension(CreateExtension()); 514 515 std::vector<std::string> sender_ids; 516 sender_ids.push_back("sender1"); 517 Register(extension->id(), sender_ids); 518 519 WaitForCompleted(); 520 EXPECT_FALSE(registration_id_.empty()); 521 EXPECT_EQ(GCMClient::SUCCESS, result_); 522 523 // The registration info should be cached. 524 EXPECT_FALSE(GetGCMProfileService()->registration_info_map_.empty()); 525 526 // The registration info should be persisted. 527 EXPECT_TRUE(HasPersistedRegistrationInfo(extension->id())); 528 529 // Uninstall the extension. 530 extension_service_->UninstallExtension(extension->id(), false, NULL); 531 base::MessageLoop::current()->RunUntilIdle(); 532 533 // The cached registration info should be removed. 534 EXPECT_TRUE(GetGCMProfileService()->registration_info_map_.empty()); 535 536 // The persisted registration info should be removed. 537 EXPECT_FALSE(HasPersistedRegistrationInfo(extension->id())); 538 } 539 540 class GCMProfileServiceSendTest : public GCMProfileServiceTest { 541 public: 542 GCMProfileServiceSendTest() : result_(GCMClient::SUCCESS) { 543 } 544 545 virtual ~GCMProfileServiceSendTest() { 546 } 547 548 void Send(const std::string& receiver_id, 549 const GCMClient::OutgoingMessage& message) { 550 GetGCMProfileService()->Send( 551 kTestingAppId, 552 receiver_id, 553 message, 554 base::Bind(&GCMProfileServiceSendTest::SendCompleted, 555 base::Unretained(this))); 556 } 557 558 void SendCompleted(const std::string& message_id, GCMClient::Result result) { 559 message_id_ = message_id; 560 result_ = result; 561 SignalCompleted(); 562 } 563 564 protected: 565 std::string message_id_; 566 GCMClient::Result result_; 567 568 private: 569 DISALLOW_COPY_AND_ASSIGN(GCMProfileServiceSendTest); 570 }; 571 572 TEST_F(GCMProfileServiceSendTest, Send) { 573 GCMClient::OutgoingMessage message; 574 message.id = "1"; 575 message.data["key1"] = "value1"; 576 message.data["key2"] = "value2"; 577 Send(kUserId, message); 578 579 // Wait for the send callback is called. 580 WaitForCompleted(); 581 EXPECT_EQ(message_id_, message.id); 582 EXPECT_EQ(GCMClient::SUCCESS, result_); 583 } 584 585 TEST_F(GCMProfileServiceSendTest, SendError) { 586 GCMClient::OutgoingMessage message; 587 // Embedding error in id will tell the mock to simulate the send error. 588 message.id = "1@error"; 589 message.data["key1"] = "value1"; 590 message.data["key2"] = "value2"; 591 Send(kUserId, message); 592 593 // Wait for the send callback is called. 594 WaitForCompleted(); 595 EXPECT_EQ(message_id_, message.id); 596 EXPECT_EQ(GCMClient::SUCCESS, result_); 597 598 // Wait for the send error. 599 WaitForCompleted(); 600 EXPECT_EQ(GCMEventRouterMock::SEND_ERROR_EVENT, 601 gcm_event_router_mock_->received_event()); 602 EXPECT_EQ(kTestingAppId, gcm_event_router_mock_->app_id()); 603 EXPECT_EQ(message_id_, gcm_event_router_mock_->send_message_id()); 604 EXPECT_NE(GCMClient::SUCCESS, gcm_event_router_mock_->send_result()); 605 } 606 607 TEST_F(GCMProfileServiceTest, MessageReceived) { 608 GCMClient::IncomingMessage message; 609 message.data["key1"] = "value1"; 610 message.data["key2"] = "value2"; 611 gcm_client_mock_->ReceiveMessage(kTestingUsername, kTestingAppId, message); 612 WaitForCompleted(); 613 EXPECT_EQ(GCMEventRouterMock::MESSAGE_EVENT, 614 gcm_event_router_mock_->received_event()); 615 EXPECT_EQ(kTestingAppId, gcm_event_router_mock_->app_id()); 616 ASSERT_EQ(message.data.size(), 617 gcm_event_router_mock_->incoming_message().data.size()); 618 EXPECT_EQ( 619 message.data.find("key1")->second, 620 gcm_event_router_mock_->incoming_message().data.find("key1")->second); 621 EXPECT_EQ( 622 message.data.find("key2")->second, 623 gcm_event_router_mock_->incoming_message().data.find("key2")->second); 624 } 625 626 TEST_F(GCMProfileServiceTest, MessagesDeleted) { 627 gcm_client_mock_->DeleteMessages(kTestingUsername, kTestingAppId); 628 WaitForCompleted(); 629 EXPECT_EQ(GCMEventRouterMock::MESSAGES_DELETED_EVENT, 630 gcm_event_router_mock_->received_event()); 631 EXPECT_EQ(kTestingAppId, gcm_event_router_mock_->app_id()); 632 } 633 634 } // namespace gcm 635