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/user_list.h"
10 #include "base/bind.h"
11 #include "base/callback_forward.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 "google_apis/gcm/engine/gcm_store_impl.h"
18 #include "testing/gtest/include/gtest/gtest.h"
24 class GCMClientDelegate
: public GCMClient::Delegate
{
26 explicit GCMClientDelegate(const std::string
& username
);
27 virtual ~GCMClientDelegate();
29 const std::string
& GetUsername() const { return username_
; }
31 // Overrides of GCMClientDelegate:
32 virtual void OnCheckInFinished(const GCMClient::CheckinInfo
& checkin_info
,
33 GCMClient::Result result
) OVERRIDE
{}
34 virtual void OnRegisterFinished(const std::string
& app_id
,
35 const std::string
& registration_id
,
36 GCMClient::Result result
) OVERRIDE
{}
37 virtual void OnSendFinished(const std::string
& app_id
,
38 const std::string
& message_id
,
39 GCMClient::Result result
) OVERRIDE
{}
40 virtual void OnMessageReceived(const std::string
& app_id
,
41 const GCMClient::IncomingMessage
& message
)
43 virtual void OnMessagesDeleted(const std::string
& app_id
) OVERRIDE
{}
44 virtual void OnMessageSendError(const std::string
& app_id
,
45 const std::string
& message_id
,
46 GCMClient::Result result
) OVERRIDE
{}
47 virtual GCMClient::CheckinInfo
GetCheckinInfo() const OVERRIDE
{
48 return GCMClient::CheckinInfo();
50 virtual void OnGCMReady() OVERRIDE
{}
53 std::string username_
;
58 class UserListTest
: public testing::Test
{
61 virtual ~UserListTest();
63 virtual void SetUp() OVERRIDE
;
65 static size_t GetListSize(const UserList
* user_list
);
66 void SetDelegateCallback(const std::string
& username
,
67 int64 user_serial_number
);
69 scoped_ptr
<UserList
> BuildUserList();
73 void UpdateCallback(bool success
);
75 void Initialize(UserList
* user_list
, scoped_ptr
<GCMStore::LoadResult
> result
);
80 int64 last_assigned_serial_number_
;
81 std::string last_assigned_username_
;
82 scoped_ptr
<GCMStore
> gcm_store_
;
85 base::ScopedTempDir temp_directory_
;
86 base::MessageLoop message_loop_
;
87 scoped_ptr
<base::RunLoop
> run_loop_
;
90 UserListTest::UserListTest()
91 : last_assigned_serial_number_(gcm::kInvalidSerialNumber
) {}
93 UserListTest::~UserListTest() {}
95 void UserListTest::SetUp() {
96 ASSERT_TRUE(temp_directory_
.CreateUniqueTempDir());
100 size_t UserListTest::GetListSize(const UserList
* user_list
) {
101 return user_list
->delegates_
.size();
104 void UserListTest::SetDelegateCallback(const std::string
& username
,
105 int64 user_serial_number
) {
106 last_assigned_username_
= username
;
107 last_assigned_serial_number_
= user_serial_number
;
111 scoped_ptr
<UserList
> UserListTest::BuildUserList() {
112 gcm_store_
.reset(new GCMStoreImpl(true,
113 temp_directory_
.path(),
114 message_loop_
.message_loop_proxy()));
115 return scoped_ptr
<UserList
>(new UserList(gcm_store_
.get()));
118 void UserListTest::Initialize(UserList
* user_list
,
119 scoped_ptr
<GCMStore::LoadResult
> result
) {
120 ASSERT_TRUE(result
->success
);
121 user_list
->Initialize(result
->serial_number_mappings
);
125 void UserListTest::ResetLoop() {
126 if (run_loop_
&& run_loop_
->running())
130 void UserListTest::PumpLoop() {
131 run_loop_
.reset(new base::RunLoop
);
135 void UserListTest::UpdateCallback(bool success
) { ASSERT_TRUE(success
); }
137 GCMClientDelegate::GCMClientDelegate(const std::string
& username
)
138 : username_(username
) {}
140 GCMClientDelegate::~GCMClientDelegate() {}
142 // Make sure it is possible to add a delegate, and that it is assigned a serial
144 TEST_F(UserListTest
, SetDelegateAndCheckSerialNumberAssignment
) {
145 scoped_ptr
<UserList
> user_list(BuildUserList());
146 gcm_store_
->Load(base::Bind(
147 &UserListTest::Initialize
, base::Unretained(this), user_list
.get()));
150 // First adding a delegate.
151 scoped_ptr
<GCMClientDelegate
> delegate(new GCMClientDelegate("test_user_1"));
152 user_list
->SetDelegate(
153 delegate
->GetUsername(),
155 base::Bind(&UserListTest::SetDelegateCallback
, base::Unretained(this)));
158 // Verify the record was created.
159 EXPECT_EQ(1u, GetListSize(user_list
.get()));
160 // Verify username and serial number were assigned.
161 EXPECT_EQ(delegate
->GetUsername(), last_assigned_username_
);
162 EXPECT_NE(gcm::kInvalidSerialNumber
, last_assigned_serial_number_
);
163 // Check that a serial number was assigned to delegate.
164 EXPECT_EQ(last_assigned_serial_number_
,
165 user_list
->GetSerialNumberForUsername(delegate
->GetUsername()));
168 // Get the delegate that was added to the list by both serial number and
170 TEST_F(UserListTest
, GetDelegate
) {
171 scoped_ptr
<UserList
> user_list(BuildUserList());
172 gcm_store_
->Load(base::Bind(
173 &UserListTest::Initialize
, base::Unretained(this), user_list
.get()));
176 // Start by adding a delegate and a serial number.
177 scoped_ptr
<GCMClientDelegate
> delegate(new GCMClientDelegate("test_user_1"));
178 user_list
->SetDelegate(
179 delegate
->GetUsername(),
181 base::Bind(&UserListTest::SetDelegateCallback
, base::Unretained(this)));
184 EXPECT_EQ(delegate
.get(),
185 user_list
->GetDelegateBySerialNumber(last_assigned_serial_number_
));
186 EXPECT_EQ(delegate
.get(),
187 user_list
->GetDelegateByUsername(last_assigned_username_
));
190 // Make sure that correct mapping between username of the delegate and a serial
191 // number is preserved when loading the user list. Also verify that setting a
192 // delegate after load works correctly. (Finds the existing mapping entry.)
193 TEST_F(UserListTest
, LoadUserEntrySetDelegate
) {
194 scoped_ptr
<UserList
> user_list(BuildUserList());
195 gcm_store_
->Load(base::Bind(
196 &UserListTest::Initialize
, base::Unretained(this), user_list
.get()));
199 // Start by adding a delegate and a serial number.
200 scoped_ptr
<GCMClientDelegate
> delegate(new GCMClientDelegate("test_user_1"));
201 user_list
->SetDelegate(
202 delegate
->GetUsername(),
204 base::Bind(&UserListTest::SetDelegateCallback
, base::Unretained(this)));
207 // Reload the GCM User List.
208 user_list
= BuildUserList().Pass();
209 gcm_store_
->Load(base::Bind(
210 &UserListTest::Initialize
, base::Unretained(this), user_list
.get()));
213 // Verify a single record was loaded, with matching username, but no delegate.
214 EXPECT_EQ(1u, GetListSize(user_list
.get()));
215 int64 serial_number
=
216 user_list
->GetSerialNumberForUsername(delegate
->GetUsername());
217 EXPECT_EQ(last_assigned_serial_number_
, serial_number
);
218 EXPECT_EQ(NULL
, user_list
->GetDelegateBySerialNumber(serial_number
));
219 EXPECT_EQ(NULL
, user_list
->GetDelegateByUsername(delegate
->GetUsername()));
221 // After loading is complete, Delegates will start adding itself looking for
222 // their serial numbers. Check that correct matches are found and new records
224 user_list
->SetDelegate(
225 delegate
->GetUsername(),
227 base::Bind(&UserListTest::SetDelegateCallback
, base::Unretained(this)));
230 EXPECT_EQ(1u, GetListSize(user_list
.get()));
232 user_list
->GetSerialNumberForUsername(delegate
->GetUsername());
233 EXPECT_EQ(last_assigned_serial_number_
, serial_number
);
234 EXPECT_EQ(delegate
.get(),
235 user_list
->GetDelegateBySerialNumber(serial_number
));
236 EXPECT_EQ(delegate
.get(),
237 user_list
->GetDelegateByUsername(delegate
->GetUsername()));
240 // Check that it is possible to add multiple delegates to the user list.
241 TEST_F(UserListTest
, AddMultipleDelegates
) {
242 scoped_ptr
<UserList
> user_list(BuildUserList());
243 gcm_store_
->Load(base::Bind(
244 &UserListTest::Initialize
, base::Unretained(this), user_list
.get()));
247 // Start by adding a delegate and a serial number.
248 scoped_ptr
<GCMClientDelegate
> delegate1(new GCMClientDelegate("test_user_1"));
249 user_list
->SetDelegate(
250 delegate1
->GetUsername(),
252 base::Bind(&UserListTest::SetDelegateCallback
, base::Unretained(this)));
255 int64 serial_number1
= last_assigned_serial_number_
;
257 scoped_ptr
<GCMClientDelegate
> delegate2(new GCMClientDelegate("test_user_2"));
258 user_list
->SetDelegate(
259 delegate2
->GetUsername(),
261 base::Bind(&UserListTest::SetDelegateCallback
, base::Unretained(this)));
264 int64 serial_number2
= last_assigned_serial_number_
;
266 // Ensuring that serial numbers are different.
267 EXPECT_EQ(2u, GetListSize(user_list
.get()));
269 // Reading the user entries.
270 user_list
= BuildUserList().Pass();
271 gcm_store_
->Load(base::Bind(
272 &UserListTest::Initialize
, base::Unretained(this), user_list
.get()));
275 // Serial numbers stay the same, but there are no delegates assigned.
276 EXPECT_EQ(2u, GetListSize(user_list
.get()));
277 EXPECT_EQ(NULL
, user_list
->GetDelegateByUsername(delegate1
->GetUsername()));
278 EXPECT_EQ(NULL
, user_list
->GetDelegateBySerialNumber(serial_number1
));
279 EXPECT_EQ(NULL
, user_list
->GetDelegateByUsername(delegate2
->GetUsername()));
280 EXPECT_EQ(NULL
, user_list
->GetDelegateBySerialNumber(serial_number2
));
282 // Setting and checking a delegate on the second user.
283 user_list
->SetDelegate(
284 delegate2
->GetUsername(),
286 base::Bind(&UserListTest::SetDelegateCallback
, base::Unretained(this)));
289 // First user still does not have a delegate.
290 EXPECT_EQ(NULL
, user_list
->GetDelegateByUsername(delegate1
->GetUsername()));
291 EXPECT_EQ(NULL
, user_list
->GetDelegateBySerialNumber(serial_number1
));
292 // Second user has a delegate set.
293 EXPECT_EQ(delegate2
.get(),
294 user_list
->GetDelegateByUsername(delegate2
->GetUsername()));
295 EXPECT_EQ(delegate2
.get(),
296 user_list
->GetDelegateBySerialNumber(serial_number2
));
299 // Adding a delegate before the user list is initialized. Verifies that serial
300 // number assignment is postponed until after initialization.
301 TEST_F(UserListTest
, AddDelegateThenInitializeWithoutSerialNumber
) {
302 scoped_ptr
<UserList
> user_list(BuildUserList());
304 // Add a delegate first.
305 scoped_ptr
<GCMClientDelegate
> delegate(new GCMClientDelegate("test_user_1"));
306 user_list
->SetDelegate(
307 delegate
->GetUsername(),
309 base::Bind(&UserListTest::SetDelegateCallback
, base::Unretained(this)));
311 EXPECT_EQ(gcm::kInvalidSerialNumber
, last_assigned_serial_number_
);
312 EXPECT_EQ("", last_assigned_username_
);
314 // Now run the initialization.
315 gcm_store_
->Load(base::Bind(
316 &UserListTest::Initialize
, base::Unretained(this), user_list
.get()));
317 // Need to pump twice, due to initialization triggering additional set of
318 // callbacks to be run.
322 EXPECT_EQ(last_assigned_serial_number_
,
323 user_list
->GetSerialNumberForUsername(delegate
->GetUsername()));
324 EXPECT_EQ(delegate
->GetUsername(), last_assigned_username_
);
327 // Adding a delegate that already has a serial number on a subsequent restart of
328 // the user list and prior to initialization. Expects to assing correct serial
329 // number based on existing mappings.
330 TEST_F(UserListTest
, AddDelegateThenInitializeWithSerialNumber
) {
331 scoped_ptr
<UserList
> user_list(BuildUserList());
332 gcm_store_
->Load(base::Bind(
333 &UserListTest::Initialize
, base::Unretained(this), user_list
.get()));
336 // First add a delegate to the list so that serial number is persisted.
337 scoped_ptr
<GCMClientDelegate
> delegate(new GCMClientDelegate("test_user_1"));
338 user_list
->SetDelegate(
339 delegate
->GetUsername(),
341 base::Bind(&UserListTest::SetDelegateCallback
, base::Unretained(this)));
344 last_assigned_serial_number_
= gcm::kInvalidSerialNumber
;
345 last_assigned_username_
= "";
347 // Resetting the user list to make sure it is not initialized.
348 user_list
= BuildUserList().Pass();
350 // Add a delegate again, this time no callback is expected until the list is
352 user_list
->SetDelegate(
353 delegate
->GetUsername(),
355 base::Bind(&UserListTest::SetDelegateCallback
, base::Unretained(this)));
357 // Now run the initialization.
358 gcm_store_
->Load(base::Bind(
359 &UserListTest::Initialize
, base::Unretained(this), user_list
.get()));
360 // Need to pump twice, due to initialization triggering additional set of
361 // callbacks to be run.
365 EXPECT_EQ(last_assigned_serial_number_
,
366 user_list
->GetSerialNumberForUsername(delegate
->GetUsername()));
367 EXPECT_EQ(delegate
->GetUsername(), last_assigned_username_
);