Chromium Code Reviews| Index: google_apis/gcm/engine/user_list_unittest.cc |
| diff --git a/google_apis/gcm/engine/user_list_unittest.cc b/google_apis/gcm/engine/user_list_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..046afa50602ff455ceefe10c649ba93e266f90e4 |
| --- /dev/null |
| +++ b/google_apis/gcm/engine/user_list_unittest.cc |
| @@ -0,0 +1,374 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "google_apis/gcm/engine/user_list.h" |
| + |
| +#include <string> |
| +#include <vector> |
| + |
| +#include "base/bind.h" |
| +#include "base/callback_forward.h" |
| +#include "base/files/file_path.h" |
| +#include "base/files/scoped_temp_dir.h" |
| +#include "base/memory/scoped_ptr.h" |
| +#include "base/message_loop/message_loop.h" |
| +#include "base/run_loop.h" |
| +#include "google_apis/gcm/engine/gcm_store_impl.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +namespace gcm { |
| + |
| +namespace { |
| +const int64 kSerialNumberMissing = -1; |
| +} // namespace |
| + |
| +class UserListTest : public testing::Test { |
| + public: |
| + UserListTest(); |
| + virtual ~UserListTest(); |
| + |
| + static unsigned long GetListSize(const UserList* user_list); |
|
Nicolas Zea
2014/01/14 23:56:42
why not just make this a standalone function in an
jianli
2014/01/15 01:07:09
nit: use size_t instead
fgorski
2014/01/15 01:29:21
Because the information is private, and UserListTe
fgorski
2014/01/15 01:29:21
Done.
|
| + void SetDelegateCallback(const std::string& username, |
| + int64 user_serial_number); |
| + |
| + scoped_ptr<UserList> BuildUserList(); |
| + |
| + void PumpLoop(); |
| + |
| + void UpdateCallback(bool success); |
| + |
| + void Initialize(UserList* user_list, const GCMStore::LoadResult& result) { |
|
Nicolas Zea
2014/01/14 23:56:42
nit: prefer being consistent about whether methods
fgorski
2014/01/15 01:29:21
Done.
|
| + ASSERT_TRUE(result.success); |
| + user_list->Initialize(result.serial_number_mappings); |
| + ResetLoop(); |
| + } |
| + |
| + void ResetLoop() { |
| + if (run_loop_ && run_loop_->running()) |
| + run_loop_->Quit(); |
| + } |
| + |
| + protected: |
| + int64 last_assigned_serial_number_; |
| + std::string last_assigned_username_; |
| + scoped_ptr<GCMStore> gcm_store_; |
| + |
| + private: |
| + base::ScopedTempDir temp_directory_; |
| + base::MessageLoop message_loop_; |
| + scoped_ptr<base::RunLoop> run_loop_; |
| +}; |
| + |
| +class GCMClientDelegate : public GCMClient::Delegate { |
|
Nicolas Zea
2014/01/14 23:56:42
move this into an anon namespace
fgorski
2014/01/15 01:29:21
Done.
|
| + public: |
| + explicit GCMClientDelegate(const std::string& username); |
| + virtual ~GCMClientDelegate(); |
| + |
| + const std::string& GetUsername() const { return username_; } |
| + |
| + // Overrides of GCMClientDelegate: |
| + virtual void OnCheckInFinished(const GCMClient::CheckinInfo& checkin_info, |
| + GCMClient::Result result) OVERRIDE {} |
| + virtual void OnRegisterFinished(const std::string& app_id, |
| + const std::string& registration_id, |
| + GCMClient::Result result) OVERRIDE {} |
| + virtual void OnSendFinished(const std::string& app_id, |
| + const std::string& message_id, |
| + GCMClient::Result result) OVERRIDE {} |
| + virtual void OnMessageReceived(const std::string& app_id, |
| + const GCMClient::IncomingMessage& message) |
| + OVERRIDE {} |
| + virtual void OnMessagesDeleted(const std::string& app_id) OVERRIDE {} |
| + virtual void OnMessageSendError(const std::string& app_id, |
| + const std::string& message_id, |
| + GCMClient::Result result) OVERRIDE {} |
| + virtual GCMClient::CheckinInfo GetCheckinInfo() const OVERRIDE { |
| + return checkin_info_; |
|
jianli
2014/01/15 01:07:09
nit: no need to save a copy of CheckinInfo. Return
fgorski
2014/01/15 01:29:21
Done.
|
| + } |
| + virtual void OnLoadingCompleted() OVERRIDE {} |
| + virtual base::TaskRunner* GetFileTaskRunner() OVERRIDE { return NULL; } |
| + |
| + private: |
| + GCMClient::CheckinInfo checkin_info_; |
| + std::string username_; |
| +}; |
| + |
| +UserListTest::UserListTest() |
| + : last_assigned_serial_number_(kSerialNumberMissing) { |
| + EXPECT_TRUE(temp_directory_.CreateUniqueTempDir()); |
|
Nicolas Zea
2014/01/14 23:56:42
move this into BuildUserList()? And change to ASSE
fgorski
2014/01/15 01:29:21
Done. Moved, but compilation complains about ASSER
|
| +} |
| + |
| +UserListTest::~UserListTest() {} |
| + |
| +// static |
| +unsigned long UserListTest::GetListSize(const UserList* user_list) { |
| + return user_list->delegates_.size(); |
| +} |
| + |
| +void UserListTest::SetDelegateCallback(const std::string& username, |
| + int64 user_serial_number) { |
| + last_assigned_username_ = username; |
| + last_assigned_serial_number_ = user_serial_number; |
| + ResetLoop(); |
| +} |
| + |
| +scoped_ptr<UserList> UserListTest::BuildUserList() { |
| + gcm_store_.reset(new GCMStoreImpl(temp_directory_.path(), |
| + message_loop_.message_loop_proxy())); |
| + return scoped_ptr<UserList>(new UserList(gcm_store_.get())); |
| +} |
| + |
| +void UserListTest::PumpLoop() { |
| + run_loop_.reset(new base::RunLoop); |
| + run_loop_->Run(); |
| +} |
| + |
| +void UserListTest::UpdateCallback(bool success) { ASSERT_TRUE(success); } |
| + |
| +GCMClientDelegate::GCMClientDelegate(const std::string& username) |
| + : username_(username) {} |
| + |
| +GCMClientDelegate::~GCMClientDelegate() {} |
| + |
| +TEST_F(UserListTest, SetDelegateAndCheckSerialNumberAssignment) { |
| + scoped_ptr<UserList> user_list(BuildUserList()); |
| + gcm_store_->Load(base::Bind( |
| + &UserListTest::Initialize, base::Unretained(this), user_list.get())); |
| + PumpLoop(); |
| + |
| + // First adding a delegate. |
| + scoped_ptr<GCMClientDelegate> delegate(new GCMClientDelegate("test_user_1")); |
| + user_list->SetDelegate( |
| + delegate->GetUsername(), |
| + delegate.get(), |
| + base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this))); |
| + PumpLoop(); |
| + |
| + // Verify the record was created. |
| + EXPECT_EQ(1u, GetListSize(user_list.get())); |
| + EXPECT_EQ(delegate->GetUsername(), last_assigned_username_); |
| + |
| + int64 read_serial_number; |
| + EXPECT_TRUE(user_list->GetSerialNumberForUsername(delegate->GetUsername(), |
| + &read_serial_number)); |
| + EXPECT_EQ(last_assigned_serial_number_, read_serial_number); |
| +} |
| + |
| +TEST_F(UserListTest, GetDelegate) { |
| + scoped_ptr<UserList> user_list(BuildUserList()); |
| + gcm_store_->Load(base::Bind( |
| + &UserListTest::Initialize, base::Unretained(this), user_list.get())); |
| + PumpLoop(); |
| + |
| + // Start by adding a delegate and a serial number. |
| + scoped_ptr<GCMClientDelegate> delegate(new GCMClientDelegate("test_user_1")); |
| + user_list->SetDelegate( |
| + delegate->GetUsername(), |
| + delegate.get(), |
| + base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this))); |
| + PumpLoop(); |
| + |
| + EXPECT_EQ(delegate.get(), |
| + user_list->GetDelegateBySerialNumber(last_assigned_serial_number_)); |
| + EXPECT_EQ(delegate.get(), |
| + user_list->GetDelegateByUsername(last_assigned_username_)); |
| +} |
| + |
| +TEST_F(UserListTest, GetSerialNumberForUsername) { |
| + scoped_ptr<UserList> user_list(BuildUserList()); |
| + gcm_store_->Load(base::Bind( |
| + &UserListTest::Initialize, base::Unretained(this), user_list.get())); |
| + PumpLoop(); |
| + |
| + // Start by adding a delegate and a serial number. |
| + scoped_ptr<GCMClientDelegate> delegate(new GCMClientDelegate("test_user_1")); |
| + user_list->SetDelegate( |
| + delegate->GetUsername(), |
| + delegate.get(), |
| + base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this))); |
| + PumpLoop(); |
| + |
| + int64 read_serial_number; |
| + EXPECT_TRUE(user_list->GetSerialNumberForUsername(delegate->GetUsername(), |
| + &read_serial_number)); |
| + EXPECT_EQ(last_assigned_serial_number_, read_serial_number); |
| +} |
| + |
| +TEST_F(UserListTest, LoadUserEntrySetDelegate) { |
| + scoped_ptr<UserList> user_list(BuildUserList()); |
| + gcm_store_->Load(base::Bind( |
| + &UserListTest::Initialize, base::Unretained(this), user_list.get())); |
| + PumpLoop(); |
| + |
| + // Start by adding a delegate and a serial number. |
| + scoped_ptr<GCMClientDelegate> delegate(new GCMClientDelegate("test_user_1")); |
| + user_list->SetDelegate( |
| + delegate->GetUsername(), |
| + delegate.get(), |
| + base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this))); |
| + PumpLoop(); |
| + |
| + // Reload the GCM User List. |
| + user_list = BuildUserList().Pass(); |
| + gcm_store_->Load(base::Bind( |
| + &UserListTest::Initialize, base::Unretained(this), user_list.get())); |
| + PumpLoop(); |
| + |
| + // Verify a single record was loaded, with matching username, but no delegate. |
| + EXPECT_EQ(1u, GetListSize(user_list.get())); |
| + int64 read_serial_number; |
| + EXPECT_TRUE(user_list->GetSerialNumberForUsername(delegate->GetUsername(), |
| + &read_serial_number)); |
| + EXPECT_EQ(last_assigned_serial_number_, read_serial_number); |
| + EXPECT_EQ(NULL, user_list->GetDelegateByUsername(delegate->GetUsername())); |
| + EXPECT_EQ(NULL, user_list->GetDelegateBySerialNumber(read_serial_number)); |
| + |
| + // After loading is complete, Delegates will start adding itself looking for |
| + // their serial numbers. Check that correct matches are found and new records |
| + // not created. |
| + user_list->SetDelegate( |
| + delegate->GetUsername(), |
| + delegate.get(), |
| + base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this))); |
| + PumpLoop(); |
| + |
| + EXPECT_EQ(1u, GetListSize(user_list.get())); |
| + EXPECT_TRUE(user_list->GetSerialNumberForUsername(delegate->GetUsername(), |
| + &read_serial_number)); |
| + EXPECT_EQ(last_assigned_serial_number_, read_serial_number); |
| + EXPECT_EQ(delegate.get(), |
| + user_list->GetDelegateByUsername(delegate->GetUsername())); |
| + EXPECT_EQ(delegate.get(), |
| + user_list->GetDelegateBySerialNumber(read_serial_number)); |
| +} |
| + |
| +TEST_F(UserListTest, AddMultipleDelegates) { |
| + scoped_ptr<UserList> user_list(BuildUserList()); |
| + gcm_store_->Load(base::Bind( |
| + &UserListTest::Initialize, base::Unretained(this), user_list.get())); |
| + PumpLoop(); |
| + |
| + // Start by adding a delegate and a serial number. |
| + scoped_ptr<GCMClientDelegate> delegate1(new GCMClientDelegate("test_user_1")); |
| + user_list->SetDelegate( |
| + delegate1->GetUsername(), |
| + delegate1.get(), |
| + base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this))); |
| + PumpLoop(); |
| + |
| + int64 serial_number1 = last_assigned_serial_number_; |
| + |
| + scoped_ptr<GCMClientDelegate> delegate2(new GCMClientDelegate("test_user_2")); |
| + user_list->SetDelegate( |
| + delegate2->GetUsername(), |
| + delegate2.get(), |
| + base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this))); |
| + PumpLoop(); |
| + |
| + int64 serial_number2 = last_assigned_serial_number_; |
| + |
| + // Ensuring that serial numbers are different. |
| + EXPECT_EQ(2u, GetListSize(user_list.get())); |
| + |
| + // Reading the user entries. |
| + user_list = BuildUserList().Pass(); |
| + gcm_store_->Load(base::Bind( |
| + &UserListTest::Initialize, base::Unretained(this), user_list.get())); |
| + PumpLoop(); |
| + |
| + // Serial numbers stay the same, but there are no delegates assigned. |
| + EXPECT_EQ(2u, GetListSize(user_list.get())); |
| + EXPECT_EQ(NULL, user_list->GetDelegateByUsername(delegate1->GetUsername())); |
| + EXPECT_EQ(NULL, user_list->GetDelegateBySerialNumber(serial_number1)); |
| + EXPECT_EQ(NULL, user_list->GetDelegateByUsername(delegate2->GetUsername())); |
| + EXPECT_EQ(NULL, user_list->GetDelegateBySerialNumber(serial_number2)); |
| + |
| + // Setting and checking a delegate on the second user. |
| + user_list->SetDelegate( |
| + delegate2->GetUsername(), |
| + delegate2.get(), |
| + base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this))); |
| + PumpLoop(); |
| + |
| + // First user still does not have a delegate. |
| + EXPECT_EQ(NULL, user_list->GetDelegateByUsername(delegate1->GetUsername())); |
| + EXPECT_EQ(NULL, user_list->GetDelegateBySerialNumber(serial_number1)); |
| + // Second user has a delegate set. |
| + EXPECT_EQ(delegate2.get(), |
| + user_list->GetDelegateByUsername(delegate2->GetUsername())); |
| + EXPECT_EQ(delegate2.get(), |
| + user_list->GetDelegateBySerialNumber(serial_number2)); |
| +} |
| + |
| +TEST_F(UserListTest, AddDelegateThenInitializeWithoutSerialNumber) { |
| + scoped_ptr<UserList> user_list(BuildUserList()); |
| + |
| + // Add a delegate first. |
| + scoped_ptr<GCMClientDelegate> delegate(new GCMClientDelegate("test_user_1")); |
| + user_list->SetDelegate( |
| + delegate->GetUsername(), |
| + delegate.get(), |
| + base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this))); |
| + |
| + EXPECT_EQ(kSerialNumberMissing, last_assigned_serial_number_); |
| + EXPECT_EQ("", last_assigned_username_); |
| + |
| + // Now run the initialization. |
| + gcm_store_->Load(base::Bind( |
| + &UserListTest::Initialize, base::Unretained(this), user_list.get())); |
| + // Need to pump twice, due to initialization triggering additional set of |
| + // callbacks to be run. |
| + PumpLoop(); |
| + PumpLoop(); |
| + |
| + int64 serial_number; |
| + EXPECT_TRUE(user_list->GetSerialNumberForUsername(delegate->GetUsername(), |
| + &serial_number)); |
| + EXPECT_EQ(serial_number, last_assigned_serial_number_); |
| + EXPECT_EQ(delegate->GetUsername(), last_assigned_username_); |
| +} |
| + |
| +TEST_F(UserListTest, AddDelegateThenInitializeWithSerialNumber) { |
| + scoped_ptr<UserList> user_list(BuildUserList()); |
| + gcm_store_->Load(base::Bind( |
| + &UserListTest::Initialize, base::Unretained(this), user_list.get())); |
| + PumpLoop(); |
| + |
| + // First add a delegate to the list so that serial number is persisted. |
| + scoped_ptr<GCMClientDelegate> delegate(new GCMClientDelegate("test_user_1")); |
| + user_list->SetDelegate( |
| + delegate->GetUsername(), |
| + delegate.get(), |
| + base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this))); |
| + PumpLoop(); |
| + |
| + last_assigned_serial_number_ = kSerialNumberMissing; |
| + last_assigned_username_ = ""; |
| + |
| + // Resetting the user list to make sure it is not initialized. |
| + user_list = BuildUserList().Pass(); |
| + |
| + // Add a delegate again, this time no callback is expected until the list is |
| + // initialized. |
| + user_list->SetDelegate( |
| + delegate->GetUsername(), |
| + delegate.get(), |
| + base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this))); |
| + |
| + // Now run the initialization. |
| + gcm_store_->Load(base::Bind( |
| + &UserListTest::Initialize, base::Unretained(this), user_list.get())); |
| + // Need to pump twice, due to initialization triggering additional set of |
| + // callbacks to be run. |
| + PumpLoop(); |
| + PumpLoop(); |
| + |
| + int64 serial_number; |
| + EXPECT_TRUE(user_list->GetSerialNumberForUsername(delegate->GetUsername(), |
| + &serial_number)); |
| + EXPECT_EQ(serial_number, last_assigned_serial_number_); |
| + EXPECT_EQ(delegate->GetUsername(), last_assigned_username_); |
| +} |
| + |
| +} // namespace gcm |